greensock / GSAP

GSAP (GreenSock Animation Platform), a JavaScript animation library for the modern web
https://gsap.com
19.83k stars 1.72k forks source link

Support for rotate3d (which is "rotation around custom axis") #73

Closed fregante closed 10 years ago

fregante commented 10 years ago

Greensock doesn't support rotate3d correctly: http://codepen.io/bfred-it/pen/sHyFg

rotate3d not supported

jackdoyle commented 10 years ago

Due to the nature of matrix3d(), how browsers report current values, and the way rotate3d() works, I don't think this is possible to accommodate this except by using an onUpdate like you did in that demo, or by creating a dedicated plugin for a special property like rotate3d but you're the first to ever request this, so it's tough to justify creating a plugin yet. If you have an idea for implementation, I'm all ears, but I don't think it can be done effectively and efficiently inside CSSPlugin.

fregante commented 10 years ago

I'm at least the second one! :grin:

Would it be too expensive to apply the rotate3d matrix?

jackdoyle commented 10 years ago

Ha ha - I guess you are the 2nd :)

Getting the matrix3d isn't the problem - the browser actually does that for us anyway (by applying whatever you defined as the "transform" value, and then reading back the getCalculatedStyle() data) - the problem has to do with the fact that any matrix3d() value can be arrived at multiple ways, so for example a rotationX of 180 is the same as a rotation of 180 and rotationY of 180.

fregante commented 10 years ago

I figured it would be something like that…

A way I would approach it is to append the rotate3d() function to the matrix (i.e. transform: matrix(...) rotate3d(1, -1, 0, …deg)) and tween the angle in there. It might be dirty but it would be faster than manually calculating/applying that matrix on each tick (rather than just once before the start)

jackdoyle commented 10 years ago

I'm not sure I understand, though - are you saying you'd have an entirely different (additional) rotate3d component? If so, how would it be affected when part-way through a rotate3d() tween, the user starts another tween for rotation:45 or rotationY:30 or whatever? Are you saying those would be additive, thus the user wouldn't be able to count on the end rotation being 45 in this case (because the rotate3d() messes it up)?

fregante commented 10 years ago

It looks like it.

Alternatively, since getting the 3d matrix isn't a problem, what if you apply that rotate3d function at every tick? At that point you'd have a normal matrix3d where you can apply the conflicting rotation tween normally. I don't know how you would handle conflicting properties like that, though — is there any similar situation? Perhaps autoAlpha and opacity? x and the plain transform?

There probably isn't any way other than tweening that …deg separately.

jackdoyle commented 10 years ago

I really don't think there's a clean way of doing this aside from a dedicated plugin that'd overwrite any rotation/rotationX/rotationY tweens (like autoAlpha does for opacity and visibility).

fregante commented 9 years ago

It looks like even the previous way to do it is broken as of 1.15.0. Any idea why? (red square) http://codepen.io/bfred-it/pen/sHyFg

jackdoyle commented 9 years ago

I'm a little confused - are you saying an old version did work the way you expected? It appears to me like 1.15.0 is the best one yet, and like I said earlier I don't think there's a clean way to accommodate rotate3d() without a dedicated plugin or something. Perhaps I misunderstood what you were saying.

fregante commented 9 years ago

Up to 1.14.2 I had a way to use rotate3d even if not officially supported, 1.15.0 took away that one too.

Consider the red one only:

1.14.2: http://codepen.io/bfred-it/pen/sHyFg 1.15.0: http://codepen.io/bfred-it/pen/vEXNdP

What I'm saying is that it looks like 1.15.0 can no longer SET a transform string as given:

TweenLite.set('#blueBox', {
  transform: "rotate3d(1, -1, 0, 45deg)" // no longer works correctly
});
jackdoyle commented 9 years ago

Ah, I see what you mean. Let me look into this. It's rather difficult because it has to do with decomposing the matrix and the OLD way of doing it had problems in some [rather common] scenarios but the new algorithm is obviously causing issues in your scenario.

blowsie commented 6 years ago

Old ticket I know, but is there any way this can be achieved without using transform: 'rotate3d(... ?

jackdoyle commented 6 years ago

HI @blowsie - can you provide more details please? I'm not sure what exactly you're trying to do. A reduced test case in codepen would be super helpful.