csscss-animationscss-transformstranslate3d

CSS 3 Animations. translate3d versus matrix


I have been doing projects that have required smooth transitions and animations. We have recently migrated from using Javascript to CSS animations almost 100% of the time.

I have found using translate3d provides a very smooth nice animation on both mobile and desktop.

My current animating style is like this:

CSS:

.animation-up{
     transform: translate3d(0, -100%, 0);
 }

.animation-down{
     transform: translate3d(0, 100%, 0);
 }

.animation-left{
     tranform: translate3d(-100%, 0, 0);
 }

.animation-right{
     tranform: translate3d(-100%, 0, 0);
 }

Recently, I have begun to look into different frameworks that seem to be getting a lot of buzz. Two in specific GreenSock (http://greensock.com/tweenmax) and Famo.us (http://famo.us). Both show awesome frame-rates and amazing performance.

I am noticing they are using a martix transform.

Greensock example (using matrix):

<div class="box green" style="transform: matrix(1, 0, 0, 1, 0, 100);"></div>

Famo.us example (using 3D-matrix):

<div class="famous-surface" style="transform-origin: 0% 0% 0px; transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 149, 385, 0, 1);"></div>

My Question is... What is the difference between translate3d and matrix? Is there a huge improvement using matrix over translate3D? Is there another method out there that yields even better results?

I have been happy with translate3D, but want to learn whatever method will give the smoothest best animations and looking for guidance as to what that maybe.


Solution

  • Nit is correct - in most real-world scenarios, performance would be indistinguishable between translate3d() and matrix3d(). Ultimately, all transforms get converted to a matrix at some level because that's how the GPU renders things (at least that's my understanding).

    A matrix() and matrix3d() contain not only positional data, but also rotation, scale, and skew.

    You asked whether there's a performance difference between matrix() and matrix3d() and the answer is "sometimes". matrix3d() (or any 3D-related transform) generally forces the browser to "layerize" that element (think of it like taking a photo of its pixels and storing them on the GPU) which is then faster to manipulate since its pixels are separated from the rest of the screen's/layers'. Typically you'll see smoother animations with this technique. However, there's a small cost to layerize something initially (shuttle the pixels to the GPU).

    The other down side to matrix3d() is that most browsers capture the pixels at a specific size (the element's natural size), so if you scale it way up, things look fuzzy or pixelated. Again, this typically only matters if you're scaling something UP. Oh, and layerizing something takes up memory. If you exceed the GPU's memory, it can slow things down. In my experience, this rarely happens though.

    Recent version of GreenSock's GSAP will automatically use whichever technique is most likely to deliver the smoothest results. If you're only changing position, it'll use translate3d(). If you scale and move, it'll use translate3d() and scale(). If you have any rotation or skew, it'll shift to matrix3d() because that's fastest. As of version 1.15.0, it uses force3D:"auto" which means it'll use 3D during the tween to gain the benefits of layerization, but then switch back to 2D when the animation is over to free up GPU memory. It's a highly optimized system. You can force it to use whichever technique you want, too.

    I stumbled across some interesting discoveries when analyzing the performance of CSS and JS animation. I recorded a screencast that you might want to check out: http://greensock.com/css-performance/ (be sure to read the comments too).