Search code examples
reactjsframer-motion

How to skip the delay of an animation in framer-motion mid-way?


I am showing a div on the page start and then turn off it’s opacity and remove it after 20 seconds. But I want to turn the opacity off immediately when the user is scrolling (I mean still play the smooth animation but don’t wait for the delay of 20 seconds)

import "./styles.css";
import { motion } from "framer-motion";
import { useEffect } from "react";

export default function App() {
  useEffect(() => {
    document.addEventListener("scroll", () => {
      // skip the transition delay of the animation and start it immediately here
    });
  });

  return (
    <>
      <motion.div
        id="start"
        style={{
          background: "blue",
          position: "fixed",
          top: 0,
          left: 0,
          width: "100%",
          height: "100%"
        }}
        onAnimationComplete={() => {
          const node = document.querySelector("#start") as any;
          if (!node) return;
          node.style.display = "none";
        }}
        initial={{ opacity: 1 }}
        animate={{ opacity: 0 }}
        transition={{ delay: 20, duration: 2 }}
      />
      <p>
        distinctio vitae voluptatibus ipsa veritatis sequi laborum quasi
        explicabo! Vero, accusamus libero, assumenda animi porro dolorum
        reprehenderit totam laboriosam harum mollitia nihil. Dolores,
        laudantium? Nisi amet voluptatum officia enim error atque consequuntur
        nobis similique quibusdam numquam illum nesciunt laborum a maxime quidem
        qui vitae rerum cum, incidunt voluptatem modi? Quam sit vitae autem
        temporibus voluptates voluptatum. Perspiciatis expedita voluptatibus
        laborum, iusto alias recusandae odit omnis. Earum, maxime fugit.
        Deleniti cupiditate obcaecati vero libero atque error modi tempore
        maxime consequuntur quod exercitationem, possimus ad omnis quas autem
        culpa ut ratione asperiores? Explicabo blanditiis debitis dolor. Quia
        architecto quam enim dolores laudantium impedit odio provident
        voluptatum quaerat. Repellendus labore, voluptates placeat nobis dicta
        optio quia in dolores porro, deserunt officiis, magnam culpa totam ea
        est autem veritatis minus quaerat. Quisquam, omnis consectetur porro,
        vitae deleniti enim pariatur, sed voluptatem fugiat libero illo.
        Veritatis autem laudantium, a neque officia consectetur optio alias
        repudiandae ea quia pariatur saepe tenetur ab dolorum reiciendis rerum
        qui iste quisquam delectus accusantium corrupti obcaecati maxime non
        sunt. Non dolores illum beatae minus quisquam, a tempore facere
        voluptatum aspernatur optio veritatis delectus fuga! Alias aliquid,
        nostrum atque explicabo, eum, modi culpa iusto minus ad omnis sint quod
        corrupti? Dolorem officia, id aliquam, accusantium tempore dolorum nisi
        deleniti ea dignissimos consequuntur voluptatem quas nihil quod facere,
        excepturi quam hic. Repellat quas provident aliquam perspiciatis
        temporibus voluptates quaerat? Repellendus blanditiis nobis delectus
        fugit vero voluptas placeat quidem accusantium quam. Ipsa corrupti
        laborum magni reprehenderit dolore nisi autem sint quisquam quia quidem.
        Vero quod consequatur perspiciatis esse mollitia consequuntur nobis, sit
        dolores, placeat nostrum unde deserunt obcaecati officiis modi ab
        provident quaerat assumenda eaque aliquid voluptates ducimus
        dignissimos, incidunt dolorum nam. Deleniti cumque est eaque maiores
        molestias voluptatibus totam libero praesentium a magnam, perferendis
        iste distinctio blanditiis veniam nobis nisi molestiae, sapiente
        inventore soluta magni ex! Assumenda autem error voluptatem tempora!
        Suscipit, quia repellat tenetur autem molestiae cum, mollitia fuga
        labore facere aut, amet nam quisquam quod magni itaque aliquid eaque
        vitae saepe quae soluta veniam. Eum voluptatem enim cum, qui maiores,
        sed quibusdam atque dolorem soluta recusandae obcaecati nostrum
        laboriosam impedit. Quia porro voluptates ex amet obcaecati a hic rerum,
        similique quisquam voluptate nemo at. Incidunt tempore ad laborum nihil
        sapiente! Maiores sit consequuntur eos dolor! Nulla porro vel hic et
        mollitia quis vero, temporibus est cum, ratione modi molestiae
        laboriosam eum dignissimos suscipit. Inventore facere voluptate earum
        obcaecati quos atque hic similique voluptates veritatis, at debitis
        ullam maxime praesentium nesciunt quasi magni blanditiis maiores veniam
        tempore nemo iusto? Tempore, at voluptatem. Voluptatem facilis ratione
        fuga non iusto, consequatur autem temporibus facere reiciendis provident
        deserunt accusantium doloribus culpa neque. Corrupti, expedita! Autem
        obcaecati incidunt necessitatibus iste deserunt in adipisci molestiae
        suscipit, voluptas soluta vitae? Earum, consequatur nam odio quo
        pariatur obcaecati vel adipisci deserunt facere culpa fugiat ipsum nisi
        saepe repudiandae possimus, quisquam illo in suscipit. Distinctio harum
        repudiandae dolorem animi repellendus quo vitae accusantium saepe illum
        omnis, reprehenderit perspiciatis quod iusto totam. Id voluptatem,
        tenetur ducimus recusandae nesciunt dolorum ad cum reiciendis, suscipit
        dolores mollitia et illo?
      </p>
    </>
  );
}

