Reputation: 6267
I'm migrating an app from react-spring to framer-motion. With Spring, I can animate a number with:
export default function MyNumber({ number }) {
const spring: any = useSpring({ from: { number: 0 }, to: { number } });
return (
<animated.div>
{spring.number.interpolate((c) => c.toFixed(1))}
</animated.div>
);
}
I don't see how to do it with Framer-Motion.
Upvotes: 5
Views: 4566
Reputation: 1569
if you want to use a hook for better reusability, try this other approach:
import { useEffect, useState } from 'react';
import { animate } from 'framer-motion';
export const useAnimatedCounter = (
maxValue: number,
initialValue = 0,
duration = 1,
) => {
const [counter, setCounter] = useState<number>(initialValue);
useEffect(() => {
const controls = animate(initialValue, maxValue, {
duration,
onUpdate(value) {
setCounter(value);
}
});
return () => controls.stop();
}, [initialValue, maxValue, duration]);
return counter;
}
Upvotes: 0
Reputation: 6267
So I've found the answer:
import { animate } from "framer-motion";
import React, { useEffect, useRef } from "react";
function Counter({ from, to }) {
const ref = useRef();
useEffect(() => {
const controls = animate(from, to, {
duration: 1,
onUpdate(value) {
ref.current.textContent = value.toFixed(1);
}
});
return () => controls.stop();
}, [from, to]);
return <p ref={ref} />;
}
export default function App() {
return <Counter from={0} to={65.4} />;
}
Upvotes: 2