I'm trying to make a [n sec] countdown using Framer Motion in a React Application, but when I try to change the text displaying on the screen after the [n sec], the countdown gets to the 0 seconds before the text change happens.
Here's the code that makes that change:
const [status, setStatus] = useState("Waiting...");
const count = useMotionValue(5);
const time = useTransform(count, Math.round);
useEffect(() => {
const animation = animate(count, 0, { duration: 5 });
setTimeout(() => {
setStatus("Finished!");
}, 5 * 1000);
return animation.stop;
}, []);
The GitHub repository to reproduce this is linked here: https://github.com/jpfragoso30/jp-framer-sandbox/tree/main
I've tried using the onUpdate method for animate to check if it's a problem of being async
const animation = animate(count, 0, { duration: 5, onUpdate: (value) => { if (value === 0) setStatus("Finished!"); }, });
And the .then for when the animation ends
const animation = animate(count, 0, { duration: 5, }).then(() => setStatus("Finished!"));;
In all of these attempts I'm just getting the same result, the "Finished!" text has a delay, and I don't think the animation is counting naturally if that makes sense.
Firstly, the method to transform your count value has to be ceiling to start counting at 0, at only go to 0 when you have an absolute zero
const time = useTransform(count, Math.ceil);
and also, to make the time go "natural", you must declare a "linear" movement
const animation = animate(count, 0, {
duration: 5,
ease: "linear",
}).then(() => setStatus("Finished!"));