A small but powerful animation library for React, built on Web Animations API.
- 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
https://inokawa.github.io/react-animatable/
npm install react-animatable
- react >= 16.14
If you use ESM and webpack 5, use react >= 18 to avoid Can't resolve react/jsx-runtime
error.
And in some legacy browsers that does not support Web Animations API, you may need to use polyfill.
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"
// The return value of useAnimation and its methods are memoized
onClick={animate.pause}
>
<g transform="translate(50, 50)">
<text
// You have to pass animate to element you want to control
ref={animate}
>
Hello world
</text>
</g>
</svg>
);
};
A basic hook to use Web Animations API.
A hook to compose multiple useAnimation and orchestrate their animations.
Same as useAnimation, but it drives function not React element.
A hook to compose multiple useAnimation and plays them when element enter/update/exits. This hook must be used under AnimationGroup component.
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.
- 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.
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 />);
})();
web-animations-js does not support partial keyframes, so you have to write animation definitions like below.
PolymerElements/paper-ripple#28 (comment)
// 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" }
);
All contributions are welcome. If you find a problem, feel free to create an issue or a PR.
- Clone this repo.
- Run
npm install
. - Commit your fix.
- Make a PR and confirm all the CI checks passed.