Jump to content
Search Community

Adding new morphing tweens dynamically

rzschoch 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



during my first project with GSAP I struggle trying to have tweens dynamically added to a main timeline.


There’s a main timeline that gets a new randomized morphing animation based on SVG shapes. After the first keyframe in this child timeline I want to start a new concurrent animation on the main timeline. Unfortunately, the new animations aren’t visible. Also, I don’t know how to remove the completed child animations (kill, clear, remove?), as they are not needed anymore.


Is this even a good way to do it?


Simplified CodePen: 

Original CodePen: 

See the Pen jrWJNW?editors=1010 by rzschoch (@rzschoch) on CodePen



Thanks for helping out


See the Pen RRrmBB?editors=0010 by rzschoch (@rzschoch) on CodePen

Link to comment
Share on other sites

Hi and welcome to the GreenSock forums,


Thanks for providing the demo. Unfortunately, I'm having a very difficult time understanding what it is supposed to do.


I see an image of a dog and also a wavy line being animated.


I think it would really help if you could explain exactly what we should be seeing and what isn't working.

I'm also curious if this issue has anything to do with morphSVG specifically or if you just need help knowing how to dynamically add a timeline to a parent while the parent is running.


Troubleshooting SVG is very hard when you say that something like <path class="js-keyframe-1-1"> should be animating but there is really no way of us to know what that should look like. In other words, I can't easily watch this animation and know what any of these things are:

var $firstKeyframes = $container.find('[class^="js-keyframe-1"]');
var $secondKeyframes = $container.find('[class^="js-keyframe-2"]');
var $thirdKeyframes = $container.find('[class^="js-keyframe-3"]');

It would be much easier if you did something like "after the blue box moves across the screen I need to check if the green box should move". Make sense?

If morphing is necessary, try using descriptive shapes like square, circle, star etc.

The simpler the demo you provide (and the less time it takes for us to decipher it) the quicker we will be able to help.



Link to comment
Share on other sites

Thanks Carl, you are right, my CodePen lacks any good explanation and is not easy to understand. Sorry about that.


I just created a new, much more shortened one, available here:

See the Pen RRrmBB?editors=1010 by rzschoch (@rzschoch) on CodePen


What I want to achieve is a morphing animation between keyframes that are defined in an SVG. For this testcase I simplified the available keyframes to only 3. Later on there will be at least 3 variants for each keyframe.


The desired effect is a new morphing animation from the beginning, while the old is not yet completed. This effect should repeat with changing keyframes while a specific condition is fulfilled. I hope to achieve a nearly randomized morphing effect when there are enough keyframes available in the SVG.


A description of my intended sequence as seen in the CodePen:

  1. a new timeline including a morphing tween between keyframes (SVG elements) is added at position 0 in the main timeline (line 29)
  2. the main timeline starts playing (line 37)
  3. the new child timeline triggers the creation of another new timeline at a specific time (line 16), starting at the current playhead time (line 25) of the main timeline
  4. a completed timeline on the main timeline should be removed, as it is not needed anymore (line 10) / Here I have no idea what the best way would be?

And here are my questions:

  1. Does my approach make sense?
  2. Why are the new child timelines not visible and playing like the first one?
  3. How can I remove a completed child timeline?


Makes more sense now? Thanks a lot for your time and patience.

Link to comment
Share on other sites

Thanks for the new demo and for understanding our perspective. I really appreciate the effort that went into it.


I have to admit I'm still not 100% certain of exactly what needs to happen or all the requirements so I think its best to figure it out in chunks.

I think I'm getting a little confused by some of your code. I know you are working on finding the right solution so I'm getting a little lost trying to decipher what parts you are experimenting with and which parts you need to work a certain way.


So stepping back a bit, if you need to create a timeline with 3 or 4 tweens when your app loads but for some reason need to inject some "unknown" animation in the middle I think this approach will work:


var main = new TimelineLite(),
    circle = document.getElementById("circle");

main.to(circle, 1, {morphSVG:"#hippo"}, "+=1")//tween1
  .call(addAnimation)// dynamically generated animation
  .to(circle, 1, {morphSVG:"#elephant"}, "+=1")//tween2
  .to(circle, 1, {morphSVG:circle}, "+=1");//tween3

function addAnimation() {
  var child = new TimelineLite();
  child.to(circle, 1, {morphSVG:"#star"});
  //before adding child to main, you need to move tweens 2 and 3 forward to make room for child
  //shiftChildren() docs: http://greensock.com/docs/#/HTML5/GSAP/TimelineLite/shiftChildren/
  main.shiftChildren(child.duration(), true, main.time());
  main.add(child, main.time());  

The key takeaway here is that tween1, tween2, and tween3 would normally occur perfectly in sequence and the addAnimation function could technically create a child timeline of an unknown duration. The addAnimation function figures out how long the child timeline is and then pushes tween2 and tween3 out of the way so that the new child can fit in between tween 1 and 2. 


You can see it in action here:



You will notice that the circle morphs to hippo (tween1)

and then the addAnimation() function injects an animation from hippo to star (dynamic)

then the star morphs into an elephant  (tween2)

then elephant morphs into circle (tween3)


Does that help solve some of the problem?

If so we can move on to discussing how or why we should remove animations after they have been played.

  • Like 2
Link to comment
Share on other sites

Thanks for your help, again.


It’s a good idea to communicate in code chunks. To go simplify it even further I try to explain the desired effect in a timeline visualization:


o = placeholder visualizing an empty timeline

x = added timeline with tween

^ = playhead


1. Main Timeline at start:



2. Main timeline gets the first animation and starts playing:



3. At some point during play another child timeline is added to the main one (at a different layer?):




4. Now two playheads are moving and a concurrent animation with different timeline positions in the same animation are shown



5. A child timeline should remove itself after completion
6. Every child timeline creates a new one at some time, like shown in 3
So, if I understand you right, the difference between your and my version is that yours is a sequence of successive timelines and my intended version is a sequence of parallel playing timelines.
At the end, I try to have dynamically generated parallel timelines with an offset to each other. These sequences should create itself infinite until said otherwise.
Thanks a lot
  • Like 1
Link to comment
Share on other sites



I just came up with a possible solution:

See the Pen ezZJba?editors=0010 by rzschoch (@rzschoch) on CodePen


The only rather ugly way I found is to clone the origin element every time. Or is there a much more elegant way baked in GSAP? I chose this way because I need to have the original state of the SVG elements before starting a new parallel animation. If I don’t have this state the animation gets a yoyo effect (forward to backward).


It would be great to find an elegant solution for my problem.





  • Like 1
Link to comment
Share on other sites

  • Solution

i had this demo half-done before you posted your latest demo so in case it helps in some way:



If what you are doing is working, I'd say go with it. didn't notice anything really wrong with it.


Another tip is that when you morph one shape into another. The starting shape does get a "data-original" attribute applied which is a way to save the pre-morph shape data. Take a look at what happens to the <circle> when it morphs to the elephant:



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