Jump to content
se7en

Repeat and yoyo functionality with TweenLite?

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

Share this post


Link to post
Share on other sites

Close...

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

function onComplete() {
  this.reversed(!this.reversed());
}

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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

Share this post


Link to post
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?

Share this post


Link to post
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

Share this post


Link to post
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)

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

 

Close...

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

function onComplete() {
  this.reversed(!this.reversed());
}

Is there an effective way of putting a reverseDelay on this?

 

See the Pen jqjxBw by friendlygiraffe (@friendlygiraffe) on CodePen

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.