use-web-animations
React hook for highly-performant and manipulable animations using Web Anima...
README


Features
Requirement
Installation
- ```sh
- $ yarn add @wellyshen/use-web-animations
- # or
- $ npm install --save @wellyshen/use-web-animations
- ```
Before We Start
Usage
⚠️ Most modern browsers support Web Animations API natively. You can also use polyfill for full browser support.
Basic Usage
💡 This hook supports the pseudoElement property via theanimationOptions option.
- ``` js
- import useWebAnimations from "@wellyshen/use-web-animations";
- const App = () => {
- const { ref, playState } = useWebAnimations({
- keyframes: {
- transform: "translateX(500px)", // Move by 500px
- background: ["red", "blue", "green"], // Go through three colors
- },
- animationOptions: {
- delay: 500, // Start with a 500ms delay
- duration: 1000, // Run for 1000ms
- iterations: 2, // Repeat once
- direction: "alternate", // Run the animation forwards and then backwards
- easing: "ease-in-out", // Use a fancy timing function
- },
- onReady: ({ playState, animate, animation }) => {
- // Triggered when the animation is ready to play
- },
- onUpdate: ({ playState, animate, animation }) => {
- // Triggered when the animation enters the running state or changes state
- },
- onFinish: ({ playState, animate, animation }) => {
- // Triggered when the animation enters the finished state
- },
- // More useful options...
- });
- return (
- <div className="container">
- <p>�� Animation is {playState}</p>
- <div className="target" ref={ref} />
- </div>
- );
- };
- ```
- ``` js
- let prevPending = true;
- const App = () => {
- const { ref } = useWebAnimations({
- // ...
- onUpdate: ({ playState, animation: { pending } }) => {
- if (prevPending && !pending) {
- console.log("Animation is ready to play");
- }
- prevPending = pending;
- if (playState === "finished") {
- console.log("Animation has finished playing");
- }
- },
- });
- // ...
- };
- ```
Setting/Updating Animation
- ``` js
- const { animation } = useWebAnimations();
- const changeAnim = () =>
- animation({
- keyframes: { transform: ["translateX(0)", "translateX(100px)"] },
- animationOptions: 1000,
- id: "123",
- playbackRate: 1,
- autoPlay: true,
- });
- ```
Playback Control
- ``` js
- import useWebAnimations from "@wellyshen/use-web-animations";
- const App = () => {
- const { ref, playState, getAnimation } = useWebAnimations({
- playbackRate: 0.5, // Change playback rate, default is 1
- autoPlay: false, // Automatically starts the animation, default is true
- keyframes: { transform: "translateX(500px)" },
- animationOptions: { duration: 1000, fill: "forwards" },
- });
- const play = () => {
- getAnimation().play();
- };
- const pause = () => {
- getAnimation().pause();
- };
- const reverse = () => {
- getAnimation().reverse();
- };
- const cancel = () => {
- getAnimation().cancel();
- };
- const finish = () => {
- getAnimation().finish();
- };
- const seek = (e) => {
- const animation = getAnimation();
- const time = (animation.effect.getTiming().duration / 100) * e.target.value;
- animation.currentTime = time;
- };
- const updatePlaybackRate = (e) => {
- getAnimation().updatePlaybackRate(e.target.value);
- };
- return (
- <div className="container">
- <button onClick={play}>Play</button>
- <button onClick={pause}>Pause</button>
- <button onClick={reverse}>Reverse</button>
- <button onClick={cancel}>Cancel</button>
- <button onClick={finish}>Finish</button>
- <input type="range" onChange={seek} />
- <input type="number" defaultValue="1" onChange={updatePlaybackRate} />
- <div className="target" ref={ref} />
- </div>
- );
- };
- ```
Getting Animation's Information
- ``` js
- import useWebAnimations from "@wellyshen/use-web-animations";
- const App = () => {
- const { ref, getAnimation } = useWebAnimations({
- keyframes: { transform: "translateX(500px)" },
- animationOptions: { duration: 1000, fill: "forwards" },
- });
- const speedUp = () => {
- const animation = getAnimation();
- animation.updatePlaybackRate(animation.playbackRate * 0.25);
- };
- const jumpToHalf = () => {
- const animation = getAnimation();
- animation.currentTime = animation.effect.getTiming().duration / 2;
- };
- return (
- <div className="container">
- <button onClick={speedUp}>Speed Up</button>
- <button onClick={jumpToHalf}>Jump to Half</button>
- <div className="target" ref={ref} />
- </div>
- );
- };
- ```
- ``` js
- import { useState } from "react";
- import useWebAnimations from "@wellyshen/use-web-animations";
- const App = () => {
- const [showEl, setShowEl] = useState(false);
- const { ref } = useWebAnimations({
- keyframes: { transform: "translateX(500px)" },
- animationOptions: { duration: 1000, fill: "forwards" },
- onUpdate: ({ animation }) => {
- if (animation.currentTime > animation.effect.getTiming().duration / 2)
- setShowEl(true);
- },
- });
- return (
- <div className="container">
- {showEl && <div className="some-element" />}
- <div className="target" ref={ref} />
- </div>
- );
- };
- ```
Dynamic Interactions with Animation
- ``` js
- import { useEffect } from "react";
- import useWebAnimations from "@wellyshen/use-web-animations";
- const App = () => {
- const { ref, animate } = useWebAnimations();
- useEffect(() => {
- document.addEventListener("mousemove", (e) => {
- // The target will follow the mouse cursor
- animate({
- keyframes: { transform: `translate(${e.clientX}px, ${e.clientY}px)` },
- animationOptions: { duration: 500, fill: "forwards" },
- });
- });
- }, [animate]);
- return (
- <div className="container">
- <div className="target" ref={ref} />
- </div>
- );
- };
- ```
- ``` js
- import useWebAnimations from "@wellyshen/use-web-animations";
- const App = () => {
- const { ref, animate } = useWebAnimations({
- id: "fall", // Set animation id, default is empty string
- keyframes: [{ top: 0, easing: "ease-in" }, { top: "500px" }],
- animationOptions: { duration: 300, fill: "forwards" },
- onFinish: ({ animate, animation }) => {
- // Lifecycle is triggered by each animation, we can check the id to prevent animation from repeating
- if (animation.id === "bounce") return;
- animate({
- id: "bounce",
- keyframes: [
- { top: "500px", easing: "ease-in" },
- { top: "10px", easing: "ease-out" },
- ],
- animationOptions: { duration: 300, composite: "add" },
- });
- },
- });
- return (
- <div className="container">
- <div className="target" ref={ref} />
- </div>
- );
- };
- ```
⚠️ Composite modes isn't fully supported by all the browsers, please check the browser compatibility carefully before using it.
Use Built-in Animations
- ``` js
- import useWebAnimations, { bounce } from "@wellyshen/use-web-animations";
- const App = () => {
- // Add a pre-defined effect to the target
- const { ref } = useWebAnimations({ ...bounce });
- return (
- <div className="container">
- <div className="target" ref={ref} />
- </div>
- );
- };
- ```
- ``` js
- const { keyframes, animationOptions } = bounce;
- const { ref } = useWebAnimations({
- keyframes,
- animationOptions: {
- ...animationOptions,
- delay: 1000, // Delay 1s
- duration: animationOptions.duration * 0.75, // Speed up the animation
- },
- });
- ```
See all available animations
Attention seekers
Back entrances
Back exits
Bouncing entrances
Bouncing exits
Fading entrances
Fading exits
Flippers
Lightspeed
Rotating entrances
Rotating exits
Specials
Zooming entrances
Zooming exits
Sliding entrances
Sliding exits
Use Your Own ref
- ``` js
- const ref = useRef();
- const { playState } = useWebAnimations({ ref });
- ```
Working in TypeScript
- ```ts
- const App = () => {
- const { ref } = useWebAnimations<HTMLDivElement>();
- return <div ref={ref} />;
- };
- ```
💡 For more available types, please check it out.
API
- ``` js
- const returnObj = useWebAnimations(options?: object);
- ```
Return Object
| Key | Type | Default | Description |
|---|---|---|---|
| -------------- | ------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ref` | object | | | |
| `playState` | string | undefined | | |
| `getAnimation` | function | | | |
| `animate` | function | | |
Parameter
| Key | Type | Default | Description |
|---|---|---|---|
| ------------------ | ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ref` | object | | | |
| `id` | string | `""` | Sets |
| `playbackRate` | number | `1` | Sets |
| `autoPlay` | boolean | `true` | Automatically |
| `keyframes` | Array | object | | |
| `animationOptions` | number | object | | |
Use Polyfill
- ```sh
- $ yarn add web-animations-js
- # or
- $ npm install --save web-animations-js
- ```
- ``` js
- import "web-animations-js/web-animations.min";
- ```
Articles / Blog Posts
💡 If you have written any blog post or article about use-web-animations, please open a PR to add it here.
Contributors ✨
Welly 💻 📖 🚧 |
探客时代
