Jump to content
MadderMax

Returning a promise from a TimelineLite .onComplete()

Recommended Posts

Hopefully I can explain this without writing up a Codepen since Backbone takes a minute to get going, if this is unclear Ill gladly set it up tho.
 
I want to chain a timeline animation into another function, WITHOUT referencing my view in the "onComplete" of the timeline. My idea is to do this with the new Promise object in JS, but I have no idea how to do this. Here is what I got so far

// some random BB function
var ping = function(){ console.log('promise finished') };

// define our timeline
var t = new TimelineLite({
  paused: true,
  onComplete: function(){ 
      // what do I return here to be able to chain a promise 
  }
});

// run the chain

t.play().then(function(res){ ping() });

 
Obviously this doesn't work since .play() doesn't return anything, but I'm hoping there is a way to combo a .then() from the onComplete param of the timeline. 
 
Thanks in advance and happy to be posting on the forum for the first time.
 
p.s. I know I can technically pass the view itself into the timeline and trigger a function from onComplete or an event, but I'm (1) trying to keep BB and GS decoupled, and (2) curious if my question has an answer regardless if it's the better solution.

Share this post


Link to post
Share on other sites

Hi and welcome to the GreenSock forums,

 

It's important to note that methods like play(), reverse(), timeScale() do return something, they return the timeline instance that they have been called on. This is a big part of the API that allows for chaining

var tl = new TimelineLite();
// ... add a bunch of tweens ...

tl.play().timeScale(3)
tl.reverse().timeScale(1)

//or even

tl.progress(1).play(0) // jump to the end, record all starting and ending values then go back to beginning and play

Just putting that out there so you can see that if the play() method returned something else (like a promise) it would be a huge change.

 

Unfortunately, I'm at a loss for thinking of an elegant way to accomplish what you want. There might be one or two smart cookies around here though that have an idea.

Share this post


Link to post
Share on other sites

You're absolutely right - maaaaaybe I can spark a solution with this:

 

I HAVE been able to turn a timeline into a promise using this method, but where I get stuck with this approach is I dont know how to call .play() or .reverse() when I set up the encapsulation this way

var timelinePromise = function(){
	return new Promise(function(resolve){
	
		var t = new TimelineLite({
			paused: true,
			onComplete: function(){ 
				console.log('on complete resolving')
				resolve(true)
			}
		}).to( $('.testing'), 1, { width: 200, height: 200 } );

		t.play();
	});
}
	
timelinePromise().then(function(res){ console.log('promise resolved') });

CP for refrence: 

See the Pen ef5a47e2927f66b3791ecc5a346c6067?editors=0010 by koolhaus (@koolhaus) on CodePen

 

Ive been able to successfully use Tweens this way, but the point of a timeline here is that I can keep play/reversing the animation where as the Tweens ive used have been a one time execution.

  • Like 1

Share this post


Link to post
Share on other sites

Not sure what you're trying to do, but why don't you just create the timeline outside the promise if you want to access it?

See the Pen b4c2aada8cb7c5d1672bc41634ce4074?editors=0010 by osublake (@osublake) on CodePen

 

And check these out...

 

Extensive use of promises using Q

See the Pen jEyjrd?editors=0010 by ThomasBurleson (@ThomasBurleson) on CodePen

 

GSAP Promise wrapper using Bluebird

https://github.com/mattdesl/gsap-promise

  • Like 5

Share this post


Link to post
Share on other sites

Awesome solution, Blake!

 

to take it an inch further I would suggest defining and building the timeline outside the timelinePromise() function so that you can pass any animation (tween or timeline) into it

 

var t = new TimelineLite({paused: true});
t.to($(".testing"), 1, {width: 200,height: 200});

var timelinePromise = function(timeline) {
   return new Promise(function(resolve) {
      //alternate syntax for adding a callback
      timeline.eventCallback("onComplete", function() {
         console.log('on complete resolving')
         resolve(true)
      })
   });
}

//pass any animation into timelinePromise
timelinePromise(t).then(function(res) {
    console.log('promise resolved')
});
  • Like 4

Share this post


Link to post
Share on other sites

Ohhhh snap guys, thats exactly what I was looking for!

 

Blake - I had no idea I could do t.vars.onComplete() AFTER the timeline has been initialized, thats what was making all of this so difficult for me.

 

Carl - Also a great suggestion, I learned a few new techniques thanks to you guys.

 

Appreciate the responses and help guys, Cheers.

  • Like 3

Share this post


Link to post
Share on other sites

I needed this too so I made a small module to take care of it: gsap-then (0.2KB)

 

Carl's example would be as simple as:

var t = new TimelineLite({paused: true});
t.to($(".testing"), 1, {width: 200,height: 200});
t.then(function(res) {
  console.log('promise resolved')
});

Additionally it takes care of existing onComplete callbacks and can be used multiple times on the same tween.

 

Side note: This is vastly different from the package gsap-promise because it simply extends existing GSAP objects by adding a .then() method to the tweens in a few bytes, rather than loading a new library and wrapping GSAP.

  • Like 5

Share this post


Link to post
Share on other sites

Nice work, bfred. Thanks for offering this to folks. 

  • Like 1

Share this post


Link to post
Share on other sites

Interesting topic. Unfortunately Bfred.it's link containing gsap-then is down– is there any chance to get it back? 

Share this post


Link to post
Share on other sites
6 hours ago, kreativzirkel said:

Interesting topic. Unfortunately Bfred.it's link containing gsap-then is down– is there any chance to get it back? 

 

It seems to be working fine.

https://github.com/bfred-it/gsap-then

 

If you're looking into using promises, here's a thread that might help.

 

  • Like 1

Share this post


Link to post
Share on other sites

Misunderstanding; the actual website that the link refers to was broken; github showed a fancy unicorn and said the page wasn't available.

Now it works, thanks–

 

angry_unicorn.png

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.