Jump to content
GreenSock

anu

Creating TimelineLite dynamically / JS

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

Hi,

 

I have an array and I have put those contents to dynamically created divs like this

 

 

var array = ["content1", "content2", "content3"];

 

var myVar = "";

for (j = 0 ; j < array.length; j++) {       
      myVar += "<div id='name"+(j+1)+"'>"+array[j]+"</div>"
}
someDiv.innerHTML = myVar;
 
 
So as a result of this, my page looks like
 
<div id="someDiv">
     <div id="name1">content1</div>
     <div id="name2">content2</div>
     <div id="name3">content3</div>
</div>
 
Now, I would like to put those dynamically in TimelineLite, so the result would be
 
var tl = new TimelineLite();
tl.add( TweenLite.from(name1, 1, {left:0, opacity:0} ) );
tl.add( TweenLite.from(name2, 1, {left:0, opacity:0} ) );
tl.add( TweenLite.from(name3, 1, {left:0, opacity:0} ) );
 
 
So my question is, how can I put a variable inside TimelineLite constructor? 
I've tried
 
for (k=1; k<array.length+1; k++){
    tl.add( TweenLite.from(name+k, 1, {opacity:0} ) );
 
}
 
but this doesn't work.. anyone? Thanks in advance!
 
 
 
Link to comment
Share on other sites

Hi anu, welcome to the foruns!

 

Having something we can see the error and a reduced case scenario makes it easier for the people here to help you track down and fix whatever might be wrong. Have a read at this post from Carl where he explains how to make a little code pen demo.

 

Regarding your question: It should work. Why it doesn't work could be for a number of reasons. And because we can't see the error, we can't tell you what is wrong. However, on your second loop, you really should convert name into a string and add the # to it so that TweenLite knows your are looking for an id name.

 

See the Pen JGXdrv by dipscom (@dipscom) on CodePen

  • Like 4
Link to comment
Share on other sites

Hi @anu, welcome!

This should be easy to fix. What you seem to be missing is concatenating the `name` part (which is a constant string) with a value of an iterating variable `k`. You also seem to be missing the `#` part in a CSS selector which lets you select elements by ID.

 

So your `tl.add(...)` lines probably need to look something like this:

tl.add(TweenLite.from('#name' + k), /* the rest follows */));

While I am at it, I would also recommend a few things:

  • First off, I would rather suggest you to use `class` instead of `id` in order to do more things to a set of elements instead of targeting one unique element on a per-need basis.
  • Then, I would recommend you to use shortcut methods provided by TimelineMax (and Lite) versions, such as `.from()`, `.fromTo()` and `.to()` instead of using `.add()` (and then passing a `TweenLite.to()` instance to it). These are convenience methods, it just makes the whole thing appear a little more cleaner in my humble opinion. Both options are valid.
  • Then, I would ask to you to try and avoid animating `left` attribute of any element and instead would recommend you to always look for ways to animate `translateX` (which in GSAP world is referred to simply as `x`) property of any object. Have a read of this article which aptly explains the benefits of animating `translateX` over `left`.
  • Lastly, I would rather ask you to look into `.staggerFrom()` method (and its siblings `.staggerFromTo()` and `.staggerTo()` methods) to avoid the loop entirely and to probably add a nice staggering effect to your transitions.

Take a look at this fiddle as an example with all the recommendations, stated above, implemented. JavaScript of which looks like below:

var someDiv = document.querySelector('.someDiv');
var array = ['content1', 'content2', 'content3'];
var length = array.length;
var myVar = '';
var elements = null;
var tl = new TimelineMax({ paused: true });

for (var i = 0 ; i < length; i += 1) {
  myVar += '<div class="name">' + array[i] + '</div>';
}

someDiv.innerHTML = myVar;
elements = document.querySelectorAll('.name');

tl.staggerFrom(elements, 1, { x: 40, opacity: 0, ease: Back.easeOut.config(2) }, 0.2);
tl.play();

Hope this helps.

  • Like 5
Link to comment
Share on other sites

Hello anu, and Welcome to the GreenSock Forum!

 

Here is one way creating a dynamic timeline from a javascript object literal instead of a javascript array

 

See the Pen Croyi by jonathan (@jonathan) on CodePen

// create object with all your tween properties
var obj = {
  0: {
    target: "#box1",
    duration: .25,
    vars: {
      autoAlpha: 0,
      scale: 1.2
    }
  },
  1: {
    target: "#box2",
    duration: .25,
    vars: {
      autoAlpha: 0,
      scale: 1.3
    }
  },
};

// create a new timeline
var tl = new TimelineMax({
  repeat: -1
});

// create a loop
var i = 0;
for (var key in obj) {
  
  // apply all your propertt values in your tween
  tl.to(obj[i].target, obj[i].duration, obj[i].vars);

  i++;
}

  When animating it is better to use x, y, and z versus top, right, bottom, or left. Since x and y will animate on a sub-pixel level whereas top, right, bottom, or left only animate on a pixel level. Please see the following:

 

GreenSock Jack's Myth Busting: CSS Animations vs. JavaScript: https://css-tricks.com/myth-busting-css-animations-vs-javascript/

 

And this to: http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

 

Also to better help you a codepen example would be helpful to see your code live and in an editable environment.

 

 

:)

  • Like 4
Link to comment
Share on other sites

Wow, there's quite a few of us lurking around at this time of the day...

 

Bet we were all writing at the same time. Jonathan and Tahir's posts show up as published at the exact same time to me...

  • Like 4
Link to comment
Share on other sites

Nice job guys.. its great to see other people tackle the same problem a different way ;)

  • Like 1
Link to comment
Share on other sites

Thanks guys for quick replies!! I'll look them closer but looks good!

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