Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
cerulean

Repeat staggered tween once but keep last element repeating

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

Basically what the title says....I'm not attaching a CodePen as it's more or less an API question I think...

 

I've got a collection of `divs`in a circle shape.  I collect these in an array and then TweenMax.staggerTo on all of them with yoyo:1 and repeat:1 so that they quickly tween back to how they were when they started.  But I'd like the last one to remain in the tweened state, that is "yoyo" all of the elements except the last.  What's the simplest way to do this? (If there is a way).

 

 TweenMax.staggerTo(myArrayOfDivs, .5, {
            repeat: 1,
            backgroundColor: "rbga(100,255,255,0.9)",
            scale: 1.2,
            yoyo: true,
        }, .05).length;
    }
    // how to keep myArrayOfDivs[length-1] tweened?

 

I thought of doing a staggerTo on all but the last element of the array (i.e., create a new array with all but the last element), setting a onCompleteAll on the staggerTo and then tweening the last element separately, but that didn't work, as I don't want it to start when all of the rest have tweened and yoyo'd, but for all to flow seamlessly as if it were one tween. 

 

 

 

Any suggestions welcome!

Link to comment
Share on other sites

staggerTo() creates and array of tweens. You can grab the last tween and set repeat(0)

 

var tweens = TweenMax.staggerTo("div", 1, {x:100, yoyo:true, repeat:1}, 0.5);
tweens.pop().repeat(0);

 

See the Pen JZvjgO?editors=1010 by anon (@anon) on CodePen

 

  • Like 3
Link to comment
Share on other sites

To expand on the original question, the following does exactly what I want it to do -- it staggerTo's around my circle of DIVs once and then leaves the second element tweened.

 

const tweens = TweenMax.staggerTo(myArrayOfDivs, .5, {
    repeat: 1,
    backgroundColor: "rbga(100,255,255,0.9)",
    scale: 1.2,
    yoyo: true
}, .05);
tweens.pop().repeat(0);


If I wish to continue the process and now start a staggerTo on the currently highlighted element (the second in the array), have it tween back to its original value and then continue with the yoyo tweens (as per above) to now end up on the _third_ element at keep that tweened, how do I do that?

    I can take care of the array mechanics -- that is, set up an array with the currently tweened element as the first element, followed by all the other divs and then repeating the first element and ending with the last element), but now what I'd like is to have the _first_ tween only go _backwards_ (i.e. the yoyo portion) and the last tween (as above) only go _forwards.  To get the last tween correct I simply pop it off staggerTo and do what you suggested above.  To get the first tween correct do I shift() the first tween off and then do something to it?  Thus, I'm curious what to do in the last line below...is it reverse()?

const tweens = TweenMax.staggerTo(myNewArrayofDivsSetupForSecondRound, .5, {
    repeat: 1,
    backgroundColor: "rbga(100,255,255,0.9)",
    scale: 1.2,
    yoyo: true
}, .05);
tweens.pop().repeat(0);
tweens.shift().something(); // what do I do here to make the tween only go in reverse?

 

 

I thought the answer might be a final


 

tweens.shift().reverse()

but that didn't work.  Any clues appreciated.

Link to comment
Share on other sites

Sorry, I can't follow your description.

My best guess was to try reverse() but since that didn't work, please look at the staggerTo() docs and watch the video for cycle

https://greensock.com/docs/TweenMax/static.staggerTo()

 

Perhaps you can run some logic on the index of the current tween and then modify that tween in some way.

 

Another approach might be looping through all the elements, building tweens for each one, and inserting them in a timeline.

 

Ultimately I think this is going to come down to the code you write to assess the state of each tween in the group and what you need to have happen next. I really don't think there is an API feature that is going to specifically handle the case you are describing.

 

 

 

Link to comment
Share on other sites

