skip to Main Content

I am building a website that uses framer-motion for animation

I have this image component

 <motion.img
              ref={scope}
              initial={{ x: -200 }}
              alt="pacman"
              className="absolute z-50"
              src="/pacman.gif"
              width={100}
              height={50}
            />

and here it is running a series of animation

  const [scope, animate] = useAnimate();

  const runAnimation = async () => {
    await animate(scope.current, { x: 300 }, { duration: 2 });
    await animate(scope.current, { scaleX: -1 }, { duration: 0.2 });
    await animate(scope.current, { x: -200 }, { duration: 2 });
    await animate(scope.current, { scaleX: 1 }, { duration: 0.2 });
  };

  useEffect(() => {
    runAnimation();
  }, []);

but I don’t understand how can I restart this series inifinity times in a loop once the series got completed

2

Answers


  1.  // if your component rerendered for some reason runInterval.current will be untouched
     let runInterval = useRef<ReturnType<typeof setInterval>>();
    
     const startAnimation = () => {
        runInterval.current = setInterval(() => {
          runAnimation();
        // total duration is 4.4s=4400ms
        }, 4400);
        
      };
    

    The setInterval() function is commonly used to set a delay for
    functions that are executed again and again, such as animations. You
    can cancel the interval using clearInterval().

     useEffect(() => {
        startAnimation();
        return () => runInterval.current && clearInterval(runInterval.current);
      }, []);
    
    Login or Signup to reply.
  2. Here is the answer:

    You can call the runAnimation function recursively at the end of the animation series. This way, once all the animations are complete, it will start the animation series again.

    const runAnimation = async () => {
        await animate(scope.current, { x: 300 }, { duration: 2 });
        await animate(scope.current, { scaleX: -1 }, { duration: 0.2 });
        await animate(scope.current, { x: -200 }, { duration: 2 });
        await animate(scope.current, { scaleX: 1 }, { duration: 0.2 });
        runAnimation(); // Restart the animation series once completed
    };
    
    useEffect(() => {
        runAnimation();
    }, []);
    

    By doing this, the animation series will run indefinitely in a loop.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search