How to achieve full-page animation on scroll using Framer Motion, Complex layouts changes?

2.1k views Asked by At

I am working for an IT company, Where I need to create a product which contain scroll animation all over the pages, same layouts are changing every time, and others components are morphing everywhere to another shapes and size, currently I am using useViewPortScroll from framer motion and intersectionObserver API from pure JavaScript,

  const animate = useTransform(
    scrollYProgress,
    [0.0, 0.13, 0.2, 0.3, 0.4, 0.5],
    [1000, 0, 0, 0, -800, -1000]
  )

but the problem is when ever i add new pages in between the pages the whole things get messed up? is there any way we can map the scrollYProgress according to the pages or percentage value, that would be a lifesaver for me?

Please do suggest me a nice solution. thanks in advance.

1

There are 1 answers

0
Manish Yadav On

most of you guys might be searching answers and solutions for the problems like this, I worked around this tried different libraries and online solutions most of them didn't worked as expected, at the end of day I solved the issue using gsap3, gsap3 ScrollTrigger and ReactJS, i mapped array of pages with the viewport scroll and used small JavaScript logic to snap pages to view using scroll trigger that mostly solved all of my issues, Go with gsap at first it might seems little bit overwhelmed but i assure you the result will be more than expected.

code sample is as below....

const LandingPage = () => {
    const pannel_1 = useRef(null);
    const pannel_2 = useRef(null);
    const pannel_3 = useRef(null);


    const pages = [
        pannel_1.current,
        pannel_2.current,
        pannel_3.current,

    ];

    // page animation

    useEffect(() => {
        function goToSection(i, pannel, anim) {
            const tl = gsap.timeline();
            if (tl.isActive()) return null;
            tl.to(window, {
                scrollTo: { y: pannel, autoKill: false },
                duration: 0.7,
                ease: 'none'
            });
            if (anim) {
                anim.restart();
            }
        }

        pages.map((pannel, i) => {
            ScrollTrigger.create({
                trigger: pannel,
                onEnter: () => goToSection(i, pannel)
            });
            ScrollTrigger.create({
                trigger: pannel,
                start: 'bottom bottom',
                onEnterBack: () => goToSection(i, pannel)
            });
        });
    });

    return (
        <div className={styles.container}>
            <section ref={pannel_1} className={`${styles.pannel}`}>
                <Page pannel_1={pannel_1} />
            </section>

            <section ref={pannel_2} className={`${styles.pannel} `}>
                <Page pannel_3={pannel_3} />
            </section>

            <section ref={pannel_3} className={`${styles.pannel}`}>
                <Page pannel_3={pannel_3} />
            </section>
        </div>
    );
};

export default LandingPage;