Sandbox: https://codesandbox.io/s/framer-motion-enter-animation-forked-7j3zpl?file=/src/App.tsx:0-5194

What is the best way to achieve it?

Thank you!


Solution

  • Explanation

    • Using useAnimationControls you can stop and start animations.
    • Used this with your on scroll event to stop the delayed animation and start a new animation without the delay.
    • After the scroll listener is called the first time the listener is removed to prevent restarting the animation. Done using removeEventListener
    • A timer is set up on first render that will cancel the scroll handler after 20s (the animation delay). This will mean that once the delayed animation starts it won't be "overwriten"

    Solution

    • If you replace the below App.tsx code into your codesandbox you provided you should get the desired result.

    App.tsx:

    import "./styles.css";
    import { motion, useAnimationControls  } from "framer-motion";
    import { useEffect, useCallback } from "react";
    
    export default function App() {
    
      const controls = useAnimationControls()
    
      const animationScrollHandler = useCallback( () => {
        // Stop the delayed animation
        controls.stop();
        // Start new animation  
        controls.start(() => ({ opacity: 0, transition:{ duration: 2} })) 
        // Remove scroll listener
        document.removeEventListener("scroll",animationScrollHandler) 
      },[controls])
    
    
      useEffect(() => {
        // Start delayed animation on first render
        controls.start(() => ({  opacity: 0, transition:{delay: 20, duration: 2} }))   
        document.addEventListener("scroll", animationScrollHandler);
        //Timer to cancel scroll listener if delayed animation started
        setTimeout(() => document.removeEventListener("scroll",animationScrollHandler), 20000);
      },[controls, animationScrollHandler]);
    
      return (
            
          <div onScroll={animationScrollHandler}>
          <motion.div
            id="start"
            style={{
              background: "blue",
              position: "fixed",
              top: 0,
              left: 0,
              width: "100%",
              height: "100%"
            }}
            onAnimationComplete={() => {
              const node = document.querySelector("#start") as any;
              if (!node) return;
              node.style.display = "none";
            }}
            animate={controls}
          />
          <p>
            distinctio vitae voluptatibus ipsa veritatis sequi laborum quasi
            explicabo! Vero, accusamus libero, assumenda animi porro dolorum
            reprehenderit totam laboriosam harum mollitia nihil. Dolores,
            laudantium? Nisi amet voluptatum officia enim error atque consequuntur
            nobis similique quibusdam numquam illum nesciunt laborum a maxime quidem
            qui vitae rerum cum, incidunt voluptatem modi? Quam sit vitae autem
            temporibus voluptates voluptatum. Perspiciatis expedita voluptatibus
            laborum, iusto alias recusandae odit omnis. Earum, maxime fugit.
            Deleniti cupiditate obcaecati vero libero atque error modi tempore
            maxime consequuntur quod exercitationem, possimus ad omnis quas autem
            culpa ut ratione asperiores? Explicabo blanditiis debitis dolor. Quia
            architecto quam enim dolores laudantium impedit odio provident
            voluptatum quaerat. Repellendus labore, voluptates placeat nobis dicta
            optio quia in dolores porro, deserunt officiis, magnam culpa totam ea
            est autem veritatis minus quaerat. Quisquam, omnis consectetur porro,
            vitae deleniti enim pariatur, sed voluptatem fugiat libero illo.
            Veritatis autem laudantium, a neque officia consectetur optio alias
            repudiandae ea quia pariatur saepe tenetur ab dolorum reiciendis rerum
            qui iste quisquam delectus accusantium corrupti obcaecati maxime non
            sunt. Non dolores illum beatae minus quisquam, a tempore facere
            voluptatum aspernatur optio veritatis delectus fuga! Alias aliquid,
            nostrum atque explicabo, eum, modi culpa iusto minus ad omnis sint quod
            corrupti? Dolorem officia, id aliquam, accusantium tempore dolorum nisi
            deleniti ea dignissimos consequuntur voluptatem quas nihil quod facere,
            excepturi quam hic. Repellat quas provident aliquam perspiciatis
            temporibus voluptates quaerat? Repellendus blanditiis nobis delectus
            fugit vero voluptas placeat quidem accusantium quam. Ipsa corrupti
            laborum magni reprehenderit dolore nisi autem sint quisquam quia quidem.
            Vero quod consequatur perspiciatis esse mollitia consequuntur nobis, sit
            dolores, placeat nostrum unde deserunt obcaecati officiis modi ab
            provident quaerat assumenda eaque aliquid voluptates ducimus
            dignissimos, incidunt dolorum nam. Deleniti cumque est eaque maiores
            molestias voluptatibus totam libero praesentium a magnam, perferendis
            iste distinctio blanditiis veniam nobis nisi molestiae, sapiente
            inventore soluta magni ex! Assumenda autem error voluptatem tempora!
            Suscipit, quia repellat tenetur autem molestiae cum, mollitia fuga
            labore facere aut, amet nam quisquam quod magni itaque aliquid eaque
            vitae saepe quae soluta veniam. Eum voluptatem enim cum, qui maiores,
            sed quibusdam atque dolorem soluta recusandae obcaecati nostrum
            laboriosam impedit. Quia porro voluptates ex amet obcaecati a hic rerum,
            similique quisquam voluptate nemo at. Incidunt tempore ad laborum nihil
            sapiente! Maiores sit consequuntur eos dolor! Nulla porro vel hic et
            mollitia quis vero, temporibus est cum, ratione modi molestiae
            laboriosam eum dignissimos suscipit. Inventore facere voluptate earum
            obcaecati quos atque hic similique voluptates veritatis, at debitis
            ullam maxime praesentium nesciunt quasi magni blanditiis maiores veniam
            tempore nemo iusto? Tempore, at voluptatem. Voluptatem facilis ratione
            fuga non iusto, consequatur autem temporibus facere reiciendis provident
            deserunt accusantium doloribus culpa neque. Corrupti, expedita! Autem
            obcaecati incidunt necessitatibus iste deserunt in adipisci molestiae
            suscipit, voluptas soluta vitae? Earum, consequatur nam odio quo
            pariatur obcaecati vel adipisci deserunt facere culpa fugiat ipsum nisi
            saepe repudiandae possimus, quisquam illo in suscipit. Distinctio harum
            repudiandae dolorem animi repellendus quo vitae accusantium saepe illum
            omnis, reprehenderit perspiciatis quod iusto totam. Id voluptatem,
            tenetur ducimus recusandae nesciunt dolorum ad cum reiciendis, suscipit
            dolores mollitia et illo?
          </p>
        </div>
      );
    }