Jump to content
GreenSock

mattmogford

Rotate - But not shortest distance

Go to solution Solved by Jonathan,

Warning: Please note

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

Hi All,

 

I have a semi-simple rotation, that increases on it's previous rotation each time.

e.g

Spin 620deg, next time spin from 620deg to 1350deg.

 

I'm using the jquery gsap plugin -->  https://greensock.com/jquery-gsap-plugin

wheelObj.animate(
{
  transform: "translate3d( 0, 0, 0 ) rotate3d( 0, 0, 1, " + rotationAmount + "deg )"
  // rotationZ : rotationAmount
},
{
  duration: wheelObj.duration,
  easing: "easeInOutQuad",
  complete: _THIS.spinWheelToComplete
} );

The rotationZ that is commented out worked perfectly fine, it would spin to 620 then to 1350 and so on.

But it doesn't go too well on some android devices, and gets juddery and slows.

 

So to optimise I'm going for the transform - rotate3d option that should.

The only problem is, something is being 'too' clever, say it's told to rotate to 450deg, it will only rotate the 90deg instead of all the way round once, then another 90.

 

I hope someone can help with this as I've looked everywhere and nobody seems to have come across this before.

 

Thanks in advance

Matt

 

 

Link to comment
Share on other sites

  • Solution

Hello mattmogford, and welcome to the GreenSock Forum!

 

Have you tried just to use rotation instead of rotationZ, which is the same thing in GSAP. And you can use force3D: true to force hardware acceleration:

wheelObj.animate(
{
  rotation : rotationAmount,
  force3D: true
},
{
  duration: wheelObj.duration,
  easing: "easeInOutQuad",
  complete: _THIS.spinWheelToComplete
} );

:

See the CSSPlugin Docs for more info

 

Does that help?

  • Like 1
Link to comment
Share on other sites

I haven't tried that, I didn't know of force3D. I'll give that a try.

I'll have to get some 'slower' devices to test it on, but in the mean time, is there a way to disable shortest distance rotating?

 

Thank you

Matt

Link to comment
Share on other sites

Is this what you were after :

 

See the Pen emEgmM by anon (@anon) on CodePen

 

directionalRotation

  • Tweens rotation in a particular direction which can be either clockwise ("_cw" suffix), counter-clockwise ("_ccw" suffix), or in the shortest direction ("_short" suffix) in which case the plugin chooses the direction for you based on the shortest path. For example, if the element's rotation is currently 170 degrees and you want to tween it to -170 degrees, a normal rotation tween would travel a total of 340 degrees in the counter-clockwise direction, but if you use the _short suffix, it would travel 20 degrees in the clockwise direction instead. Example::
TweenLite.to(element, 2, {rotation:"-170_short"});

//or even use it on 3D rotations and use relative prefixes:
TweenLite.to(element, 2, {rotation:"-170_short", rotationX:"-=30_cw", rotationY:"1.5rad_ccw"});

:

  • Notice that the value is in quotes, thus a string with a particular suffix indicating the direction (_cw, _ccw, or _short). You can also use the "+=" or "-=" prefix to indicate relative values. Directional rotation suffixes are supported in all rotational properties (rotation, rotationX, and rotationY); you don't need to use directionalRotation as the property name. There is a DirectionalRotationPlugin that you can use to animate objects that aren't DOM elements, but there's no need to load that plugin if you're just animating css-related properties with CSSPlugin because it has DirectionalRotationPlugin's capabilities baked-in.

 

More info in the CSSPlugin Docs. Then scroll down to Directional Rotation area. :)

  • Like 1
Link to comment
Share on other sites

Thank you Jonathan,

 

The code below, seems to have encouraged the previously lagging android devices to run smoothly.

rotation : rotationAmount,
force3D: true

Thanks a lot for your help, such a simple thing fixes a killer bug!

 

Matt

Link to comment
Share on other sites

To learn more of why adding force3D:true works..  please check out these articles on forcing hardware acceleration for smoother animation. Moving the element on its own render layer using the GPU instead of the CPU.

 

Article by GreenSock's Jack: http://css-tricks.com/myth-busting-css-animations-vs-javascript/

 

Article by Paul Irsih: http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

 

:)

  • Like 1
Link to comment
Share on other sites

Just to chime in [a bit late], it is always best to use the simpler GSAP properties like rotation, x, y, scaleX, scaleY, etc. instead of composing a "transform" string like "transform: rotate(270deg)" for several reasons:

  1. When you compose a "transform" string, GSAP must assign it to the element and then read the computed style back as a matrix() or matrix3d() from the browser to ensure that everything lines up perfectly (remember, the string could have an unlimited number of instructions strung together, making it exceedingly complex). Due to some math complexities (I'll spare you), it's literally impossible to discern certain rotational values. In other words, a rotate(360deg) gives the same matrix() as a rotate(720deg) or rotate(0deg). It's also the same as a scale(-1, -1). You were trying to create rotational values beyond the "normal" window, thus it gets virtually impossible to correctly decipher using this process. 
  2. When you define the GSAP-friendly values like rotation, scaleX, scaleY, x, y, skewX, etc., it's very easy (and super fast) to read and cache those. GSAP always stores them in a _gsTransform object attached to the element anyway, so it avoids querying the DOM, deciphering matrices, etc. In other words, it's MUCH faster, and MUCH more accurate. 

For the record, you probably don't really need to set force3D:true since recent versions of GSAP automatically enable force3D:"auto" to get the 3D GPU juice during the tween. The only reason you might want to consider force3D:true is if you're using an old version or if you are going to keep re-animating the same element's transforms over and over because force3D:true will keep it in 3D instead of allowing it to go back to 2D after the animation, thus there's no need to layerize it again next time you animate it. Tradeoff: if you have too many things on the page with 3D matrices (like CRAZY amounts), it could exceed the GPU's memory and cause slowdowns but that's VERY rare. 

 

I hope that helps. 

  • Like 3
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.
×