A bit of reflow, using TweenJS

Inspired by some modern applications (especially the “Metro” look and feel), I wanted to put together an animated tile reflow script for an HTML page I was creating.

As the size of the page changes, the tiles move into their new positions.

SNAGHTML113b633f[4]

You can try it here, if you’re using a modern browser (IE9+, Chrome, FF, Safari, etc.).

Dependencies:

  1. TweenJS
  2. EaselJS (for the ticker used in TweenJS)
  3. CSSPlugin (an add on to the the TweenJS library)
  4. jQuery (1.7.2)

Relayouts are queued (as to prevent multiple from running).

Only boxes that will be visible to the end user (either animating to the screen or off the screen) are animated. It does not animate elements that do not start or end in the current viewport including boxes that would animate “through” the current viewport. I considered the latter to not add anything to the overall experience and just uses more CPU to perform the animations, so I intentionally left it out.

In the layout loop, the code verifies that the animation needs to run:

// here's the final destination
pos = { left: Math.round(x), top: Math.round(y) };

// check old and new positions, if either are in the viewport, we'll animate
if (isScrolledIntoView(pos.top + parentOfBoxesOffsetTop, boxH) || isScrolledIntoView(box.y + parentOfBoxesOffsetTop, boxH)) {
    Tween.get(box.e).to(pos, 500 + 500 * Math.random(), 
        Ease.quadInOut).call(function () {
            --layoutPending;
            if (!layoutPending && queuedLayout) { queueLayout(); }
    });
} else {

If it needs to animate, the code uses the static Tween method “get” to start an animation on the current element.

  1. Tween.get(box.e) creates a new instance of the Tween class (initialized with the element to tween).
  2. Using that Tween instance, the CSS attributes (thanks to the handy CSSPlugin), for left and top are animated for at least 500ms and up to a full second. The easing function I chose is quadInOut. Tip: Here’s a great way to visualize easing options using TweenJS.
  3. Finally, when the animation completes, an anonymous function is called which decrements the number of pending animations and if there are no remaining elements to animate, and there’s something queued, another cycle is started.

All the code used by the demo is in default.html.

Colors of the boxes were set using hsl (only available in modern browsers):

box.style.backgroundColor = "hsl(" + c + ", 100%, 50%)";

Where “c” is:

c = (i / boxes * 360).toFixed(1);