Jump to content
Search Community

Different timelines can't use the same tweens...

klon 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

Dear GSAP developpers,

 

First of all, thanks for your library, which is now the only source of animation for the website I'm coding.

 

Despite all my efforts, I can't find a way to work around my wish to use the same tween in multiple timelines.

  • Yes, I can easily play a Tween and reverse it whenever I want (see the Codepen)...
  • Yes, I can easily create a Timeline for one specific situation...
  • But no, I can't find how to control a tween being played in a timeline from another timeline !

This Codepen's HTML describes what I would like to achieve.

 

The buttons perform as I expect them to, except for the sequence requirement (#hero1, THEN #hero2).

Obviously, I would like to use a TimelineLite for each sequence (using delays is not an option if the number of tweens involved increases), to allow the opening/closing of each #hero to be reversed midway if the user decides so.

 

I guess my trouble comes from this (found in FAQ) :

 

Can I put the same tween in multiple timelines?No. Every tween and timeline has one (and only one) parent timeline. Think of them like DisplayObjects/MovieClips - they cannot exist in two places at once. They can only have one parent.

 

 

Any idea on how to get the behaviour I describe in the codepen's HTML ?

 

[EDIT : I initially came to GSAP to avoid using callbacks, please don't tell me that's the solution :/]

[EDIT : I just realized the problem as I put it is easy to solve. What I need is to AVOID at all costs using more than one tween for each object I work on. No problem with maniuplating in any way the tweens I declared, though.

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

, due to the funny behaviour when you quickly click on buttons]

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

Link to comment
Share on other sites

  • Solution

Thanks for the demo and detailed explanation.

Not sure I understand the requirement of needing to re-use the same tween in multiple timelines, but what you can do is create multiple timelines that control the progress of the same tweens (and sequence them) like

 

var T_close_hero1 = TweenLite.to('#hero1', 1, {height:0, ease:Linear.easeNone}).pause();
var T_close_hero2 = TweenLite.to('#hero2', 1, {height:0, ease:Linear.easeNone}).pause();


$('#button1').click(function(){
  var tl = new TimelineLite();
  tl.to(T_close_hero1, T_close_hero1.duration(), {progress:1})
    .to(T_close_hero2, T_close_hero2.duration(), {progress:1})
});
$('#button2').click(function(){
  var tl = new TimelineLite();
  tl.to(T_close_hero1, T_close_hero1.duration(), {progress:0})
    .to(T_close_hero2, T_close_hero2.duration(), {progress:0})
});
$('#button3').click(function(){
  var tl = new TimelineLite();
  tl.to(T_close_hero1, T_close_hero1.duration(), {progress:0})
    .to(T_close_hero2, T_close_hero2.duration(), {progress:1})
});

 

http://codepen.io/GreenSock/pen/ojvpjo?editors=001

 

However it seems you still need to add logic to determine the "if needed" part

 

---

 

 

I would most often suggest in these situations that you call functions that return tweens on the fly and you then glue them together in timelines whenever you click a button. something like

//to close hero1 and then hero2

var tl = new TimelineLite()
tl.add(getAnimation("close", "#hero1"))
tl.add(getAnimation("close", "#hero2"))

//close 1 and then open 2
var tl = new TimelineLite()
tl.add(getAnimation("close", "#hero1"))
tl.add(getAnimation("open", "#hero2"))

function getAnimation(direction, element) {
  //logic to generate a tween that opens or closes any element
  ...
  return someTween;
}
  • Like 1
Link to comment
Share on other sites

[EDIT : Thanks Carl, your reply was indeed a solution to my question... In the meantime, I came to understand better how to use GSAP, which made my very question obsolete ! Sorry about that :/]

 

Hi Carl, thanks for your time !

 

Your first proposition : tweening a tween, how pervert ! I think it will do the trick, with some adjustments...

Your second propostion : that's what I first tried, feels natural, but I can't manage to pull it off...

 

About creating tweens on the fly

That's clearly the most intuitive way to do, but in many situations I can't build the "open this hero" tween. For instance :

/* this one works (I love GSAP) */
function T_closeHero() {
    return TweenLite.to('#hero', 0.7 ,{minHeight:0, height:0, flex:'none'});
}

/* This one won't work, I accept it */
function T_openHero() {
    return TweenLite.to('#hero', 0.7 ,{minHeight:'380px', height:'auto', flex:'1'});
}

Therefore, I chose to "openHero" by reversing "closeHero", thanks to Diaco's help.

If I could make "openHero" to work, well...

 

About your proposition to tween my tweens

That sounds wonderful.

I think the thing to do if I use that trick is to overwrite when needed.

 

Here is my logic. When the user orders to open/close #someHero :

  1. #someHero should try to get open/closed, no matter what was ordered before
  2. #someHero should start its animation from where it was (no "jump")

With that idea in mind, I played a bit with overwrite :

See the Pen MagGMo?editors=001 by anon (@anon) on CodePen

 

The huge problem with this solution is the duration of the tweens. They will take ".duration()" on the timeline no matter what.

If #someHero is already open, it shouldn't take time when I re-order it to open.

See the Pen gaYKgp?editors=001 by anon (@anon) on CodePen

var duration = 1;
var T_close_hero1 = TweenLite.to('#hero1', duration, {height:0, ease:Linear.easeNone}).pause();
var T_close_hero2 = TweenLite.to('#hero2', duration, {height:0, ease:Linear.easeNone}).pause();

$('#button1').click(function(){
  var tl = new TimelineLite();
  tl.to(T_close_hero1, (1 - T_close_hero1.progress())*duration, {progress:1, overwrite:"all"})
    .to(T_close_hero2, (1 - T_close_hero2.progress())*duration, {progress:1, overwrite:"all"})
});
$('#button2').click(function(){
  var tl = new TimelineLite();
  tl.to(T_close_hero1, T_close_hero1.progress()*duration, {progress:0, overwrite:"all"})
    .to(T_close_hero2, T_close_hero2.progress()*duration, {progress:0, overwrite:"all"})
});
$('#button3').click(function(){
  var tl = new TimelineLite();
  tl.to(T_close_hero1, T_close_hero1.progress()*duration, {progress:0, overwrite:"all"})
    .to(T_close_hero2, (1 - T_close_hero2.progress())*duration, {progress:1, overwrite:"all"})
});

 

What I need now

 

If I can build a working tween to slide down a flexbox with unknown height, it solves all my problems.

This would mean having a working "slideDown()" function in

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

.

 

If I can't, well, how can I get the behaviour from

See the Pen gaYKgp?editors=001 by anon (@anon) on CodePen

without doing all that math ?(and believe me, I love math, those calculations don't seem complicated at all, but I feel like I'm losing the beauty of GSAP when I do any calculation like that !)

 

Hope you'll find the courage to read all that, can't blame you if not !

Cheers

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...