Jump to content
Search Community

Repeat and yoyo functionality with TweenLite?

se7en test
Moderator Tag

Go to solution Solved by Carl,

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

Hello,

 

What I am trying to do is animate some SVG icons and I choose GSAP because of the various issues some browsers have when dealing with CSS animation of SVG elements.

 

It appears that TweenLite+CSSPlugin can do everything that I need. The only thing that I need that TweenLite doesn't give me is the repeat and yoyo functionality.

 

I tried to simulate that functionality by using "onComplete:reverseThis, onReverseComplete:restartThis (where reverseThis is a function that just calls this.reverse() and restartThis calls this.restart() )

 

This solution seems to work initially, but if I let the animation run for a while the various elements go out of sync. This doesn't happen when I use the native repeat:-1 and yoyo:true functionality of TweenMax.

 

I looked at the plugins and there doesn't seem to be a plugin that will give me the repeat and yoyo functionality with TweenLite.

 

Is there a way to do what I need without the need to load the whole TweenMax?

 

Thank you

Link to comment
Share on other sites

  • Solution

Although Blake's code is elegant and concise you will probably still see some time-drifting due to the fact that it relies on code outside the engine to execute and change the direction of the tween. Even if it's a few milliseconds per iteration it can compound over time to be noticeable.

 

When a TweenMax tween repeats the engine controls everything and ensures perfect synchronization.

  • Like 2
Link to comment
Share on other sites

Yeah, TweenMax is definitely the simplest option. And really, when you consider CDNs and caching, the file size becomes a non-issue. 

 

That being said, you could try a technique like this:

TweenLite.to(.... {onComplete:function() {
    var endTime = this.endTime();
    this.reverse().startTime(endTime);
}});

Theory: on a regular "reverse()", it just picks up the tween and positions it on the parent timeline so that it starts reversing NOW, but if you want to avoid any time drifts you could record when the endTime() is and force its new startTime to that value after having reversed, thus it may start slightly into that reverse, as if some time has already elapsed if necessary. But again, if I were you I'd probably just let TweenMax do its magic. ;)

  • Like 4
Link to comment
Share on other sites

Thanks, I will try out that solution with TweenLite!

 

I am still bothered a bit by the file size of TweenMax. I know GSAP is quite popular but it is not "jQuery popular" so I assume that CDN/caching would not be as effective.

 

Maybe the repeat/yoyo functionality could be part of a small plugin for TweenLite, like most other features seem to be?

Link to comment
Share on other sites

I certainly understand the concern, but please keep in mind:

  • Plugins are for specific special properties on tweens, but "repeat", "yoyo", and "repeatDelay" are core-level properties that are also present in TimelineMax, so it wouldn't really fit with the "plugin" model. 
  • If we start breaking out each little feature into a plugin like that, I worry that it'll get too complex/cumbersome from an API standpoint
  • Doing so may actually give you WORSE loading performance because of latency issues with multiple requests from the server. When it's all packed into one convenient file, it's able to load faster than being spread across multiple files. 
  • Doing so reduces the likelihood that the files you're requesting will be cached. If everybody just loads TweenMax, it becomes extremely well-cached and pervasive, leading to almost zero load time whereas if we have a ton of little optional files, some will be less common, thus less likely to be cached.
  • In practical reality, the difference between TweenLite and TweenMax is less than 1 second on typical connections when not cached, and zero when it is cached.

In the advertising world, I'm pretty sure GSAP is even more popular than jQuery, and it has been adopted by EVERY major ad network. They have all committed to having it on their CDN and not counting its file size against ads. That's a tremendous boon to developers and should lead to it being VERY widely cached. 

 

I wrote about some of this at http://greensock.com/kilobyte-conundrum/. I'd recommend checking that out ;) 

  • Like 3
Link to comment
Share on other sites

Thanks for the detailed answer. I read the article you linked to and I agree with your points. I sometimes wonder why the browsers don't include all major javascript libraries like some browsers include the flash player, and then use the local version if the author links to the CDN file.

 

In any case the technique you supplied earlier seems to work, but in the last couple of days that I used TweenMax I started using the bezier functionality also. Do you think it would be better to use TweenMax instead of TweenLite + css + bezier plugins?

 

Also, when you say that TweenMax is 34Kb is that after gzip, or thats the size without the included plugins? (because TweenMax.min.js seems to be 105kb)

Link to comment
Share on other sites

Yes, it is most likely better to load TweenMax than 3 smaller files individually.

 

TweenMax.min.js contains all the core tools/plugins that you need and gets downloaded as a 35kb zipped file. Please check Chrome's network inspector.

The number outlined in red is what gets downloaded. It is 105 after it is de-compressed.

 

aMcgQOV.png

  • Like 2
Link to comment
Share on other sites

  • 5 months later...

The simplest way would involve a TimelineMax with a TweenMax in it:

var tl = new TimelineMax({repeat:-1});
tl.to("#box", 2, {x: 400, yoyo:true, repeat:1, repeatDelay:1});

Or, if you're limited to loading TweenLite, you could do it with some logic and a delayedCall():

 

TweenLite.to("#box", 2, {x:400, onComplete:onComplete, onReverseComplete:onReverseComplete});

function onReverseComplete() {
  this.play();
}

function onComplete() {
  var tween = this;
  TweenLite.delayedCall(1, function() {
      tween.reverse();
  });
}
Or an alternate with only one function:
TweenLite.to("#box", 2, {x:400, onComplete:onComplete, onReverseComplete:onComplete});

function onComplete() {
  var tween = this;
  if (tween.reversed()) {
    tween.play();
  } else {
    TweenLite.delayedCall(1, function() {
      tween.reverse();
    });
  }
}
  • 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.
×
×
  • Create New...