Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 557
w3bMak3r Avatar asked Feb 06 '15 00:02

w3bMak3r


3 Answers

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).

like image 133
Jack Avatar answered Sep 28 '22 01:09

Jack


At their core, both translate3d() and matrix3d() are matrix transforms.

translate3d(dx, dy, dz):

Sample image 1

matrix3d(a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4):

Sample image 2

The former is simply a shorthand for only moving an element, while the latter allows you to specify the whole matrix. Since they both use the same underlying structures their performance will be near-identical (for operations of similar scale).

like image 25
Etheryte Avatar answered Sep 28 '22 01:09

Etheryte


Another thing that you have to consider is that animating matrices won't give you all of the options that you have animating transforms, specially if you are setting rotations.

The most obvious one is animating from rotate(0deg) to rotate(360deg). The equivalent matrix of both is the same (obviously). You need to set the transforms with rotate, or it won't work.

In complex transforms, usually setting the transforms with matrices won't give you the animation that you expect.

But, if you use only translations, as your title implies, anything of this is an issue

like image 43
vals Avatar answered Sep 28 '22 00:09

vals