OK, thanks.  I've added a CodePen, if that helps you see things more clearly.  To get the animation started, type something in the input field and hit return.  It feels so close -- I tried .reverse(), I tried reverse() and setting yoyo to false, I tried progress(0.5) -- nope....  If anything occurs to you, please let me know.  Otherwise I can use a timeline as you suggest...  CodePen is here: https://codepen.io/Cerulean3/pen/OEZVjm -- https://codepen.io/Cerulean3/pen/OEZVjm

 

 

Link to comment
Share on other sites

By the way, the relevant code is in Animation.animate() -- there's a lot of JS to wade through.  But it's the only GSAP code in there at the moment, so you can just search for staggerTo and you'll find it rapidly.  I only loop through twice at the moment, in an inelegant way.  Just trying to understand it.

 

Link to comment
Share on other sites

Sorry, I don't think I can help you. I really don't know what the end result is supposed to be or where to begin in trying to decipher all the array stuff.

    this.animate = function () {


        let tmparr = this.letters.slice();

        tmparr = tmparr.concat(tmparr.slice(0,2));


        const tweens = TweenMax.staggerTo(tmparr, .5, {
            repeat: 1,
            backgroundColor: "rbga(100,255,255,0.9)",
            scale: 1.2,
            yoyo: true
        }, .05,doNext,[],this);
        tweens.pop().repeat(0);


        function doNext() {
            let arr = this.letters.slice();
            arr.push(arr.shift());
            arr = arr.concat(arr.slice(0,2));
            debug("array is",arr[0]);

            const tweens = TweenMax.staggerTo(arr, .5, {
                repeat: 1,
                backgroundColor: "rbga(100,255,255,0.9)",
                scale: 1.2,
                yoyo: true
            }, .05);
            tweens.pop().repeat(0);
            tweens[0].reverse;
        }
    }

}

 

Perhaps someone else will have some time later on.

  • Like 2
Link to comment
Share on other sites

Yeah I had a hard time following everything too.

 

Maybe you could make a simplified demo with a few divs and just enough code to demonstrate the problem? I think that would really help get you some answers. 

 

Happy tweening.

 

  • Like 2
Link to comment
Share on other sites

Thanks @PointC  -- I've made a new CodePen, vastly simplified.  

See the Pen pKVYyq by Cerulean3 (@Cerulean3) on CodePen

 

 

As you can see there is a circle with the letters of the alphabet.  In this example I'd like to start with "B" (I'm avoid the special case of "A" as first in the alphabet for purposes of the demo), do an animation of the full circle and then leave B in the highlighted state.  Thanks to @Carl that works fine with TweenMax.staggerTo. On the next round I'd like to start with the next letter in the alphabet -- C in this case -- and do the same thing.  However I want the  letter that remained highlighted from the previous round -- B in this case -- to go back to its normal state.  Obviously I can just tween it back before starting the next TweenMax.staggerTo, but I want it to flow seamlessly with the main animation and I'm not sure how to do that.   One thought is to use TimelineMax and insert first a TweenMax of the highlighted letter and then the staggerTo of the rest, calculating when to start the staggerTo so that it seems seamless.  But I was wondering if there were an easier way.

 

  • My thought was to access the first tween in the array returned by staggerTo and then to tweak it  -- using, perhaps seek or progress so that it only started in the yoyo part of the tween.  That doesn't seem to work

 

 

Thanks for any clues....

Link to comment
Share on other sites

I'm still not sure I'm following everything. Do you want the highlighted letter to fully reverse before the next stagger starts? Like this?

 

See the Pen LrrPXY by PointC (@PointC) on CodePen

Or did you mean that highlighted element reverse would blend in with the next stagger? If that's the case you can change the delay value in the if statement to match your stagger value of .05.

 

Does this help at all or am I not understanding the desired outcome here?

 

Happy tweening.

 

Link to comment
Share on other sites

  • Sahil changed the title to Repeat staggered tween once but keep last element repeating

@PointC -- thanks very much! -- it's the second option I was looking for: " that highlighted element reverse would blend in with the next stagger".  

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.

×