GithubHelp home page GithubHelp logo

morellodev / react-awesome-reveal Goto Github PK

View Code? Open in Web Editor NEW
1.1K 5.0 40.0 6.84 MB

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

Home Page: https://react-awesome-reveal.morello.dev

License: MIT License

HTML 0.59% TypeScript 81.25% JavaScript 2.33% Shell 0.07% MDX 15.76%
reatctjs typescript javascript web intersection-observer css css-animations hooks reveal animations

react-awesome-reveal's Introduction

React Awesome Reveal

Version Last Commit Downloads Size License Rate on Openbase

Tip

If you like this library, please consider supporting its creator.

React Awesome Reveal 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 and implemented as CSS Animations to benefit from hardware acceleration.

Table Of Contents

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

npm install react-awesome-reveal @emotion/react --save

or, if you are using Yarn:

yarn add react-awesome-reveal @emotion/react

or, if you are using PNPM (as I strongly suggest):

pnpm add react-awesome-reveal @emotion/react

Quick Start

Import effects from React Awesome Reveal to your React component, for example the Fade effect:

import { Fade } from "react-awesome-reveal";

Then simply wrap the components you want to animate:

<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 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 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:

<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:

<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:

<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:

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 is the API used to determine if an element is inside the viewport or not. Browser support is really good – with Safari adding support in 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 directly or use a service like polyfill.io to add it when needed.

yarn add intersection-observer

Then import it in your app:

import "intersection-observer";

If you are using Webpack (or similar) you could use dynamic imports to load the polyfill only if needed. A basic implementation could look something like this:

