当我进入主页 (index.html) 并导航到工作页面时,一切都按预期进行。但是一旦我刷新工作页面中的页面而不是初始页面,一切都会停止工作——这可能是什么原因?
我已经尝试在 barbajs 代码中刷新动画,但似乎即使使用 Barba 视图显式重新初始化动画也不起作用。
YOUTUBE 视频:https://www.youtube.com/watch?v=FbkBvcjlCYI&t=33s
// Main Scripts
function initScripts() {
initNavAnimations();
initMagneticButtons();
initButtonsAnimations();
initHomeAnimations();
//initWorkPageAnimations() --> it used to be here but I'm now calling it specifically on the barba view to see if something works.
}
// NOTE: data.next = current container
barba.init({
sync: true,
timeout: 7000,
debug: true, // !IMPORTANT
views: [{ // THIS IS WHERE I'M CALLING MANUALLY BUT NOTHING STILL WORKS
namespace: 'work-page',
afterEnter() {
initWorkAnimations();
ScrollTrigger.refresh();
console.log('WORRRRRRK PAFGE ENTER');
},
}],
transitions: [{
name: 'default',
async once(data) {
// Once page loads
initSmoothScroll(data.next.container);
initScripts();
},
async leave(data) {
pageTransitionIn(data, this)
await delay(1200)
data.current.container.remove();
},
async enter(data) {
pageTransitionOut(data, this);
},
async beforeEnter(data) {
ScrollTrigger.getAll().forEach((x) => x.kill());
console.log('destroying everything');
locoScroll.destroy(); // Optional!
initSmoothScroll(data.next.container);
initScripts();
ScrollTrigger.refresh(); // IMPORTANT!
}
},
{ // Optional
name: 'to-home',
from: {
},
to: {
namespace: ['first-page']
},
once(data) {
// do something once on the initial page load
initSmoothScroll(data.next.container);
initScripts();
},
}]
})
完整代码在这里:
const intro = document.querySelector('.loading__container');
const word = document.querySelector('.word');
const content = document.querySelector('.content');
let locoScroll;
// On Load Animation
window.addEventListener('load', () => {
word.classList.add('loading--active');
gsap.set("html", {
cursor: "wait"
});
setTimeout(() => {
gsap.set("html", {
cursor: "auto"
}, "=-0.6");
intro.classList.add('loading--inactive');
word.classList.remove('loading--active');
}, 1500)
// Remove right after load
setTimeout(() => {
intro.remove();
}, 2000)
});
function initSmoothScroll(container) {
// Scrolling Animation
locoScroll = new LocomotiveScroll({
el: container.querySelector('[data-scroll-container]'),
smooth: true,
multiplier: 1,
smoothMobile: true,
});
// each time Locomotive Scroll updates, tell ScrollTrigger to update too (sync positioning)
locoScroll.on("scroll", ScrollTrigger.update);
// tell ScrollTrigger to use these proxy methods for the ".smooth-scroll" element since Locomotive Scroll is hijacking things
ScrollTrigger.scrollerProxy("[data-scroll-container]", {
scrollTop(value) {
return arguments.length ? locoScroll.scrollTo(value, { duration: 0, disableLerp: true }) : locoScroll.scroll.instance.scroll.y;
}, // we don't have to define a scrollLeft because we're only scrolling vertically.
getBoundingClientRect() {
return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight };
},
// LocomotiveScroll handles things completely differently on mobile devices - it doesn't even transform the container at all! So to get the correct behavior and avoid jitters, we should pin things with position: fixed on mobile. We sense it by checking to see if there's a transform applied to the container (the LocomotiveScroll-controlled element).
pinType: container.querySelector("[data-scroll-container]").style.transform ? "transform" : "fixed"
});
// each time the window updates, we should refresh ScrollTrigger and then update LocomotiveScroll.
ScrollTrigger.addEventListener("refresh", () => locoScroll.update());
ScrollTrigger.defaults({ scroller: "[data-scroll-container]" });
// each time the window updates, we should refresh ScrollTrigger and then update LocomotiveScroll.
ScrollTrigger.addEventListener('refresh', () => locoScroll.update());
// after everything is set up, refresh() ScrollTrigger and update LocomotiveScroll because padding may have been added for pinning, etc.
ScrollTrigger.refresh();
}
function initHomeAnimations() {
if (document.body.id === 'first-page') {
//Page 2
const tlH = gsap.timeline({
scrollTrigger: {
trigger: '.background',
// markers: { startColor: 'blue', endColor: 'blue' },
scrub: true,
start: '-40%',
end: '40%',
},
});
tlH.fromTo('.highlight', { color: 'rgba(255, 255, 255, 0.4)' }, { color: 'rgba(255, 255, 255, 1)', stagger: 1 });
const tlHRemove = gsap.timeline({
scrollTrigger: {
trigger: '.background',
// markers: { startColor: 'pink', endColor: 'pink' },
scrub: true,
start: '-20%',
end: '60%',
},
});
tlHRemove.to('.highlight', { color: 'rgba(255, 255, 255, 0.4)', stagger: 1 });
// Work Experience Fade Text
const tlFade = gsap.timeline({
scrollTrigger: {
trigger: '.work',
toggleActions: 'play none none reset',
scrub: true,
start: '60%',
end: '120%',
// markers: true,
},
});
/**
* Allow pinning animation only for Desktop/Ipad users
* Fade In for Desktop Accordingly
*/
ScrollTrigger.matchMedia({
"(min-width: 820px)": function () {
const pinSecond = gsap.timeline({
scrollTrigger: {
trigger: '.background',
pin: true,
start: '0%',
end: '100%',
}
});
tlFade.fromTo('.work__description', { opacity: 0, y: 50 }, { opacity: 1, y: 0, duration: 1.2 });
tlFade.fromTo('.work-btn', { opacity: 0, y: 50 }, { opacity: 1, y: 0, duration: 1.2 });
},
// Reset fade for mobile
"(max-width: 540px)": function () {
gsap.set('.work__description', { opacity: 1, y: 0, duration: 1 });
},
})
}
}
function initButtonsAnimations() {
/**
* BtnFill
* If button is hover do the animation else reset
*/
const btnClick = document.querySelectorAll('.btn-click');
btnClick.forEach(e => {
const btnFill = e.querySelector('.btn-fill');
gsap.to(btnFill, { y: '-76%', ease: Power2.easeInOut });
e.addEventListener('mouseenter', function () {
gsap.to(btnFill, .5, { startAt: { y: '76%' }, y: '0%', ease: Power2.easeInOut });
});
e.addEventListener('mouseleave', function () {
gsap.to(btnFill, .5, { y: '-76%', ease: Power2.easeInOut });
})
})
}
function initNavAnimations() {
// Nav
const tlIntro = gsap.timeline({
scrollTrigger: {
trigger: '.intro',
start: '20%',
toggleActions: 'play none none reverse',
pin: true,
pinSpacing: false,
// markers: true
},
});
tlIntro.fromTo('nav', { opacity: 1 }, { opacity: 0, duration: .60 });
const tlPopUpNav = gsap.timeline({
scrollTrigger: {
trigger: '.btn-hamburger',
start: '0%',
toggleActions: 'play none none reverse',
// markers: true
},
});
tlPopUpNav.fromTo('.btn-hamburger', { scale: '0' }, { scale: '1' });
/**
* Animated nav lines when clicked
* Initially hide the nav, if clicked move it xPercent: 1 (active) and reduce with to standard look
* Make sure to move it right -90% to hide it.
*
* Otherwise, put it back to normal to normal width and hiding the rounded div as far possible
*/
const burger = document.querySelector('.btn-hamburger');
const fixedNav = document.querySelector('.fixed-nav');
const clickables = document.querySelectorAll('.clickable');
burger.addEventListener('click', navToggle);
gsap.set('.fixed-nav', { xPercent: 140 }); // hide
function navToggle(e) {
if (!fixedNav.classList.contains('nav-active')) {
fixedNav.classList.add('nav-active');
gsap.to('.header__nav__line1', 0.5, { rotate: '45', y: 0 });
gsap.to('.header__nav__line2', 0.5, { rotate: '-45', y: -5 });
gsap.to('.fixed-nav', { xPercent: -0 });
gsap.to('.rounded-div', { width: '3vw', right: '-90%' }, '<'); // most left
} else {
removeNav();
}
// remove if clicked on a nav btn
clickables.forEach((clickable) => {
clickable.addEventListener('click', removeNav);
})
function removeNav() {
fixedNav.classList.remove('nav-active');
gsap.to('.header__nav__line1', 0.5, { rotate: '0', y: 0 });
gsap.to('.header__nav__line2', 0.5, { rotate: '0', y: 0 });
gsap.to('.fixed-nav', { xPercent: 150 }); // hide
// Fix rounded div for mobile
if (window.innerWidth > 540)
gsap.to('.rounded-div', { width: '775%', right: '-390%', xPercent: 10 }, '<');
else
gsap.to('.rounded-div', { width: '775%', right: '-500%', xPercent: 10 }, '<');
}
}
}
function initMagneticButtons() {
const magnets = document.querySelectorAll('.magnetic');
// START : If screen is bigger as 540 px do magnetic
if (window.innerWidth > 540) {
// Reset the mouse if hover off otherwise play the animation
magnets.forEach((magnet) => {
magnet.addEventListener('mousemove', moveMagnet);
magnet.addEventListener('mouseleave', function (event) {
gsap.to(event.currentTarget, 1.5, {
x: 0,
y: 0,
ease: Elastic.easeOut
});
gsap.to(".btn-text", 1.5, {
x: 0,
y: 0,
ease: Elastic.easeOut
});
});
});
// Mouse move
function moveMagnet(event) {
var magnetButton = event.currentTarget;
var bounding = magnetButton.getBoundingClientRect();
const magnetsStrength = 80;
const magnetStrengthText = 60;
gsap.to(magnetButton, {
x: (((event.clientX - bounding.left) / magnetButton.offsetWidth) - 0.5) * magnetsStrength,
y: (((event.clientY - bounding.top) / magnetButton.offsetHeight) - 0.5) * magnetsStrength,
rotate: "0.001deg",
ease: Power4.easeOut
});
}
}
}
function initWorkAnimations() {
if (document.body.id === 'first-page') {
const container = document.querySelector('.scrollx');
const sections = gsap.utils.toArray('.scrollx section');
const texts = gsap.utils.toArray('anim');
const mask = document.querySelector('.mask');
// Preference
const nav = document.querySelector('.nav');
nav.classList.add('absolute-nav');
let scrollTween = gsap.to(sections, {
xPercent: -100 * (sections.length - 1),
ease: 'none',
scrollTrigger: {
trigger: '.scrollx',
pin: true,
scrub: 1,
end: '+=3000',
markers: true,
}
})
gsap.to(mask, {
width: '100%',
scrollTrigger: {
trigger: '.wrapper',
start: 'top left',
scrub: 1
}
});
}
}
// Main Scripts
function initScripts() {
initNavAnimations();
initMagneticButtons();
initButtonsAnimations();
initHomeAnimations();
}
// NOTE: data.next = current container
barba.init({
sync: true,
timeout: 7000,
debug: true, // !IMPORTANT
views: [{
namespace: 'work-page',
afterEnter() {
initWorkAnimations();
ScrollTrigger.refresh();
console.log('WORRRRRRK PAFGE ENTER');
},
}],
transitions: [{
name: 'default',
async once(data) {
// Once page loads
initSmoothScroll(data.next.container);
initScripts();
},
async leave(data) {
pageTransitionIn(data, this)
await delay(1200)
data.current.container.remove();
},
async enter(data) {
pageTransitionOut(data, this);
},
async beforeEnter(data) {
ScrollTrigger.getAll().forEach((x) => x.kill());
console.log('destroying everything');
locoScroll.destroy(); // Optional!
initSmoothScroll(data.next.container);
initScripts();
ScrollTrigger.refresh(); // IMPORTANT!
}
},
{ // Optional
name: 'to-home',
from: {
},
to: {
namespace: ['first-page']
},
once(data) {
// do something once on the initial page load
initSmoothScroll(data.next.container);
initScripts();
},
}]
})
function delay(n) {
n = n || 2000;
return new Promise((done) => {
setTimeout(() => {
done();
}, n);
});
}
// Animation - Page transition In
function pageTransitionIn(data, curr) {
let done = curr.async();
const tl = gsap.timeline({ default: { ease: 'power2.inOut' } });
tl.fromTo('.main-wrap', 1, { opacity: 1 }, { opacity: 0 });
tl.fromTo('.btn-hamburger', { opacity: 1 }, { opacity: 0 }, '>');
tl.fromTo('.swipe', 0.75, { x: '-100%' }, { x: '0%', onComplete: done }, '-=0.5',);
}
function pageTransitionOut(data, curr) {
let done = curr.async();
const tl = gsap.timeline({ default: { ease: 'power2.inOut' } });
tl.fromTo('.swipe', 1, { x: '0' }, { x: '100%', stagger: 0.25, onComplete: done });
tl.fromTo(data.next.container, 0.75, { opacity: 0 }, { opacity: 1 });
}