Jump to content
Search Community

Shorter way to animate multiple elements into different end positions?

LipstickVoid test
Moderator Tag

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

Such as dealing of cards. You are doing a similar animation but each element ends up in a slightly different position.

 

I know I can animate them one by one and delay each one slightly like in the example code below but is there a shorter and more effective/elegant way of doing this?

 

Thanks in advance!

.to('.element1', 1, { x: "+=30",  ease: Power3.easeInOut }, "frame1+=1")
.to('.element2', 1, { x: "+=60",  ease: Power3.easeInOut }, "frame1+=1.15")
.to('.element3', 1, { x: "+=90",  ease: Power3.easeInOut }, "frame1+=1.25")
Link to comment
Share on other sites

There are a bunch of ways to approach this. Here's one that uses function-based values:

.staggerTo(".element1, .element2, .element3", 1, {x: function(i) {
    return "+=" + (i * 30);
}, ease:Power3.easeInOut}, 0.15, "frame1+=1");

Or use a function that does all the repetitive stuff for you and you just feed in the variables. 

 

Does that help?

  • Like 1
Link to comment
Share on other sites

There are a bunch of ways to approach this. Here's one that uses function-based values:

.staggerTo(".element1, .element2, .element3", 1, {x: function(i) {
    return "+=" + (i * 30);
}, ease:Power3.easeInOut}, 0.15, "frame1+=1");

Or use a function that does all the repetitive stuff for you and you just feed in the variables. 

 

Does that help?

 

Yes, it answers my question. Thank you. What if the end positions are not cookie cutter like it's not increasing by 30 each time but a bit random? How would you approach that?

Link to comment
Share on other sites

Sure, it can be as random as you like.

Here is a demo slightly modified from our docs:

See the Pen xRwwoQ?editors=0010 by GreenSock (@GreenSock) on CodePen

 

 

staggerTo() with cycle: http://greensock.com/docs/#/HTML5/GSAP/TimelineLite/staggerTo/ Watch the video to see how flexible the cycle feature can be.

 

Sorry. I'll try my best to explain what I have in mind.

 

I didn't mean random as in randomizing it with code but rather if I was animating elements which aren't of the same width or height that placing them evenly cannot be the same value. The spacing between the elements should look even to our eyes but if the element sizes are different we can't keep adding the same value because X is counting from the element's initial position. For example, I want 10px spacing between each element and ALL the elements are initially at X: 0 position. Element A is 20px wide, element B is 30px and element C is 5px. So, I move element A 10px to the right side. Element B should be moved the total of element A width + the width element A moved + spacing width. Element C should move the total of element A width + the width element A moved + element B width + the width element B moved + spacing width. It's like the dealer spreading a deck of cards evenly except that cards' width and height aren't the same.

 

Or am i getting more confusing?

Link to comment
Share on other sites

Sounds like you just need to implement the logic using math, that's all. Sorta like (not real code, and this assumes you start out with them all absolutely positioned with their top/left edges aligned):

var tl = new TimelineLite({delay:1});
var gap = 10; //pixels between each
var stagger = 0.15;
var x = 0;
for (var i = 1; i < elements.length; i++) {
    x += (elements[i-1].offsetWidth + gap) - elements[i].offsetWidth;
    tl.to(elements[i], 1, {x:x, ease:Power3.easeInOut}, i * stagger);
}

You could easily tuck that into a function and parameterize it so that you can apply the logic in multiple scenarios. 

  • Like 1
Link to comment
Share on other sites

Sounds like you just need to implement the logic using math, that's all. Sorta like (not real code, and this assumes you start out with them all absolutely positioned with their top/left edges aligned):

var tl = new TimelineLite({delay:1});
var gap = 10; //pixels between each
var stagger = 0.15;
var x = 0;
for (var i = 1; i < elements.length; i++) {
    x += (elements[i-1].offsetWidth + gap) - elements[i].offsetWidth;
    tl.to(elements[i], 1, {x:x, ease:Power3.easeInOut}, i * stagger);
}

You could easily tuck that into a function and parameterize it so that you can apply the logic in multiple scenarios. 

 

Sorry for the late reply. Thanks. I will try implementing with your example.

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