friendlygiraffe

stop after end repeat

Recommended Posts

Hi there,

 

I have a banner that loops 3 times:

var tl = new TimelineMax({repeat:3});

tl.append( TweenLite.from($(".text1"), 0.5, {alpha:0}));
tl.append( TweenLite.to($(".text1"), 0.5, {alpha:0}),"+=2.5");
tl.append( TweenLite.from($(".text2"), 0.5, {alpha:0}) );
tl.append( TweenLite.to($(".text2"), 0.5, {alpha:0}),"+=2.5" );
tl.append( TweenLite.from($(".tele"), 0.5, {alpha:0}) );
tl.append( TweenLite.to($(".tele"), 0.5, {alpha:0}),"+=2" );
tl.append( TweenLite.from($(".endframe_logos"), 0.5, {alpha:0}) );
tl.append( TweenLite.to($(".endframe_logos"), 0.5, {alpha:0}),"+=4" );

After it's finished the 3 loops,  I don't want the last Tween to fire. instead stopping at the 2nd from last line

 

Is this possible using a label or some such?

 

Thanks

Share this post


Link to post
Share on other sites

How about having a loop variable and a if statement?

var loop = 0;

var tl = new TimelineMax({repeat:3, onComplete:count});

tl.from($(".text1"), 0.5, {alpha:0}));
tl.to($(".text1"), 0.5, {alpha:0}),"+=2.5");
tl.from($(".text2"), 0.5, {alpha:0}) );
tl.to($(".text2"), 0.5, {alpha:0}),"+=2.5" );
tl.from($(".tele"), 0.5, {alpha:0}) );
tl.to($(".tele"), 0.5, {alpha:0}),"+=2" );
tl.from($(".endframe_logos"), 0.5, {alpha:0}) );
if(loop < 2) {
 tl.to($(".endframe_logos"), 0.5, {alpha:0}),"+=4" );
}

function count() {
 loop++;
}

Share this post


Link to post
Share on other sites

Dipscom, that conditional logic wouldn't work because you're running it once when the timeline is created (rather than each iteration). 

 

friendlygiraffe, you could consolidate your code quite a bit by using the convenience methods, chaining, and skipping the jQuery selectors. Here's something that would probably work (though I haven't tested since you didn't provide a codepen demo): 

var tl = new TimelineMax({repeat:3, repeatDelay:0.5}),
    loop = 0;


tl.from(".text1", 0.5, {alpha:0})
  .to(".text1", 0.5, {alpha:0}, "+=2.5")
  .from(".text2", 0.5, {alpha:0} )
  .to(".text2", 0.5, {alpha:0}, "+=2.5")
  .from(".tele", 0.5, {alpha:0})
  .to(".tele", 0.5, {alpha:0}, "+=2")
  .from(".endframe_logos", 0.5, {alpha:0})
  .call(function() {
     loop++;
     if (loop < 3) {
             TweenLite.to(".endframe_logos", 0.5, {alpha:0});
     }
   }, "+=4");

Better?

  • Like 1

Share this post


Link to post
Share on other sites

Dear mr. Almighty Code-God Who Answers by GreenSock,

 

My eyes burn with the vision of you addressing me personally and my soul is elevated into nirvana for receiving advice from your goddiness.

 

Yes, I do forget that detail more often than not. The timeline creation code only runs once. I will return to the dark depths of shame now and brood about it.

  • Like 2

Share this post


Link to post
Share on other sites

LOL. Nice, Dipscom. No need to cower in the dark depths of shame - I'm super appreciative of your contributions here in the forums. It's such a great way for all of us to learn (myself included). Please keep chiming in as much as you can. We're happy you're here!

  • Like 1

Share this post


Link to post
Share on other sites

Dipscom, that conditional logic wouldn't work because you're running it once when the timeline is created (rather than each iteration). 

 

friendlygiraffe, you could consolidate your code quite a bit by using the convenience methods, chaining, and skipping the jQuery selectors. Here's something that would probably work (though I haven't tested since you didn't provide a codepen demo): 

var tl = new TimelineMax({repeat:3, repeatDelay:0.5}),
    loop = 0;


tl.from(".text1", 0.5, {alpha:0})
  .to(".text1", 0.5, {alpha:0}, "+=2.5")
  .from(".text2", 0.5, {alpha:0} )
  .to(".text2", 0.5, {alpha:0}, "+=2.5")
  .from(".tele", 0.5, {alpha:0})
  .to(".tele", 0.5, {alpha:0}, "+=2")
  .from(".endframe_logos", 0.5, {alpha:0})
  .call(function() {
     loop++;
     if (loop < 3) {
             TweenLite.to(".endframe_logos", 0.5, {alpha:0});
     }
   }, "+=4");

Better?

 

Hi jack - I created a CodePen of your method here http://codepen.io/friendlygiraffe/pen/zvjRBd

 

If you run a debug view, it throws an error:

“Uncaught TypeError: Function.prototype.apply: Arguments list has wrong type”

Any ideas? 

 

Thanks

 

 

 

 

Share this post


Link to post
Share on other sites
yeah, simple mistake (which is why we like demos :-P) call() takes 2 additional parameters before position: params and scope
 

the following code would avoid the error

.call(function() {
     loop++;
     if (loop < 2) {
        TweenLite.to(".frame3", 1, {alpha:0});
     }
   }, [], this, "+=4");

