Jump to content
Search Community

Re-using timeline with dynamic fill property

Vilas test
Moderator Tag

Recommended Posts

Hi guys, 

 

I have a gsap timeline which animates an svg circle. (Scale and color).

 

What I'm trying to achieve is to pass a dynamic color when clicking different buttons, for example:

 

    buttonA.addEventListener('click', (e)=>{runAnimation(DYNAMIC_VALUE)});

 

 

and then use that value here:
    tl.to(circles, {
        stagger:{ each: 0.05},
        ease: "none",
        fill: `#${DYNAMIC_VALUE}` 
    })

 

It seems that the dynamic value is always using the initial value but can't be changed later. 
Any idea on how to bypass this issue?

 

Edit: seems that using a function + tl.invalidate() works, however, spam clicking the button seems to break the animation. Any ideas?

 

Thank you in advance!

See the Pen zYXJYPY by omikron1989 (@omikron1989) on CodePen

Edited by Vilas
Found a small fix
Link to comment
Share on other sites

Hi @Vilas and welcome to the GSAP Forums!

 

You're using the invalidate method AFTER restarting the timeline, it has to be BEFORE:

const runAnimation = (currentColorName) => {
  currentColor = currentColorName;
  tl.invalidate();
  tl.restart();
};

 

Another option is to use the call method:

https://gsap.com/docs/v3/GSAP/Timeline/call()

 

const tweenFill = () => {
  gsap.to(circles, {
    stagger: { each: 0.05 },
    ease: "none",
    fill: function () {
      return `#${currentColor}`;
    }
  });
};

tl.call(tweenFill);

tl.to(
  circles,
  {
    stagger: { each: 0.05, repeat: 1, yoyo: true },
    scale: 1.05,
    ease: "sine.inOut",
    transformOrigin: "center center"
  },
  "<"
);

Here is a fork of your codepen:

See the Pen bGJxEJd by GreenSock (@GreenSock) on CodePen

 

Hopefully this helps

Happy Tweening!

Link to comment
Share on other sites

On 4/15/2024 at 11:43 PM, Rodrigo said:

Hi @Vilas and welcome to the GSAP Forums!

 

You're using the invalidate method AFTER restarting the timeline, it has to be BEFORE:

const runAnimation = (currentColorName) => {
  currentColor = currentColorName;
  tl.invalidate();
  tl.restart();
};

 

Another option is to use the call method:

https://gsap.com/docs/v3/GSAP/Timeline/call()

 

const tweenFill = () => {
  gsap.to(circles, {
    stagger: { each: 0.05 },
    ease: "none",
    fill: function () {
      return `#${currentColor}`;
    }
  });
};

tl.call(tweenFill);

tl.to(
  circles,
  {
    stagger: { each: 0.05, repeat: 1, yoyo: true },
    scale: 1.05,
    ease: "sine.inOut",
    transformOrigin: "center center"
  },
  "<"
);

Here is a fork of your codepen:

 

 

 

Hopefully this helps

Happy Tweening!

This is awesome! Thank you so much! 

 

So using the .call function injects the callback into the timeline and runs is every time the animation plays? but with updated parameters? 
That seems super useful!

 

 

Link to comment
Share on other sites

16 hours ago, Vilas said:

So using the .call function injects the callback into the timeline and runs is every time the animation plays? but with updated parameters? 

Yeah, that's basically how it works. When you call a function and a variable has been updated the function will reflect the updated value, just the way most programming languages work, as far as I know at least, I can speak for JS and PHP, but it would make sense that it works like that in every language.

 

Happy Tweening!

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