A hook to effortlessly run requestAnimationFrame()
in React (demo):
import useAnimationFrame from 'use-animation-frame';
const Counter = () => {
const [time, setTime] = useState(0);
useAnimationFrame(e => setTime(e.time));
return <div>Running for:<br/>{time.toFixed(1)}s</div>;
};
Inspired by CSS-Tricks' Using requestAnimationFrame with React Hooks and my twitter reply.
Accepts a function that will be called on each requestAnimationFrame step. If there's a re-render and a new function is created, it'll use that instead of the previous one:
useAnimationFrame(callback);
The callback receives a single parameter, which is an object with two properties (based on the performance.now()
API):
time
: the absolute time since the hook was first mounted. This is useful for wall clock, general time, etc.delta
: the time since the hook was run last. This is useful to measure e.g. FPS.
All times are in the International System of Units seconds, including decimals.
With my other library use-interpolation it's easy to calculate the FPS (see in CodeSandbox):
import React, { useState } from "react";
import useInterpolation from 'use-interpolation';
import useAnimationFrame from 'use-animation-frame';
const Counter = () => {
const [time, setTime] = useState(0);
// 1s of interpolation time
const [fps, setFps] = useInterpolation(1000);
useAnimationFrame(e => {
setFps(1 / e.delta);
setTime(e.time);
});
return (
<div>
{time.toFixed(1)}s
<br />
{fps && Math.floor(fps.value)} FPS
</div>
);
};