Jump to content
Search Community

Problem with concurrently tweening dynamically created elements

LauraGSAP test
Moderator Tag

Go to solution Solved by LauraGSAP,

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'm trying to tween multiple elements which have been created dynamically. The problem is, that when the new element starts tweening, it stops the tween on the previous element. I've tried using timelines and normal tweens.

 

I've attached the html file, but here's the main javascript code:

 

var boxNum = 0;
 
function newBox()
{
 
document.getElementById('boxes').innerHTML += "<div id='b"+boxNum+"' class='box'></div>";
//random left variable
var leftVar = Math.floor(Math.random() * 560) + 5;
//set animation
TweenLite.to($('#b'+boxNum+'')[0], 0, {css:{top:-50, left:leftVar}});
TweenLite.to($('#b'+boxNum+'')[0], 2, {css:{top:460}, ease:Sine.easeIn});
TweenLite.delayedCall(1.5, newBox);
boxNum++;
}
 
Any help to make multiple dynamically created elements tween at the same time would be appreciated.
 
Kind regards,
 
Laura
:o)

multi-tweens.html

Link to comment
Share on other sites

Hi LauraGSAP  :)

 

You have some issues in your code :

 

- pls use TweenLite.set(yourElement ,{......} ); instead of TweenLite.to(yourElement,0,{......} ); .
 
- $('#b'+boxNum+'')[0] !!! you select an id , not an array , i think you mean $('.box'')[0] , anyway your selector should be
$('.box'')[boxNum] or $('#b'+boxNum+'') .
 
- you need to put newBox(); in your code to fire for first time .
 
- you can use 'x/y' property instead of 'left/top' to make better performance .
 
var boxNum = 0;
function newBox(){ 
  document.getElementById('boxes').innerHTML += "<div id='b"+boxNum+"' class='box'></div>";
  var leftVar = Math.floor(Math.random() * 560) + 5; 
  TweenLite.set($('.box')[boxNum],  {y:-50, x:leftVar});
//TweenLite.set($('#b'+boxNum+''), {y:-50, x:leftVar});
  TweenLite.to($('#b'+boxNum+''), 2, {y:460, ease:Sine.easeIn});
  TweenLite.delayedCall(1.5, newBox);
  boxNum++;
}
newBox();
pls check this out :

See the Pen raxBZp by MAW (@MAW) on CodePen

 
and pls for next time , make a reduced Codepen demo for better response :
 
Read This First: How to Create a CodePen Demo
  • Like 1
Link to comment
Share on other sites

I have a different take on this, and just modified your function to:

function newBox()
{
  var newElement = $("<div id='b"+boxNum+"' class='box'></div>").appendTo("#boxes");
  //random left variable
  var leftVar = Math.floor(Math.random() * 560) + 5;  
  //set animation          
  TweenLite.fromTo(newElement, 2, { top:-50, left:leftVar }, { top:460, ease:Sine.easeIn });
  TweenLite.delayedCall(.5, newBox);
  boxNum++;
}
There were a few things to improve, but the only actual issue was with your innerHTML call. When you modify innerHTML it replaces the entire node with the adjusted HTML, which actually destroys the pre-existing elements replacing them with new ones (even if the id hasn't changed). GSAP loses it's target since it has a reference to the DOM element that no longer exists, not the id itself. Since you were using jQuery I just jQueryfied it, but you could also use

function newBox()
{
  var newElement = document.createElement("div");
  newElement.setAttribute("id", "b"+boxNum);
  newElement.setAttribute("class", "box");
  document.getElementById("boxes").appendChild(newElement);
  //random left variable
  var leftVar = Math.floor(Math.random() * 560) + 5;  
  //set animation          
  TweenLite.fromTo(newElement, 2, { top:-50, left:leftVar }, { top:460, ease:Sine.easeIn });
  TweenLite.delayedCall(.5, newBox);
  boxNum++;
}
P.S. GSAP works well with jQuery objects, so you don't need to use the underlying DOM element for a tween target, a jQuery selection works just as well. Also you can just pass the selector string as your target and GSAP will do the jQuery selection for you

// all work the same
TweenLite.to("#target", 1, { ... });
TweenLite.to($("#target"), 1, { ... });
TweenLite.to($("#target")[0], 1, { ... });
  • Like 1
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...