Refreshing page GSAP animations not working using BarbaJS

380 Views Asked by At

When I enter the main page (index.html) and navigate to the work page everything works as expected. But once I refresh the page in the workpage and not the initial page everything stops working -- what could be the reason for this?

I've tried refreshing animations in the barbajs code and it seems that it doesn't work even with the usage of Barba views to reinitialize the animations explicitly.

YOUTUBE VIDEO: 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();
        },
    }]
})

The full code is here:

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 });
}
0

There are 0 best solutions below