How'd They Do That? GSAP for HTML and the Card Folding Animation

On the advice of a friend, I recently visited In the responsive breakpoints for the desktop, there is a transition with cards that shuffle into one another forming a single stack. This animation is activated by scrolling down. You might wonder how the design and development group hired by onlycoin accomplished this. Simply put, the answer is superscrollorama in concert with Greensock Animation Platform (GSAP) and CSS3 transforms.

I was less enamored with the scrolling, which is cool, but wondered more about the choice of elements used to pull off the card - stacking animation. Did they use a canvas or SVG? Turns out the cards are just rotated elements. But then how was than animation synchronized so beautifully to form the stack of cards that shuffled into one another so perfectly? That's where GSAP comes into play. card folding animation frames

Part of the Greensock Animation Platform (GSAP) is an animation library for JavaScript. It gives JavaScript developers the ability to create a rich set of element transitions that perform well across browsers old and new. The animation, or animations created from these transitions can be controlled on a timeline, like Flash animations.

As you would expect, tweens are added to the GSAP timeline. In GSAP for JavaScript, a tween consists of a target element or array of elements, a duration (in seconds or frames depending on if the timeline is time or frames-based), and a JSON object defining the end value for each property of the element or elements that you are animating. A tween could also have a named position that controls the placement of the tween in the timeline.

The cool thing about timelines and tweens is you can spin up a high fidelity animation with very little code. Where the tl variable is the timeline, for example, here's the code I used in the CodePen demo to add tweens to the timeline so the cards collapse into a deck:, 1, { rotation: 0, left: 0, top: 25 }, 0)
		.to(green, 1, { rotation: 0, left: 0, top: -345 }, 0)
              	.to(orange, 1, { rotation: 0 }, 0)
              	.to(blue, 1, { rotation: 0, left: 0, top: -370 }, 0)
              	.to(texture, 1, { opacity: '1.0' }, "begin-push")
              	.to([orange, green, gray], 1, { opacity: 0 }, "begin-push")
              	.to(blue, 0.75, { top: 370, force3D: true });


The "begin-push" is that named position I referred to earlier. The first occurrence of the named position just defines it at that position in the timeline, but other tweens use it to time their transitions at the exact same point as the named position was first defined from top down. That's it! Check out the demo on CodePen:

Several times during the animation, I chose to inspect one of those card elements mid-rotation, on the page, and I found an inline style much like this:


	style="transform: matrix(0.94711, -0.32088, 0.32088, 0.94711, 0, 0); left: 197px; top: 322px; opacity: 1;"


So, what is a matrix transform, and what's with those six arguments? This 3 x 3 matrix function represents some transformation of the element in 2d space. It could be a scale transform, a skew, a translate transform, anything CSS3 can handle with regard to transforming an element in 2D space. The power of the matrix transform is that it can be used to perform multiple transformations on an element at the same time. The matrix above represents a single rotate transform, or simply a rotation of the element upon which it applies.

The style above includes a rotation matrix simply expressed as a vector: [cos(a) sin(a) -sin(a) cos(a) 0 0], where a is the angle at which you want the card rotated. Note the similarity between the vector notation and the transform matrix above: matrix(0.94711, -0.32088, 0.32088, 0.94711, 0, 0).


	cos(a) = 0.94711
	sin(a) = -0.32088
	-sin(a) = 0.32088
	cos(a) = 0.94711


This is like turning something counter-clockwise, because experimentation with a calculator will tell you the angle a being used is value very close to -19.5 degrees. All this can simply be expressed as


	transform: rotate(-19.5deg);


But you should know that when you look at the resulting value using developer tools of your favorite browser, you will find the value being reported as a matrix as shown above. For an easy to follow, and insightful breakdown of transformations, including a great example of rotation, check Example 3, in the W3C editor's draft on transform rendering

By default, all transforms (rotate included) are applied about the center of the object. This is because the default transform origin, or point within the object at which transforms are applied, is 50% from the top, and 50% from the left.

Every good site encourages interaction, but the best sites encourage interaction and work harmoniously with the user to create a meaningful user experience. Next time you build a site, think about how animation could play a part. It's a great way to entertain, and involve the user!