react-animatable
react-animatable copied to clipboard
Tiny(~1kB) animation hooks for React, built on Web Animations API.
react-animatable
A small but powerful animation library for React, built on Web Animations API.

Features
- Performant animation driven by native Web Animations API (WAAPI), but with minimal stress integrating it to React.
- HTML, SVG, Canvas and other things can be animated.
- TypeScript centric design for modern web application development.
- Composable and declarative APIs based on React hooks.
- Tiny bundle size (currently about 2kB gzipped) and has zero dependencies. Of course treeshakeable
Demo
https://inokawa.github.io/react-animatable/
Install
npm install react-animatable
Requirements
- react >= 16.14
And in some legacy browsers that does not support Web Animations API, you may need to use polyfill.
Usage
The hooks accepts canonical keyframe format objects and KeyframeEffect's options as arguments, so check them before using this library.
import { useEffect } from "react";
import { useAnimation } from "react-animatable";
export const App = () => {
// Define your animation in WAAPI way
const animate = useAnimation(
[
{ fill: "red", fontSize: "24px" },
{ fill: "green", fontSize: "36px" },
],
{
duration: 800,
easing: "ease-in-out",
iterations: Infinity,
direction: "alternate",
}
);
useEffect(() => {
// And play it!
animate.play();
}, []);
return (
<svg
width={600}
height={400}
viewBox="0 0 600 400"
onClick={
// The return value of useAnimation and its methods are memoized
animate.pause
}
>
<g transform="translate(50, 50)">
<text
ref={
// You have to pass ref to element you want to control
animate.ref
}
>
Hello world
</text>
</g>
</svg>
);
};
API
useAnimation
A basic hook to use Web Animations API.
Examples
useAnimationController
A hook to compose multiple useAnimation and orchestrate their animations.
Examples
useAnimationFunction
Same as useAnimation, but it drives function not React element.
Examples
useTransitionAnimation
A hook to compose multiple useAnimation and plays them when element enter/update/exits. This hook must be used under AnimationGroup component.
Examples
AnimationGroup
A component to provide some behavior to its children. Currently it only detects enter/update/exit of children by key, that works similar to TransitionGroup of react-transition-group.
Use polyfill
- browsers that have KeyframeEffect
- browsers that have Element.animate()
- browsers that have no Web Animations APIs
In 1, you can use all functions of this library without polyfill. Some of the newer features like composite mode and CSS Motion Path may be ignored in some browsers though.
In 2, you can use this library but useAnimationFuction
would not work.
In 3, you have to setup Web Animations API polyfill to use this library.
Setup web-animations-js
npm install web-animations-js
// You can polyfill always
import "web-animations-js";
ReactDOM.render(<App />);
// or polyfill only if browser does not support Web Animations API
(async () => {
if (!("animate" in document.body)) {
await import("web-animations-js");
}
ReactDOM.render(<App />);
})();
Partial keyframes are not supported
error was thrown
web-animations-js does not support partial keyframes, so you have to write animation definitions like below.
https://github.com/PolymerElements/paper-ripple/issues/28#issuecomment-266945027
// valid
const animate = useAnimation(
[
{ transform: "translate3d(0px, 0, 0)" },
{ transform: "translate3d(400px, 0, 0)" },
],
{ duration: 800, easing: "ease-in-out" }
);
// invalid
const animate = useAnimation(
{ transform: "translate3d(400px, 0, 0)" },
{ duration: 800, easing: "ease-in-out" }
);
// valid
const animate = useAnimation(
[
{ transform: "translateX(0px)", fill: "blue" },
{ transform: "translateX(100px)", fill: "red" },
{ transform: "translateX(0px)", fill: "blue" },
],
{ duration: 800, easing: "ease-in-out" }
);
// invalid
const animate = useAnimation(
[
{ transform: "translateX(0px)" },
{ transform: "translateX(100px)", fill: "red" },
{ fill: "blue" },
],
{ duration: 800, easing: "ease-in-out" }
);
Contribute
All contributions are welcome. If you find a problem, feel free to create an issue or a PR.
Making a Pull Request
- Clone this repo.
- Run
npm install
. - Commit your fix.
- Make a PR and confirm all the CI checks passed.