Matrix3D transformation not working as intended

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax.

Recommended Posts

Hello GreenSock,

I'm having a problem which is described here, but wasn't actually solved in terms of why it doesn't get the correct matrix3d values: https://greensock.com/forums/topic/13986-tweening-directly-to-a-specific-matrix3d-transform/

This is what the matrix is set to:

`matrix3d(0.613582, -0.090278754224, 0, -0.00205016, -0.211713, 0.7803832528079999, 0, -0.00323228, 0, 0, 1, 0, 0, 0, 0, 1)`

And this is how it's supposed to look:

This is what results (using force3d:true):

`matrix3d(0.613584, -0.0902806, 0, 0, -0.21171, 0.780381, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)`

Here's a Fiddle (CodePen wasn't working as it didn't want to save for some reason): https://jsfiddle.net/6agx0pL8/

Just like the forum poster I linked to, I was using PerspectiveTransform.js to get to this matrix3d.

Am I missing something, or is this actually a bug or missing feature?

Share on other sites

Well, it's not really a bug or missing feature per se, but it's a bit complicated to explain. I'll give it a shot with a rough overview...

Matrices must be decomposed into components like x, y, rotation, skewX, skewY, scaleX, scaleY, rotationX, rotationY, etc. that then get animated and combined back into a matrix3d() on each tick. If you try to just tween the values inside a matrix3d(), you'll get really odd results in most cases.

The challenge here is that you've got an EXTREMELY rare edge case where it's impossible to decompose the matrix cleanly into all those component values. There simply isn't a combination of those values that translate perfectly into your 3D matrix (if there's a math wiz out there who can prove me wrong, please chime in...I welcome input). GSAP does its best.

As a workaround in your case, you could just use a proxy object to animate each of the individual values inside the matrix and combine/apply things in an onUpdate. Here's some step-by-step code (copy/paste it into your demo and you'll see that it works):

```var target = document.querySelector("#img");

//this just forces a 3D matrix to get applied to the target
TweenMax.set(target, {force3D:true, rotation:"+=0.01"});

//create an array of the raw matrix values; we'll use this as the target of our tween (essentially tween the numbers in this array)
var proxy = parseMatrix(target.style.transform);

//parse the desintation values into the same kind of array. We'll use this as the vars object for our tween, as each element in the array matches up, basically as a property of an object.
var vars = parseMatrix("matrix3d(0.613582, -0.090278754224, 0, -0.00205016, -0.211713, 0.7803832528079999, 0, -0.00323228, 0, 0, 1, 0, 0, 0, 0, 1)");

//here's where we actually APPLY the tweening values to the element's transform/style.
vars.onUpdate = function() {
target.style.transform = "matrix3d(" + proxy.join(",") + ")";
}

//pass the appropriate data into the tween and away we go!
TweenMax.to(proxy, 2, vars);

//just takes a matrix3d() string and returns it as an array of 16 numbers
function parseMatrix(matrix) {
return matrix.match(/(?:\-|\.|\b)(\d|\.|e\-)+/g).map(function(v) {return +v;});
}```

It's not going to look great if you're trying to do large rotational values where the whole thing spins around drastically, but it should work just fine for the tilting that it looks like you're trying to do.

Does that help?

• 2
• 1
Share on other sites

Hey, thanks a lot. Yes, that certainly makes sense, having read about matrix decomposition, which is not an easy thing to do in plenty of cases.

I can definitely use the code, even though large rotational values might be a concern for me, but for that, I will just create a new thread on this forum if I need further help with that.

Cheers!

• 1