Hello!
Obviously, first of all, thanks so much for barba!
I'm not good at JS and I'm struggling to build a transition. It's actually working, but I'm pretty sure I'm not building it in the best way... And maybe you could give me advice!
My transition uses a "visual" div that takes time to load, using TweenMax. And I want to be sure it always finishes its animated timeline before getting rid of it. I had it mind to trigger the start function only when the animation has finished, but can't find a way to do it. That means, that if the new content loads fast or is cached, my animation doesn't get to its end.
My idea is:
I'm sure there must be something more "elegant" than the timeOut I'm using on the Promise!
var myTransition = Barba.BaseTransition.extend({
start: function() {
loadBlocks();
_this = this;
setTimeout(function(){
Promise
.all([_this.newContainerLoading, _this.startTransition()])
.then(_this.finishTransition.bind(_this));
}, 2000);
},
startTransition: function() {
Nothing Yet
},
finishTransition: function() {
document.body.scrollTop = 0;
setBackgroundColor(this.newContainer);
unloadBlocks();
// Finish transition
this.done();
initScrollbar();
}
});
Barba.Pjax.getTransition = function() {
return myTransition;
};
Thanks a lot in advance!
You'll have to create a second promise for your animation. Since you're using tweenmax you can use the onComplete callback to resolve a promise, then continue the transition.
This is an example from a site I'm currently working on:
maskOut: function() {
return new Promise( ( resolve, reject ) => { // <-- Promise is created
anime( {
targets: '.cover',
clipPath: [ initial, show ],
webkitClipPath: [ initial, show ],
duration: duration,
easing: 'easeInOutQuart',
complete: function() {
resolve(); // <-- Promise is resolved
}
} );
} );
},
Note that I'm using anime.js instead of TweenMax, but TweenMax has a similar onComplete callback.
maskOut would be the same as your start function. Notice how I've set up a promise and then resolved it in the complete callback? Nothing will run until that promise is resolved, and once it has been resolved it will continue on with the transition. Therefore nothing will run until the animation has finished, regardless of if the next page has loaded or not.
If you post an example of what loadBlocks(); looks like I could potentially help you further if my reply doesn't make sense.
Cheers!
Brilliant mate! Thanks a lot, it's working now.
I'm struggling to understand how promises work, I'm using a "return" to stop the function and it works well now.
Although I don't undertand why it does need the "return", since it shouldn't do anything until TweenMax resolves the promise. What am I missing?!
start: function() {
Promise
.all([this.newContainerLoading, this.startTransition()])
.then(this.finishTransition.bind(this));
},
startTransition: function() {
var transitionPromise = new Promise(function(resolve, reject) {
var loadTransition = new TimelineMax({onComplete:function(){ resolve(); } });
loadTransition
.set(blocksColor, {display:'block'})
.set(blocksColorElements, {marginLeft:0, width:0})
.set(blocksBlack, {display:'block'})
.set(blocksBlackElements, {marginLeft:0})
.set(".project-transition", {display:'block'})
.set(".project-transition__eye", {opacity:0})
.addLabel("loading")
.staggerTo(blocksColorElements, 0.75, {width:blockWidth}, 0.075, "loading")
.staggerTo(blocksBlackElements, 0.75, {width:blockWidth}, 0.075, "loading+=0.1")
.to(".project-transition__eye", 0.25, {opacity:1}, "loading+=0.5")
.to(".project-transition__title", 0.25, {opacity:1}, "loading+=0.6")
.set(".project-transition", {display:'block'}, "+3");
});
// Stops the function
return transitionPromise;
},
I'm quite new at JS and it may be difficult to explain it properly. If you have a change I'd really appreciate it.
Tthanks a lot mate, saved me!
@kram08980 In my example I gave, the return is right before the promise so it's doing the exact same thing. Glad it works! 馃憤
By using a variable, it's not running until you return it, so your return transitionPromise; isn't actually stopping the function, it's starting it.
Most helpful comment
You'll have to create a second promise for your animation. Since you're using tweenmax you can use the onComplete callback to resolve a promise, then continue the transition.
This is an example from a site I'm currently working on:
Note that I'm using anime.js instead of TweenMax, but TweenMax has a similar onComplete callback.
maskOut would be the same as your start function. Notice how I've set up a promise and then resolved it in the complete callback? Nothing will run until that promise is resolved, and once it has been resolved it will continue on with the transition. Therefore nothing will run until the animation has finished, regardless of if the next page has loaded or not.
If you post an example of what loadBlocks(); looks like I could potentially help you further if my reply doesn't make sense.
Cheers!