GSAP Animation Failing to Interpolate CSS3 Transforms

2.6k views Asked by At

I'm in the process of converting all of my CSS3 animations to javascript animations via the GSAP library.

Unfortunately, I'm having some trouble getting CSS3 transforms to work correctly.

I have a bunch of images positioned all throughout the user's screen. They are initially hidden. When the images are all fully loaded, they are animated to move vertically from offscreen and down to their final resting positions.

img {
    /* Other styles for size, position, etc. */
    ...
    transform: perspective(400px) rotateX(50deg) rotateY(-5deg) rotateZ(30deg);
    ...
}

And some of the javascript:

var _timeline = new TimelineMax(),
    _animation = {
        'transform' : 'translateY(' + offset + 'px)',
        'ease' : Power2.easeInOut
    };

All of the images are queued into a timeline for successive animation.

_timeline.from('#someElement', 1, _animation, 0);

I use the .from() function because the elements' final styles are already present in the CSS; I just need to initially position them offscreen and move them downwards.

Here's a description of the function direct from GSAP's documentation:

Static method for creating a TweenMax instance that tweens backwards - you define the BEGINNING values and the current values are used as the destination values which is great for doing things like animating objects onto the screen because you can set them up initially the way you want them to look at the end of the tween and then animate in from elsewhere.

My understanding of this is that GSAP will take the initial state you provide it and animate the element until it is exactly the same as described in the CSS.

However, I simply cannot get GSAP to interpolate between this initial state and the final state (complete with 3D transformations). I've tried many different variations of this (i.e. adding the missing transforms to the animation code or using clearProps/force3D/etc) but the final result that GSAP gives me is not properly transformed.

In other words, if I don't run any animations then my element looks correct -- it has been rotated with perspective -- but the animated version ends up wrong.

I'm still pretty new to GSAP so I'm sure I'm just missing something.

Can anybody point me in the right direction?

Thanks!

1

There are 1 answers

8
Jack On

GSAP is interpolating to (well, from) a value that has no perspective defined, thus it is acting like it is zero. As perspective gets closer to zero, it looks stronger and stronger (obviously not what you want here) and when it hits zero, the browser treats it entirely differently, almost like it is infinity. So in your case, you can simply define a perspective in your "from" value so that it's not defaulting to zero, like:

{transform: "translateY(400px) perspective(2000px)"}

Tip for transforms in GSAP: One of GSAP's most significant strengths is the way it handles transforms. A ton of effort has gone into making them intuitive, performant, and consistent. In order to maximize the benefits, I'd strongly recommend that you use GSAP's native properties for the transform components (like x, y, z, rotation, rotationX, rotationY, scaleX, scaleY, skewX, skewY, etc.) instead of using generic "transform" strings like you do in CSS because:

  • They're much faster to parse. When you define a "transform" string, it must be passed off to the browser and interpreted as a matrix() or matrix3d() which have some inherent limitations (plus the whole process takes longer).
  • You get better control of each component. For example, if your element is already rotated and scaled and translated, and later you want to move it 200px to the right, you can simply say x:"+=200" rather than having to define a lengthy string with all of the rotation/scale/translation values included.
  • They're more accurate with rotational values beyond 360 degrees due to the fact that GSAP caches the native components so they're always precise, whereas the transform strings flow through matrices which lose accuracy after a certain point. For example, the matrix() for 0deg, 360deg, and 720deg are all identical, thus it's impossible to discern the original intent.
  • Using GSAP's native transform properties allows it to work around various browser bugs and limitations, particularly with SVGs where browser support varies wildly.

So while you technically can use a regular "transform" string, you'll get better performance, accuracy, and consistency if you leverage GSAP's native properties instead.

Here's a codepen that shows the scenario you described working: http://codepen.io/anon/pen/PqKqZG

Also, just so you know, there are dedicated GSAP forums at http://greensock.com/forums where the development team is quite active.