I'm new to barba.js so just trying to get my head round it.
When a page transition is performed, my browser page scroll stays where it was. Is this intentional?
Is it possible to have it so after the transition the next page is loaded at the top like normal?
Here is my code
function pageTransition() {
var tl = gsap.timeline();
tl.to('ul.transition li', { duration: .5, scaleY: 1, transformOrigin: "top left", stagger: .2 })
tl.to('ul.transition li', { duration: .5, scaleY: 0, transformOrigin: "top left", stagger: .1, delay: .1})
}
function contentAnimation() {
var tl = gsap.timeline();
tl.from('.hero', { duration: 1, translateY: 50, opacity: 0 })
}
function delay(n){
n = n || 2000;
return new Promise(done => {
setTimeout(() => {
done();
}, n)
});
}
barba.init({
sync: true,
transitions: [{
async leave(data) {
const done = this.async();
pageTransition();
await delay(500);
done();
},
async enter(data) {
contentAnimation();
},
async once(data) {
contentAnimation();
}
}]
});
After checking through the docs again I found the hooks.
barba.hooks.enter(() => {
window.scrollTo(0, 0);
});
This solves the issue if anyone else is having the same issue.
Related
//Animation on slider
const tl = gsap.timeline({ defaults: { ease: "power1.out" } })
tl.to(".text", { y: "0%", duration: 1 });
tl.to(".slider", { y: "-100%", duration: 1.5, delay: 0.5 });
tl.to(".intro", { y: "-100%", duration: 1 }, "-=1");
tl.fromTo("nav", { opacity: 0 }, { opacity: 1, duration: 0.5 });
tl.fromTo(".shortDescription", { opacity: 0 }, { opacity: 1, duration: 0.5 });
tl.fromTo("footer", { opacity: 0 }, { opacity: 1, duration: 0.5 });
/*Animation on the Nav Bar
const sections = document.querySelectorAll('.selection');
const bubble = document.querySelector('.bubble');
const gradient = ["linear-gradient(to top, #30cfd0 0%, #330867 100%)"
"linear-gradient(to top, #a8edea 0%, #fed6e3 100%)"
];
const options = {
threshold: 0.7
};
let observer = new IntersectionObserver(navCheck, options);
function navCheck(entries) {
entries.forEach(entry => {
console.log(entry);
});
};
section.forEach(section => {
observe.observe(section);
});*/
This is the whole javascript code that I have, I currently put the nav bar animation to a comment for the gsap slider to work. but when I'm already trying to input the nav bar animation the gsap code stops working so the whole set would be stuck with the color black and it won't slide through, so you won't see the page itself.
I'm using barba.js to fade new pages in. Code must be placed between the barba wrapper div. When I click a link to a new page though, the new page fades in at the same position as the previous page was in. So if the user clicks a link, the new page is loading in near , which I don't want.
How can I get the new page to load in at the top?
I found the answer on stack about scrollRestoration function but I still don't understand how to make this work.
Could somebody help me to compile the js code below, add some css or html to fix this issue?
$(window).scrollTop(0);
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
function delay(n) {
n = n || 2000;
return new Promise((done) => {
setTimeout(() => {
done();
}, n);
});
}
function pageTransition() {
var tl = gsap.timeline();
tl.to(".animate-this", {
duration: .2, opacity: 0, delay: 0, y: 30, //scale:0, delay: 0.2,
});
tl.to(".animate-this", {
duration: 0, opacity: 0, delay: 0, scale:0, //scale:0, delay: 0.2,
});
tl.fromTo(".loading-screen", {width: 0, left: 0}, {
duration: 1,
width: "100%",
left: "0%",
ease: "expo.inOut",
delay: 0.3,
});
tl.to("#svg-1", {
duration: 1, opacity: 0, y: 30, stagger: 0.4, delay: 0.2,
});
tl.to(".loading-screen", {
duration: 1,
width: "100%",
left: "100%",
ease: "expo.inOut",
delay: 0, //CHANGE TIME HERE END TRANS
});
tl.set(".loading-screen", { left: "-100%", });
tl.set("#svg-1", { opacity: 1, y: 0 });
}
function contentAnimation() {
var tl = gsap.timeline();
tl.from(".animate-this", { duration: .5, y: 30, opacity: 0, stagger: 0.4, delay: 0.2 });
}
$(function () {
barba.init({
sync: true,
transitions: [
{
async leave(data) {
const done = this.async();
pageTransition();
await delay(2500);
done();
},
async enter(data) {
contentAnimation();
},
async once(data) {
contentAnimation();
},
},
],
});
});
Have a look:
https://pasteboard.co/Ja33erZ.gif
Here also a codepen to check my issue (html,css):
https://codepen.io/cat999/project/editor/AEeEdg
scrollRestoration shouldn't be necessary, this can be done by resetting scroll position during the transition:
tl.fromTo(".loading-screen", {width: 0, left: 0}, {
duration: 1,
width: "100%",
left: "0%",
ease: "expo.inOut",
delay: 0.3,
onComplete: function() {
window.scrollTo(0, 0);
}
});
Working example here: https://codepen.io/durchanek/project/editor/ZWOyjE
This should be what you're looking for:
barba.hooks.enter(() => {
window.scrollTo(0, 0);
});
(can be found in the docs)
I have created animations that trigger when elements enter in viewport. Problem is that I have to repeat same code for every element. I'm using anime.js and scrollMonitor.js for animations, and it's kinda hard to make working for-loop.
Here is my code:
$(window).on("load", function() {
'use strict';
var elementWatcher1 = scrollMonitor.create('#about', -200);
elementWatcher1.enterViewport(function() {
var startAnimation = anime.timeline();
startAnimation
.add({
targets: '#about .toAnimate',
translateY: [50, 0],
opacity: 1,
duration: 600,
delay: function(el, index) {
return index * 80;
},
easing: 'easeOutQuad'
});
this.destroy();
});
var elementWatcher2 = scrollMonitor.create('#portfolio', -200);
elementWatcher2.enterViewport(function() {
var startAnimation = anime.timeline();
startAnimation
.add({
targets: '#portfolio .toAnimate',
translateY: [50, 0],
opacity: 1,
duration: 600,
delay: function(el, index) {
return index * 80;
},
easing: 'easeOutQuad'
});
this.destroy();
});
var elementWatcher3 = scrollMonitor.create('#gallery', -200);
elementWatcher3.enterViewport(function() {
var startAnimation = anime.timeline();
startAnimation
.add({
targets: '#gallery .toAnimate',
translateY: [50, 0],
opacity: 1,
duration: 600,
delay: function(el, index) {
return index * 80;
},
easing: 'easeOutQuad'
})
.add({
targets: '#gallery .toAnimateToo',
opacity: 1,
duration: 600,
delay: function(el, index) {
return index * 80;
},
easing: 'easeOutQuad',
offset: 0
});
this.destroy();
});
});
Does anyone have idea how can I put this in for-loop?
In ES5 just use a forEach loop on an array of those selectors:
$(window).on("load", function() {
'use strict';
["#about", "#portfolio", "#gallery"].forEach(function(selector) {
var elementWatcher = scrollMonitor.create(selector, -200);
elementWatcher.enterViewport(function() {
var startAnimation = anime.timeline();
startAnimation
.add({
targets: selector + ' .toAnimate',
translateY: [50, 0],
opacity: 1,
duration: 600,
delay: function(el, index) {
return index * 80;
},
easing: 'easeOutQuad'
});
this.destroy();
});
});
});
In ES2015+, you could use for-of instead (with const for elementWatcher) instead.
I use TweenMax to animate divs with multiples .mouseover but I'd like one to complete before starting another one.
In this JSFiddle, you can see the divs overlap if going to fast on the links.
Is there an easy solution for this ?
$(document).ready(function() {
var blocPrototypo = $("#wrap-image-menu");
$("#prototypo").mouseover(function() {
TweenLite.to(blocPrototypo, 1.4, {
backgroundColor: "#24d390",
ease: Circ.easeInOut
});
TweenMax.to(blocPrototypo, 0.5, {
width: "39vw",
ease: Circ.easeInOut,
repeat: 1,
yoyo: true
});
var allExcept = $(".all-img-menu").not(document.getElementById("img-prototypo"));
TweenMax.to(allExcept, 0.9, {
left: "0px",
opacity: 0
});
TweenMax.to($("#img-prototypo"), 0.7, {
opacity: "1",
width: "55vw",
left: "-90px",
ease: Expo.easeOut,
delay: "0.65"
});
TweenMax.to($("#line-pagination"), 0.5, {
width: "76px",
ease: Circ.easeInOut,
repeat: 1,
yoyo: true
});
$("#current-page").fadeOut(function() {
$(this).text("01").fadeIn(1000);
});
});
$("#esadvalence").mouseover(function() {
TweenLite.to(blocPrototypo, 1.5, {
backgroundColor: "#e12a1c",
ease: Power1.easeOut
});
TweenMax.to(blocPrototypo, 0.5, {
width: "39vw",
ease: Circ.easeInOut,
repeat: 1,
yoyo: true
});
var allExcept = $(".all-img-menu").not(document.getElementById("img-esadvalence"));
TweenMax.to(allExcept, 0.9, {
left: "0px",
opacity: 0
});
TweenMax.to($("#img-esadvalence"), 0.7, {
opacity: "1",
width: "55vw",
left: "-90px",
ease: Expo.easeOut,
delay: "0.65"
});
TweenMax.to($("#line-pagination"), 0.5, {
width: "76px",
ease: Circ.easeInOut,
repeat: 1,
yoyo: true
});
$("#current-page").fadeOut(function() {
$(this).text("02").fadeIn(1000);
});
});
});
TweenLite and TweenMax have onComplete callbacks that can be used to await completion prior to beginning the next operation:
TweenLite.to(blocPrototypo, 1.5, {
backgroundColor: "#e12a1c",
ease: Power1.easeOut,
onComplete: function() {
// perform next operation
}
});
There is also params you can pass via onCompleteParams, which you could perhaps use to indicate to some generic function the next operation you'd want to execute.
TweenLite.to(blocPrototypo, 1.5, {
backgroundColor: "#e12a1c",
ease: Power1.easeOut,
onCompleteParams: [{ prop1: value1, prop2: value2 }],
onComplete: function(someParams) {
// perform next operation using passed params
}
});
Another approach could be using Promise or jQuery Deferred in combination with the onComplete event callback such as:
function foo() {
return new Promise(function(resolve, reject) {
TweenLite.to(blocPrototypo, 1.5, {
backgroundColor: "#e12a1c",
ease: Power1.easeOut,
onComplete: function() {
return resolve(true);
}
});
});
}
foo().then(function() {
// perform next operation
});
Hopefully that helps!
I have been trying to get the animation to fire off on click, I have created the animated via TimelineMax. I can't see why but it keeps firing off the first instance of this animation, there are 5 .blackout-panel and it plays the animation automatically for the first .blackout-panel, but I have no idea why - I want the full animation to be controlled by on click.
var showBarsTL = new TimelineMax({ paused: true, onComplete: killAnimation });
$('.portfolio-panel').on("click", function () {
showBarsTL.play()
});
showBarsTL.add (TweenMax.staggerTo(".blackout-panel", 0, {y:100+ '%', onStart: "", onStartParams:["{self}"], ease: Power1.easeInOut}, 0.1275, 0));
showBarsTL.add (TweenMax.from(".blackout-panel", 0, {css:{top:"auto", bottom:"0"}}));
showBarsTL.add (TweenMax.staggerTo(".blackout-panel", 0, {css:{height:"0", bottom:"0", top:"auto"}, delay: 0.1275, ease: Power1.easeInOut}, 0.1275));
function killAnimation() {
showBarsTL.clear();
}
I have created a codePen to demonstrate this: http://codepen.io/Tekkie/pen/XpBOYV/?editors=1010
Any guidance would be appreciated. Also my killAnimation function doesn't seem to be getting fired.
EDIT: 1 - I have resolved the pausing issue by putting a delay. My new JS is as follows:
var $blackoutPanels = $('.blackout-panel');
var showBarsTL = new TimelineMax({ paused: true });
showBarsTL
.add (TweenMax.staggerTo($blackoutPanels, **0.1275**, {y:100+ '%', onStart: "", onStartParams:["{self}"], ease: Power1.easeInOut}, 0.1275, 0))
.add (TweenMax.from($blackoutPanels, 0, {css:{top:"auto", bottom:"0"}}))
.add (TweenMax.staggerTo($blackoutPanels, 0, {css:{height:"0", bottom:"0", top:"auto"}, delay: 0.1275, ease: Power1.easeInOut}, 0.1275));
$('.portfolio-panel').on("click", function () {
showBarsTL.play();
});
EDIT: 2 - I have resolved all issues using the following JS:
var $blackoutPanels = $('.blackout-panel');
var showBarsTL = new TimelineMax({
paused: true
});
showBarsTL
.add(TweenMax.staggerFrom($blackoutPanels, 0, {
yPercent: -100,
top: -100 + "%",
onStartParams: ["{self}"],
ease: Power0.easeInOut
}, 0, 0))
.add(TweenMax.staggerTo($blackoutPanels, 0.3, {
yPercent: 0,
top: 0,
onStartParams: ["{self}"],
ease: Power1.easeInOut
}, 0.125, 0))
.add(TweenMax.to($blackoutPanels, 3, {
yPercent: +100,
top: +100 + "%",
onStartParams: ["{self}"],
delay: 0.3,
ease: SlowMo.ease.config(0.4, 1, false)
}, 0.3, 0))
.add(TweenMax.to($blackoutPanels, 0, {
yPercent: -100,
top: -100 + "%",
delay: 0.375
}));
$('.portfolio-panel').on("click", function() {
showBarsTL.restart(false, false);
});
Try to set the pause like this:
var showBarsTL = new TimelineMax({onComplete: killAnimation }).paused(true);
and in your function:
$('.portfolio-panel').on("click", function () {
showBarsTL.paused(false);
});