刷新页面 GSAP 动画无法使用 BarbaJS

问题描述 投票:0回答:0

当我进入主页 (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 });
}
javascript html css gsap barbajs
© www.soinside.com 2019 - 2024. All rights reserved.