UNPKG

react-awesome-reveal

Version:

React components to add reveal animations using the Intersection Observer API and CSS Animations.

222 lines (162 loc) 14.8 kB
# React Awesome Reveal [![Version](https://badgen.net/npm/v/react-awesome-reveal)](https://www.npmjs.com/package/react-awesome-reveal/v/latest) [![Last Commit](https://badgen.net/github/last-commit/awesome-reveal/react-awesome-reveal/main)](https://github.com/awesome-reveal/react-awesome-reveal/commit) [![Downloads](https://badgen.net/npm/dt/react-awesome-reveal)](https://www.npmjs.com/package/react-awesome-reveal/v/latest) [![Size](https://badgen.net/bundlephobia/minzip/react-awesome-reveal)](https://bundlephobia.com/result?p=react-awesome-reveal@latest) [![License](https://badgen.net/npm/license/react-awesome-reveal)](https://www.npmjs.com/package/react-awesome-reveal/v/latest) [![Rate on Openbase](https://badges.openbase.io/js/rating/react-awesome-reveal.svg)](https://openbase.io/js/react-awesome-reveal?utm_source=embedded&utm_medium=badge&utm_campaign=rate-badge) > [!TIP] > If you like this library, please [consider supporting its creator](https://github.com/sponsors/morellodev). [React Awesome Reveal](https://react-awesome-reveal.morello.dev) is a library for React apps written in TypeScript that adds reveal animations using the Intersection Observer API to detect when the elements appear in the viewport. Animations are internally provided by [Emotion](https://emotion.sh) and implemented as CSS Animations to benefit from hardware acceleration. ## Table Of Contents - [Features](#features) - [Installation](#installation) - [Quick Start](#quick-start) - [Supported Effects](#supported-effects) - [Attention Seekers](#attention-seekers) - [Props](#props) - [Example](#example) - [Chaining Multiple Animations](#chaining-multiple-animations) - [Custom Animations](#custom-animations) - [Other Props](#other-props) - [Intersection Observer](#intersection-observer) - [Polyfill](#polyfill) - [Past Releases](#past-releases) - [License](#license) ## Features - 🎁 **Modern stack** – It is built for modern React and supports React 18 - 🏷 **TypeScript support** – It is written in TypeScript to improve the DX - 🍃 **Lightweight** – Very little footprint on your project - ⚙️ **Uses native APIs** – Intersection Observer and CSS Animations are now supported by all browsers - 🚀 **Fast** – Buttery smooth experience thanks to the use of native asynchronous APIs and hardware acceleration - 💅 **Fully customizable** – Define custom animations and let the library render them - 💻 **SSR support** – Server Side Rendering works out-of-the-box - 🌳 **Tree-shakeable** – Only the parts you use will be included in your final bundle ## Installation To add this package as a dependency to your app, simply run ```sh npm install react-awesome-reveal @emotion/react --save ``` or, if you are using Yarn: ```sh yarn add react-awesome-reveal @emotion/react ``` or, if you are using PNPM (as I strongly suggest): ```sh pnpm add react-awesome-reveal @emotion/react ``` ## Quick Start Import effects from [React Awesome Reveal](https://www.npmjs.com/package/react-awesome-reveal) to your React component, for example the `Fade` effect: ```js import { Fade } from "react-awesome-reveal"; ``` Then simply wrap the components you want to animate: ```jsx <Fade> <p>I will gently appear as I enter the viewport</p> </Fade> ``` ## Supported Effects The effects currently supported are `Bounce`, `Fade`, `Flip`, `Hinge`, `JackInTheBox`, `Roll`, `Rotate`, `Slide` and `Zoom`. Refer to the [Animate.css](https://animate.style) documentation for the details. ### Attention Seekers Since version 3, attention seeker animations are wrapped by the `AttentionSeeker` component, which accepts a prop called `effect` that specifies the animation to render (defaults to `"bounce”`). The supported effects are: `”bounce"`, `"flash"`, `"headShake”`, `"heartBeat"`, `"jello”`, `"pulse"`, `"rubberBand"`, `“shake”`, `“shakeX"`, `"shakeY”`, `"swing”`, `"tada"` and `“wobble”`. Again, refer to the [Animate.css](https://animate.style) documentation for the details. ### Props You can pass the following props to the animation components to customize the behavior: | Prop | Description | Values | Default | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | | `cascade` | If set, each child of a reveal animation automatically get assigned a delay that takes into account their predecessor (child `i` enters the viewport after `i * delay * damping` milliseconds) – useful for animating list items. | `true` or `false` | `false` | | `damping` | Factor that affects the delay that each animated component in a cascade animation will be assigned. If `damping = 1` then the delay will be equal to the animation duration; if `damping < 1` then the delay will be lower than the animation duration; if `damping > 1` then the delay will be greater than the animation duration. | `number` | `0.5` (meaning that the delay will be half of the animation duration) | | `direction` | Origin of the animation (where applicable). | Usually `"down"`, `"left"`, `"right"` or `"up"`, with some exceptions documented in the code | `undefined` | | `delay` | Time to wait before the animation starts (in milliseconds). | `number` | `0` | | `duration` | The animation duration (milliseconds). | `number` | `1000` | | `fraction` | How much an element should be in viewport before the animation is triggered. | `number` between `0` and `1` | `0` | | `triggerOnce` | Specifies if the animation should run only once or everytime an element enters/exits/re-enters the viewport. | `true` or `false` | `false` | | `className` | The class names to add to the container element. | `string` | `undefined` | | `style` | The inline styles to add to the container element. | `React.CSSProperties` | `undefined` | | `childClassName` | The class names to add to the child element. | `string` | `undefined` | | `childStyle` | The inline styles to add to the child element. | `React.CSSProperties` | `undefined` | | `onVisibilityChange` | Callback executed when the element enters or leaves the viewport. If more than one element is being animated, this function is called on each element. | `(inView: boolean, entry: IntersectionObserverEntry) => void` | `undefined` | ### Example To trigger the animation only the first time an element enters the viewport: ```jsx <Slide triggerOnce> <p>I will animate only the first time you see me</p> </Slide> ``` ### Chaining Multiple Animations To chain together multiple animations, set the `cascade` prop to `true`: ```jsx <Fade cascade> <p>I enter first...</p> <p>...then comes my turn...</p> <p>...and finally you see me!</p> </Fade> ``` Play with the `damping` prop to alter the delay by which each child will progressively appear: ```tsx <Fade cascade damping={0.1}> <p>I enter first...</p> <p>...then comes my turn...</p> <p>...and finally you see me!</p> </Fade> ``` ## Custom Animations Starting from version 3.2.0, you can define custom animations! Simply import the `Reveal` component (which is the default export of the library – give it the name you want) and pass it a `keyframes` prop: ```jsx import React from "react"; import Reveal from "react-awesome-reveal"; import { keyframes } from "@emotion/react"; const customAnimation = keyframes` from { opacity: 0; transform: translate3d(-200px, -100px, 0); } to { opacity: 1; transform: translate3d(0, 0, 0); } `; function CustomAnimation({ children }) { return <Reveal keyframes={customAnimation}>{children}</Reveal>; } ``` If no `keyframes` prop is passed, the default rendered animation is a fading entrance from the left (equivalent to `<Fade direction="left">...</Fade>`). ### Other Props You can also pass these props to `Reveal`: - `cascade` - `damping` - `delay` - `duration` - `fraction` - `triggerOnce` - `className` and `childClassName` - `style` and `childStyle` - `onVisibilityChange` ## Intersection Observer [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) is the API used to determine if an element is inside the viewport or not. [Browser support](http://caniuse.com/#feat=intersectionobserver) is really good – with [Safari adding support in 12.1](https://webkit.org/blog/8718/new-webkit-features-in-safari-12-1), all major browsers now support Intersection Observers natively. If you need to support old browsers, add the polyfill for the Intersection Observer API. ### Polyfill You can add the [polyfill](https://www.npmjs.com/package/intersection-observer) directly or use a service like [polyfill.io](https://polyfill.io/v2/docs) to add it when needed. ```sh yarn add intersection-observer ``` Then import it in your app: ```javascript import "intersection-observer"; ``` If you are using Webpack (or similar) you could use [dynamic imports](https://webpack.js.org/guides/code-splitting/#dynamic-imports) to load the polyfill only if needed. A basic implementation could look something like this: ```javascript /** * Do feature detection, to figure out which polyfills needs to be imported. **/ async function loadPolyfills() { if (typeof window.IntersectionObserver === "undefined") { await import("intersection-observer"); } } ``` ## Past Releases To see the documentation for previous versions, navigate through past tags in the GitHub's project repository and read the README for that specific version. ## License Project source code is licensed under the MIT license. You are free to fork this repository, edit the code, share and use it both for non-commercial and commercial purposes.