/**
 * 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.

react-awesome-reveal's People

Contributors

bro3simon avatar dependabot[bot] avatar morellodev avatar pgrodrigues avatar pwfisher avatar semantic-release-bot avatar thebuilder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-awesome-reveal's Issues

SSR implementation for crawlers?

One of the promoted features is that this works out of the box with SSR. I took that to mean that when javascript is off the components will still be visible so that crawlers can read the page. If that assumption is incorrect then skip the rest.

I followed the documentation, animation works great.

<Fade>
    <div>My content</div>
</Fade>

but when I turn off javascript the component remains in a hidden state.

In order to circumvent this, I added a class to the Fade component.

<Fade className="animated-element">
    <div>My content</div>
</Fade>

and made it visible when there is no javascript.

<noscript>
    <style type="text/css">
        .animated-element{
            opacity:1 !important; 
        }
    </style>
</noscript>

Works great but... is this the best solution?

Type instead of Enum?

Why there are types like export type Direction = 'top' | 'left' | 'bottom' | 'right' | undefined; that cannot be used as enum?

that means we cannot do something like that, can we?

<Fade direction={Direction.Bottom}>

Performance is worse with multiple animation

Coming from react-reveal, and I am noticing that react-awesome-reveal animation is jittery and scrolling is janky when there are multiple animation played. Esepecially in animation heavy landing page.

Sorry but I can't create codesandbox at the moment, will do when I have the time. For now, I just informing my experience...

Children elements split up

Hi there :)

Consider the following snippet:

<Fade className="hello">
    <span>hi</span>
    <span>there</span>
</Fade>

In 2.4.2, both spans were rendered inside .hello.

Now, on 3.3.1, Fade breaks this down into two divs, each containing a single span.

image

Codesandbox: https://codesandbox.io/s/react-awesome-reveal-v3-breaks-children-irxig?file=/src/App.js

Why does this happen?
It was quite handy I could supply Fade a className instead of wrapping its children with yet another div.

Thanks!

Some elements with wrapped animation components are losing classes

I have an element with the class container and it has 2 children one with class left and one right
I wrapped children with classes left and right with different animation components tried (Fade,Slide,Bounce,Flip) and the styling was messed up when I check on developers tools the elements are missing the classes but the inner children have their classes

Content flickering

Thank you for the awesome work! I love it.

Can you tell me how can I prevent to reload content before animation? Content loads -> then animation triggers. This creates not looking good flicker of content. Do you have any solution for that?

Cosmetic issue on docs page

I love the examples page, very nice design! But it's really annoying that the sidebar disappears every time you choose a new style. It makes it kind of hard to scroll through them when trying to find the right one for your use case. I am pretty sure this will be 5 seconds for you and it will make the experience much smoother :-)

Add fraction prop

Add a new fraction prop to specify how much an element should be in viewport before triggering the reveal animation.

Add reverse prop

Animations can easily be reversed for cleanup using state to set the value of a reverse prop and is already implemented but it is not stated in documentation even though it works.

Example:

const [shown, setShown] = useState(false)
const yeetMenu = () => {
    setShown(!shown)
}
<Slide
      duration={500}
      triggerOnce={true}
      direction="right"
      reverse={shown}
> 
<nav>Menu</nav>
<button onClick={yeetMenu}>Close</button>
</Slide>

I couldn't figure out any other way of implementing this feature if it already was it was unclear.

Not working in Safari

Hi, really like the library. Just wanted to share a bug I've found. It seems the library doesn't work properly in Safari. The error I'm getting is attached below. Tested on IOS 13 as well as desktop safari version 12.0.1.

Screen Shot 2020-06-17 at 9 49 14 AM

Redesign navbar on demo site

Decide if maintain a single row of links (in this case remove the inner flex container) or add an hamburger menu for selecting the animations

Accessibility TabIndex

Hey,

First of all, i really apreciaty this kind of NPM package that helps alote to the community.

after that, i'm wandering how can I TabIndex, in the elements, and how can we use ur package in a accessibility way!.

this is my example, and when i'm traying to do TAB it never stop. How can we do it possible?

  <Fade direction="bottom">
              <h2 tabIndex="0" tabIndex className="explore-the-future-of-data__title">
                {t(`${TRANSLATION_SUFIX}.save-the-day.title-1`)}
                <br />
                {t(`${TRANSLATION_SUFIX}.save-the-day.title-2`)}
              </h2>
            </Fade>
            <Fade direction="left" cascade>
              <h3 tabIndex="1" className="explore-the-future-of-data__subtitle">{t(`${TRANSLATION_SUFIX}.save-the-day.title-3`)}</h3>
              <p tabIndex="2">{t(`${TRANSLATION_SUFIX}.save-the-day.description-1`)}</p>
              <p tabIndex="3">{t(`${TRANSLATION_SUFIX}.save-the-day.description-2`)}</p>
            </Fade>
```

Is this a fork of react-reveal?

Hi,

I was just wondering, is this a fork of react-reveal? I'm tentatively looking for a replacement. react-reveal is great, but it hasn't been maintained in 3 years, and it's giving me this warning I can't seem to make go away:

Warning: componentWillReceiveProps has been renamed, and is not recommended for use. . . . Please update the following components: RevealBase

I added UNSAFE_ to the library but one of my components which requires the when={useStateParam) stopped working afterward. Would react-awesome-reveal be a valid replacement in this instance?

Thanks

Request: Override fade-in direction distance

Love this package, it helps out my project a lot!
It would be awesome if I can control the distance elements travel when using Fade with a direction. I'm using Fade with Left and the elements always seem to fly in from off-screen. It would be super helpful if I could override that distance with a set pixel amount,

Add when-prop in the vein of react-reveal

Hi,

first, let me thank you for this modern alternative to react-reveal! Was mostly a plug- & play-replacement process.

However, one feature I'd like to see is missing: the when prop.

Example use case:

  • login form shakes on error: <Shake when={!!error}>{children}</Shake>

Nested cascade

I was curious if you thought about this. How would one achieve e.g. combined Slide and Fade, both in cascade mode? This seems like a fairly standard animation (appear one by one sliding from the left) but I am afraid that doesn't work atm. I understand that this is a sideproduct of the design. It merely loops over children and wraps them in an animation component with delay. Maybe an API could be introduced. I can picture something like "nested animations" where you would simply provide an array of animation components from the lib. There would then be used for "extra" wrapping while looping over the children. Just thinking out loud here :)

Programmatically trigger reveal or disable capability

Hi,

just here to leave a suggestion to allow programatically trigger reveal or disable them on the fly.

For example:
You have a one big web page and you have headings that include anchor links (e.g. /#about), so you can jump between sections quickly. If I implement this now and jump to third heading on the site, sections one and two still hasn't triggered their reveal animations, but when I scroll up, they will trigger. The reveals don't look that great when scrolling top of the page, because they were implemented scrolling to bottom of the page "in-mind".

The Internet Explorer problem...

Hello,
First thanks a lot for this package, it's awesome !

I am working on a website for a client, the problem is it's in a sector where a lot of people still run internet explorer on XP...
Very annoying to dev a modern website and make it work properly on every browser. Turns out IE is not dead for some people x)

I am having this error on IE11:
'IntersectionObserver' is undefined

I'm sure it's because something is not compatible with IE but it would be great if the main Reveal component would just not render in case the browser is IE. We wouldn't have animations anymore but if IE users want them they can update there browser.

Do you feel like it's something worth working on ?
If you have a workaround I'm interested !

Map Fade's items at same time in viewport.

I have a map which maps over some data and returns the component which is wrapped by the Fade, my problem now is the first 3 items are getting faded in from left at the same tim instead of one by one, this only happens on the 3 that fit in the viewport of my monitor all other components below work fine and fade in one by one, so is it possible to actually do this? I tried a few props and read the docs but nothing seems to fix this.

Thanks

Animate css in the bundle

The entire animate.css is included as a string in the package, consequently making the library unnecessarily large. After reading this, I kind of understand why this was done, but this is quite a disaster for ssr and statically generated pages. My generated HTML pages grew by 50% after adding this lib because the style is inline loaded (yet the same code also remains in the js that needs to be downloaded subsequently). I think it would make sense to make this optional. Including this directly in the source is not a good idea IMHO. I for one would prefer if I could take care of this on my end, maybe even pick only the parts of animate.css that I am interested in.

Issue Items do not appear at the right moment when scrolling down.

If you take a look at my Site https://dev-institut-fuer-bewegende-kuenste-kohl.vercel.app/ you can see that the Fade works for the news but there is a problem that it does not appear at the right moment when you go down, somehow it feels like the box size or layout size makes the problem to react-awesome-reveal. Also there is the issue that if you manage somehow to fill the last row by going up down with your mouse wheel the last 2 items never appear.

I tried to play around with fraction or delay but nothing helped. Any idea how to make it so a new row of news cards appears as soon as maybe 20pixel of the card could be seen. Any suggestion on what I can do here? Here my code

{data && data.length && (
          <Fade
            direction="up"
            cascade={true}
            triggerOnce={true}
            damping={1}
            duration={200}
            fraction={0.2}
          >
            {topNews.map((post, index) => (
              <NewsComponent key={post.id} post={post} />
            ))}
          </Fade>
        )}
```

Markup for 'ul' disappears

When applied to lists, the <ul></ul> tags disappear, is this intentional?
It's my understanding that this is not valid html markup.

Pd. Congrats on making this library! :) It's a pleasure to upgrade from react-reveal.

HeadShake removed

Hi, I am using HeadShake in my code. Any reason for removing it in v3? I still see it in the demo though.

Specific imports

It would be great if it was possible to import specific components instead of the whole bundle. Something along the lines of

import {Fade} from 'react-awesome-reveal/Fade'.

The lib is fairly small (gj on that) but this would make it even smaller.
It's fairly easy to do, I am doing something similar in some of my libs, just set up an extra build step that builds all files with babel and puts them in a specific folder.

You can check out my build script for reference: GuestBell forms transpile

animations not working - react-awesome-reveal

I want to use react-awesome-reveal in my typescript project but the animations doesnt seem to work. However, it works when I use react-reveal. Please advice on what I am missing.

import React, { Component } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import { Fade } from "react-awesome-reveal";
import ReactRevealFade from "react-reveal/Fade";
import "./style.css";

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: "React"
    };
  }

  render() {
    return (
      <div>
        <Fade>
          <Hello name={this.state.name} />
        </Fade>
        <ReactRevealFade left>
          <Hello name={this.state.name} />
        </ReactRevealFade>
        <p>Start editing to see some magic happen :)</p>
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

Stackblitz Code: Link

Any help is appreciated.

React Hooks warning, possibly related to Emotion

I've been receiving this warning while using react-awesome-reveal lately. Seems to be related to Emotion.

Warning: React has detected a change in the order of Hooks called by EmotionCssPropInternal.
This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks:
https://reactjs.org/link/rules-of-hooks

   Previous render            Next render
   ------------------------------------------------------
1. useContext                 useContext
2. undefined                  useContext
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I've attached a simple Codesandbox that contains React v17 and this package that shows the error.

Generic component

It would be great if, on top of importing different components, there would be one top-level component where you could provide "type" prop and it would render specific effect for you. Useful for wrapped components where you want to override effect for consistent behavior across an app.

Elements are visible if fractions prop is used

Hi, first of all for great work with the library!
I have been using it in my project and when I have tried to use fraction, components are visible before required fraction is reached. When fraction is 0, components are initially invisible and behave as expected.

image
Items has fraction set to 0.5. Second element is partially visible but < 0.5 fraction. When 0.5 is reached, animation is triggered anyway ( moving from invisible to the same place).

ClassName prop on container element

Previously that helped a lot, but now I understand that what I need is the effect on the container element, not on the child element.
I've tried version 2 to find out, but this version 3 updates is very good, and it's a shame if I have to go back to version 2. Sorry for bothering you

Pulse causes error

Pulse animation causes error in my create-react-app template. Other animations work well.

Code:

import React from "react";
import { setPageInfo } from "../../helpers/setPageInfo";
import { MainLayout } from "../../layouts/MainLayout";
import { Pulse } from "react-awesome-reveal";

export function Animations() {

  setPageInfo( "Animations", "This is animation sandbox." );
 
  return(
    <MainLayout>
      
      <section>
        <Pulse> 
          <h1>Pulse animation</h1>
        </Pulse>
      </section>

    </MainLayout>
  )
}

Снимок экрана 2020-09-03 в 16 10 14

How to trigger animation on variable change?

What is the equivalent of spy prop from react-reveal

spy: Any change in this prop value will cause the element to be revealed again. It makes sense to set it to some state variable. Disables the initial reveal animation (use appear prop to reenable it). Optional.

Problem with react-router Link and delay with cascade

Hi,

First thank you for the library! great work!
It was excaclty what I've been looking for :)

#1
I've got an issue when browsing through pages with react-router "Link", for example, I'm using Fade, and the components should not be visible at the beggining but when moving into another page for a split seconds they are shown and then the animation starts.

I've managed to solve it by adding "opacity: 0" to it's all children and another fade animation to wrap them and get it back to "opacity: 1".

#2
It seems like when 'cascade' is active, 'delay' won't work.

Maybe i'm doing something wrong? any way hope you'll get look into that :)

Support for ForwardRef

Hi Dennis,
First of all, I wanted to say your library is amazing! 🌟

I do have one suggestion tho:

When you use a Reveal component on a custom component, it won't work. You need to wrap it with a "vanilla" HTML element like div, span, etc. This is caused because components do not pass references to their container element by default.

But, since React has forwardRef, this is actually possible to solve.

I used @tippyjs/react which seems to support forwardRef. I guess it's not that of a change (correct me if I'm wrong).

Anyway, until this issue is not solved, it might be a good idea to consider recalculate cascade when custom components are part of the chain. The cascade animation won't work (because what I described above) but it will get into the delay calculation. I think it'll be better to exclude it from the delay (so following elements won't be too much delayed).

xoxo

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.