Jump to content

Search In
  • More options...
Find results that contain...
Find results in...

Bug report: Nested 3D transform and the Webkit Matrix

Recommended Posts

Hey guys,


I'm pretty sure I've stumbled on a bug here. I'm building a cube-gallery with TweenLite. The cube itself is transformed as are the 6 faces. (2 in this case, because i simplified it).


Here's my JS example: 

// Setup props for cube and sides
TweenMax.set("#cube", { z: -100, transformOrigin: "center" });

// Use GSAP to set values (Matrix)
// TweenMax.set(document.querySelector(".top"), { rotationX: 90, z: 100 });
// TweenMax.set(document.querySelector(".front"), { z: 100 });

// Set values normally (rotateX, translateZ)
document.querySelector(".top").style.webkitTransform = "rotateX(90deg) translateZ(100px)";
document.querySelector(".front").style.webkitTransform = "translateZ(100px)";

TweenMax.to("#cube", 1.5, { rotationX: -90, yoyo: true, repeat: -1, ease: Power3.easeInOut });

Now, using rotateX and translateZ it works just fine (In webkit, I didn't write out the other prefixes), but if I switch to the GSAP version it breaks. I'm guessing this has to do with the Matrix that is being applied instead of translateX/translateZ. 


Is there a way to force GSAP to not use the matrix? I think that would fix it for now, and i'd much prefer using the GSAP syntax.


I can't use CSS to transform the elements as they switch position when the "slider" updates. For instance, if there are only 2 slides it should move them around seamlessly to give the impression of a cube with 6 faces.


I put together a Codepen with a working example and the CSS I use:

See the Pen kvaqA by Ahrengot (@Ahrengot) on CodePen

Link to comment
Share on other sites

Hello Ahrengot,


I don't believe this to be a GSAP bug?.. but you can use force3D: false ...


Or you can even feed GSAP the CSS transform property:


Here is a working example of it using the CSS transform property


See the Pen tKbgj by jonathan (@jonathan) on CodePen


// Setup props for cube and sides
TweenMax.set("#cube", {transform: "translateZ(-100px)", transformOrigin: "center", force3D:false  });

// Use GSAP to set values (Matrix)
TweenMax.set(document.querySelector(".top"), { transform:"rotateX(90deg) translateZ(100px)", force3D:false });
TweenMax.set(document.querySelector(".front"), {transform: " translateZ(100px)", force3D:false  });

// Set values normally (rotateX, translateZ)
//document.querySelector(".top").style.webkitTransform = "rotateX(90deg) translateZ(100px)";
//document.querySelector(".front").style.webkitTransform = "translateZ(100px)";

TweenMax.to("#cube", 1.5, {transform:"rotateX(-90deg)", force3D:false, yoyo: true, repeat: -1, ease: Power3.easeInOut });

Does that help?

  • Like 1
Link to comment
Share on other sites

Or you can even feed GSAP the CSS transform property:


Oh, great! That's what I was looking for.


But wouldn't one usually expect that

// This
{ transform: "rotateX(90deg) translateZ(100px)" }
// Vs. this
{ rotationX: 90, z: 100 }

would give the same result, or am I completely missing something here? 

Link to comment
Share on other sites

Just to clarify, in regular css the order in which you define the transforms has a huge impact, so these will perform very differently:...

transform: rotateX(90deg) translateZ(100px)
transform: translateZ(100px) rotateX(90deg)

In the first case, the rotation happens first (and imagine that the entire local coordinate system rotates with it), and then the translation occurs along that rotated axis. In the second example, the translation happens first, and then the rotation, thus the translation/movement occurs in completely different directions since the local axis got rotated (before in one case, after in the other). 


However, one of the primary goals of GSAP is to deliver consistency as well as behavior that more closely mimics how most IDEs work (like Flash), it uses absolute values so that you get that consistency. In other words, translation/movement always works the same way in an absolute sense - you don't have to try to remember if you rotated or skewed something first or second or third or whatever. Animate "z" and it's always going toward or away from the viewport. Again, I think this is how most animators think and I find it more intuitive. 


So the behavior you described isn't a bug in GSAP at all - it's very intentional (unless I misunderstood something). 


In summary:

//these produce identical results:
TweenLite.set(el, { rotationX: 90, z: 100 }); 
TweenLite.set(el, { z: 100, rotationX: 90 }); //order doesn't matter when defining the transform components independently
TweenLite.set(el, { transform:"translateZ(100px) rotateX(90deg)" });

//but this is different because you're using the combined "transform" css property in which the order is VERY significant:
TweenLite.set(el, { transform:"rotateX(90deg) translateZ(100px)" });

Does that clear things up?

  • Like 2
Link to comment
Share on other sites

Oh really? That's interresting!


I never did more complicated 3D in CSS before. I've rarely been transforming multiple values, but they way you explain it makes a lot of sense. 


It's certainly not a bug then. I'll rename the post title.


Thanks everyone for clearing this up.


edit: Hmm, looks like I can't edit post title...

Edited by Ahrengot
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.