However, you will notice that while the tween in that condition is running, the timeline is already repeating. 

 

I'd sugget putting a call() right before the last tween and have it figure out whether the timeline should play through the last tween or pause (on final iteration)

 

var tl = new TimelineMax({repeat:-1}),
    loop = 0;
    loopMax = 3;


tl.from("#frame1", 1, {alpha:0})
  .to("#frame1", 1, {alpha:0}, "+=0.5")
  .from("#frame2", 1, {alpha:0} )
  .to("#frame2", 1, {alpha:0}, "+=0.5")
  .from("#frame3", 1, {alpha:0})
  .call(loopCheck)
  .to("#frame3", 2, {alpha:0, scale:0, rotation:360}, "+=2");


tl.timeScale(3)


function loopCheck() {
  console.log("loopCheck")
     loop++;
     if (loop < loopMax) {
        console.log("play again")
        tl.play();
     } else{
       console.log("done")
       tl.pause();
     }
   }
 

 

http://codepen.io/GreenSock/pen/eprVXV?editors=001

 

notice that the timeline is set to repeat infinitely and the condition above decides whether or not it should keep going

  • Like 4

Share this post


Link to post
Share on other sites

can this be done with just tweenlite and timelinelite?

This is my code below. It loops, but stop at the end. I've been trying to make it stop a few seconds before the end of the timeline but have failed to so.

function start() {
	var bg = document.getElementById('bg'),
		txt_01 = document.getElementById('txt_01'),
		txt_02 = document.getElementById('txt_02'),
		txt_03 = document.getElementById('txt_03'),
		lockup = document.getElementById('lockup'),
		banner = document.getElementById('banner'),
		tl = new TimelineLite();
		tl.eventCallback("onComplete", loopAnimation);

	tl
	.add('f1', 0)
	.add('f2', 4)
	.add('f3', 8)
	.add('f4', 12)

	tl
	.from([txt_01], 1, {x:'-=728px', ease: Power1.easeOut, onStart:function(){banner.style.visibility = 'visible';}})
	.from(txt_02, 1, {x:'-=728px', ease: Power1.easeOut}, 'f2-=0.5')
	.to(txt_01, 0.6, {opacity: 0, ease: Power1.easeOut}, 'f2-=0.6')
	.to(txt_02, 0.6, {opacity: 0, ease: Power1.easeOut}, 'f3-=0.6')
	.staggerFrom([txt_03], 0.6, {opacity: 0, ease: Power1.easeOut}, 0, 'f3+=0.5')
	.to(txt_03, 0.6, {opacity: 0, ease: Power1.easeOut}, 'f4')
	// stops looping animation
	.add('stop', '-=2')



	// start looping animation
	var loopNumber = 0;

	function loopAnimation() {
		loopNumber = loopNumber + 1;

		if (loopNumber >= 2) {
			tl.addPause('stop');
			console.log('Paused');
		} else {
			tl.restart();
			console.log('Times looped = ' + loopNumber);
		}
	}

}

Share this post


Link to post
Share on other sites

try changing

tl.addPause('stop');

to

tl.pause('stop');
  • Like 1

Share this post


Link to post
Share on other sites

thanks carl,

 

that works but it still plays my last animation line then pauses.

.add('stop') // want it to stop here before it plays the line below
.to(txt_03, 0.6, {opacity: 0, ease: Power1.easeOut}, 'f4')

So basically i want it to stop before txt_03 fades out. Its because the timeline hasn't complete its 'loop' yet. So this below hasn't fired yet

if (loopNumber >= 2) {
   tl.pause('stop');
   console.log('Paused');

Does that make sense?

 

What would be the best solution?

Thanks!
 

Share this post


Link to post
Share on other sites

try tl.pause("f4") 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks for this one Carl. That code is really useful for setting up endframes in looped animations :D

 

 

 

yeah, simple mistake (which is why we like demos :-P) call() takes 2 additional parameters before position: params and scope
 

the following code would avoid the error

.call(function() {
     loop++;
     if (loop < 2) {
        TweenLite.to(".frame3", 1, {alpha:0});
     }
   }, [], this, "+=4");

However, you will notice that while the tween in that condition is running, the timeline is already repeating. 

 

I'd sugget putting a call() right before the last tween and have it figure out whether the timeline should play through the last tween or pause (on final iteration)

 

var tl = new TimelineMax({repeat:-1}),
    loop = 0;
    loopMax = 3;


tl.from("#frame1", 1, {alpha:0})
  .to("#frame1", 1, {alpha:0}, "+=0.5")
  .from("#frame2", 1, {alpha:0} )
  .to("#frame2", 1, {alpha:0}, "+=0.5")
  .from("#frame3", 1, {alpha:0})
  .call(loopCheck)
  .to("#frame3", 2, {alpha:0, scale:0, rotation:360}, "+=2");


tl.timeScale(3)


function loopCheck() {
  console.log("loopCheck")
     loop++;
     if (loop < loopMax) {
        console.log("play again")
        tl.play();
     } else{
       console.log("done")
       tl.pause();
     }
   }
 

 

http://codepen.io/GreenSock/pen/eprVXV?editors=001

 

notice that the timeline is set to repeat infinitely and the condition above decides whether or not it should keep going

 

Share this post


Link to post
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.