Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
alonK

Problem with Trigger position on a long page with a repeating function for animation

Recommended Posts

I have a long page with multiple scroll based simple animations, some of them use the same class name to run different places.

At some point it seems the trigger position gets off for all the page and animations at the bottom of the screen are happening in the wrong place,

 

If I open console in the browser the animations are back at the correct position.

 

 

(function () {

    gsap.registerPlugin(ScrollTrigger);
    gsap.defaults({ease: "power4.out"});

    ScrollTrigger.matchMedia({
        // desktop
        "(min-width: 800px)": function () {
            mySplitText = new SplitText(".corona-hero-section h2", {type: "words,chars"});
            chars = mySplitText.chars; //an array of all the divs that wrap each character
            gsap.set(".corona-hero-section h2", {perspective: 400});
            var tl = gsap.timeline();
            tl
                .from(".logo", {duration: 2, autoAlpha: 0, y: -60, stagger: 0.3}, 1)
                .from(chars, {
                    duration: 0.8,
                    opacity: 0,
                    scale: 0,
                    y: 80,
                    rotationX: 180,
                    transformOrigin: "0% 50% -50",
                    ease: "back",
                    stagger: 0.01
                }, "+=0");

            tl.restart();

            scheneChange(5, 140, '.viewer', '.scene', false, 'bottom bottom');
            scheneChange(4, 138, '.viewer2', '.scene2', false, 'bottom bottom');
            scheneChange(1, 122, '.viewer4', '.scene4', false, 'bottom bottom');
            scheneChange(3, 146, '.viewer5', '.scene5', false, 'bottom bottom');
            scheneChange(2, 139, '.viewer6', '.scene6', false, 'bottom bottom');
            animateImageReveal();

            animateStaggerIcons('.icon-list', '.icon-list__item');
            animateStaggerIcons('.icon-num', '.icon-num__item');
            animateStaggerIcons('.icon-top', '.icon-top__item');

            aminateStaggerLi('.map-wrap__item');
            aminateStaggerLi('.program-list-wrap li');
        },

        // mobile
        "(max-width: 799px)": function () {
// Icons and text animation
            gsap.utils.toArray('.icon-list__item').forEach((section) => {
                const tls = gsap.timeline({
                    scrollTrigger: {
                        trigger: section,
                        scrub: true,
                        start: "top center",
                        // markers: true,
                        end: "+=20%",
                    },
                });

                const delay = 0.5;

                const textIcon = section.querySelectorAll(".icon-list__icon");
                const textTitle = section.querySelectorAll(".icon-list__title");
                const textText = section.querySelector(".icon-list__text");
                const textNum = section.querySelector(".icon-list__num");

                tls
                    .from(textNum, {duration: 3, autoAlpha: 0, y: -60, stagger: delay}, 0)
                    .from(textIcon, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.3)
                    .from(textTitle, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.6)
                    .from(textText, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.9)
            });
            scheneChange(5, 140, '.viewer', '.scene');
            scheneChange(4, 138, '.viewer2', '.scene2');
            scheneChange(1, 122, '.viewer4', '.scene4', false);
            scheneChange(3, 146, '.viewer5', '.scene5');
            scheneChange(2, 139, '.viewer6', '.scene6', false);
            scheneImageReveal();
            animateIconNum();

            scheneChange(1, 163.5, '.viewer3', '.scene3');
        },
        "all": function () {
            animateTitleSection();
            morphImg('.scene3');
        }
    });

    function scheneChange(frames, offset, classToAnimate, action, pin = true, start = "center center") {
        var frame_count = frames,
            offset_value = offset;
        gsap.to(classToAnimate, {
            backgroundPosition: (-offset_value * frame_count * 2) + "px 50%",
            ease: "steps(" + frame_count + ")", // use a stepped ease for the sprite sheet
            scrollTrigger: {
                trigger: action,
                start: start,
                end: "+=" + (frame_count * offset_value),
                pin: pin,
                // markers: true,
                scrub: true,
            }
        });
    }

    function morphImg(trigger) {
        const tls3 = gsap.timeline({
            scrollTrigger: {
                trigger: trigger,
                scrub: true,
                start: "top center",
                // markers: true,
                end: "+=40%",
            },
        });

        tls3
            .to('#inIsrael', {duration: 2, fill: "#9191a0", morphSVG: "#inMaoz"}, 0)
            .to('#israelText', {duration: 2, morphSVG: "#maozText"}, 0)
            .to('#israelUnderText', {duration: 2, morphSVG: "#maozUnderText"}, 0.2)
    }

    function animateIconNum() {
        const sections = gsap.utils.toArray('.icon-num__item');
        sections.forEach((section) => {
            const tls = gsap.timeline({
                scrollTrigger: {
                    trigger: section,
                    scrub: true,
                    start: "top center",
                    // markers: true,
                    end: "+=20%",
                },
            });

            const delay = 0.5;

            const textIcon = section.querySelectorAll(".icon-num__icon");
            const textTitle = section.querySelectorAll(".icon-num__title");
            const textText = section.querySelector(".icon-num__text");
            // const textNum = section.querySelector(".icon-list__num");

            tls
                .from(textText, {duration: 3, autoAlpha: 0, y: -60, stagger: delay}, 0)
                .from(textIcon, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.3)
                .from(textTitle, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.6)
            // .from(textText, {duration: 1, autoAlpha: 0, y: -60, stagger: delay}, 0.9)

        });
    }

    function animateTitleSection() {
        const sections = gsap.utils.toArray(".corona-header");
        sections.forEach((section) => {
            const splitTimeline = gsap.timeline({
                scrollTrigger: {
                    trigger: section,
                    scrub: true,
                    end: "+=70%",
                    // onToggle: self => gsap.to(".split-text", {opacity: self.isActive ? 1 : 0}),
                    toggleActions: "restart pause restart none",
                    //markers: true
                }
            });

            const split = new SplitText(section);
            splitTimeline
                .to(section, {duration: 1, backgroundColor: '#fff', ease: "none"}, 0)
                .to(section, {duration: 1, backgroundColor: '#222241', ease: "none"}, 1)
                .from(split.chars, {
                    duration: 2,
                    opacity: 0,
                    x: "random(-500, 500)",
                    y: "random(-500, 500)",
                    z: "random(-500, 500)",
                    scale: .1,
                    yoyo: true,
                    stagger: 0.02
                });
        });

    }

    function animateImageReveal() {
        let revealContainers = gsap.utils.toArray(".reveal");
        revealContainers.forEach((container) => {
            let tlImage = gsap.timeline({
                scrollTrigger: {
                    trigger: container,
                    scrub: true,
                    start: "top 100%",
                    end: "bottom 70%",
                }
            });
            tlImage.from(container, {duration: 0.3, autoAlpha: 0, y: -60, stagger: 0.3}, 1);
        });
    }

    function scheneImageReveal() {

        let revealContainers = gsap.utils.toArray(".reveal");
        revealContainers.forEach((container) => {
            let image = container.querySelector('img');
            let tlImage = gsap.timeline({
                scrollTrigger: {
                    trigger: container,
                    start: "20% 70%",
                    toggleActions: "restart none none reset",
                }
            });

            tlImage.set(container, {autoAlpha: 1});
            tlImage.from(container, 1.5, {
                xPercent: -100,
                ease: Power2.out
            });
            tlImage.from(image, 1.5, {
                xPercent: 100,
                // scale: 0.7,
                delay: -1.5,
                ease: Power2.out
            });
        });
    }

    function aminateStaggerLi(trigger) {
        gsap.set(trigger, {y: 100});
        ScrollTrigger.batch(trigger, {
            onEnter: batch => gsap.to(batch, {opacity: 1, y: 0, stagger: {each: 0.15, grid: [1, 3]}, overwrite: true}),
            onLeave: batch => gsap.set(batch, {opacity: 0, y: -100, overwrite: true}),
            onEnterBack: batch => gsap.to(batch, {opacity: 1, y: 0, stagger: 0.15, overwrite: true}),
            onLeaveBack: batch => gsap.set(batch, {opacity: 0, y: 100, overwrite: true})

        });

        ScrollTrigger.addEventListener("refreshInit", () => gsap.set(trigger, {y: 0}));

    }

    function animateStaggerIcons(list, listItem) {
        gsap.utils.toArray(list).forEach(section => {
            const elems = section.querySelectorAll(listItem);

            // Set things up
            gsap.set(elems, {y: 50, opacity: 0});

            ScrollTrigger.create({
                trigger: section,
                start: 'top 60%',
                onEnter: () => gsap.to(elems, {
                    y: 0,
                    opacity: 1,
                    duration: 1,
                    stagger: 0.2,
                    delay: 0.3,
                    ease: 'power3.out',
                    overwrite: 'auto'
                }),
                onLeaveBack: () => gsap.to(elems, {
                    y: 50,
                    opacity: 0,
                    duration: 1,
                    stagger: 0.2,
                    delay: 0.3,
                    ease: 'power3.out',
                    overwrite: 'auto'
                })
            });
        })
    }

})();

 

 

Link to comment
Share on other sites

 

Hey, welcome to the forum @alonK

 

6 minutes ago, alonK said:

At some point it seems the trigger position gets off for all the page and animations at the bottom of the screen are happening in the wrong place

 

It's pretty hard telling from just ( a whole lot of ) code - but it sounds and looks to me like that could be related to you pinning things at some point but your ScrollTriggers not being created in the order they appear on the page (because of creating them in loops for different classes).

 

So what you might want to take a look at is the .sort() method and/or setting refreshPriorities (which are explained on the same docs page).

 

Hope this helps - and if it doesn't, it would be awesome if you could create a minimal demo for us to have a look at - that always makes it easier to help.

 

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×