Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/steadicat/react-rebound

High-performance spring animations in React
https://github.com/steadicat/react-rebound

animation react spring

Last synced: 4 days ago
JSON representation

High-performance spring animations in React

Awesome Lists containing this project

README

        

# React Rebound

A spring-based React animation library that animates elements directly in the DOM for maximum performance. Hooks and component-based API available. Spring physics are based on [rebound](https://github.com/facebook/rebound-js).

Check out some demos [here](http://steadicat.github.io/react-rebound/).

## The `useAnimation` hook

`useAnimation` takes a “ref” to the element you want to animate, and an object containing the end values for the spring animation.

```js
import {useAnimation} from 'react-rebound';

function Example() {
const [hovered] = React.useState(false);
const ref = React.useRef();

// A little “pop” on hover
useAnimation(ref, {scaleX: hovered ? 1.1 : 1, scaleY: hovered ? 1.1 : 1});

return (
setHovered(true)}
onMouseLeave={() => setHovered(false)}>
Hover Me

);
}
```

## The `Animate` component

The `Animate` component wraps the DOM element you want to animate. It takes the end values for the spring animation as props.

```js
import {Animate} from 'react-rebound';

function Example() {
const [hovered] = React.useState(false);

return (

setHovered(true)} onMouseLeave={() => setHovered(false)}>
Hover Me


);
}
```

## Configuring springs

You can configure the `tension` and `friction` for the spring that’s driving the animation. Use props on `Animate`, and a third parameter to `useAnimation`.

A `delay` parameter is also available. It defers the animation by the specified number of milliseconds. This is useful for cascading animations.

```js
// Using useAnimation
useAnimation(ref, {translateX: clicked ? 200 : 0}, {tension: 200, friction: 400, delay: 100});
Click Me

// Using Animate

Click Me

```

## Animating colors

You can animate between two colors by representing colors as RGB(A) arrays. See [Supported properties](#supported-properties) for the list of color properties supported.

```js

Hover Me

```

## Render function with `animating` parameter

Sometimes it’s useful to render children differently during animations. To do that, provide a function as the only child. The function takes one parameter, a boolean that tells you whether an animation is in progress.

This option is only avaliable with the `Animate` component. If you’re using the `useAnimation` hook, use [start and end callbacks](#start-and-end-callbacks).

```js

{animating => }

```

## Start and end callbacks

In complex situations it might be useful to be notified when an animation starts or ends. `useCallback` and `Animate` provide two callbacks: `onStart` and `onEnd`.

```js

// Using useAnimation
useAnimation(
ref,
{scaleX: expanded ? : 5 : 1, scaleY: expanded ? 5 : 1},
{onStart: onExpandStart, onEnd: onExpandEnd},
);

// Using Animate

```

## Animating on first render

To animate an element in on mount, first render with the initial value, then trigger an animation using `componentDidMount` or `useEffect`:

```js
// Using useAnimation
const ref = React.useRef();
const [visible, setVisible] = React.useState(false);

React.useEffect(() => setVisible(true), []);

useAnimation(ref, {opacity: visible ? 1 : 0});

Hover Me;

// Using Animate
const [visible, setVisible] = React.useState(false);

React.useEffect(() => setVisible(true), []);

Hover Me
;
```

## Setting initial values

Spring animations should always start from their previous value: this is why with `react-rebound` you only specify the end value of the animation.

In some special cases, it might be necessary to override the start value. You have two options:

1. Use the `setCurrentValue` imperative API (see [Setting current values and velocity](#setting-current-values-and-velocity)).
2. Render with an initial value and `animate={false}`, then render again with your end value and `animate={true}`.

```js
// Using useAnimation
const [visible, setVisible] = React.useState(false);
const instantHide = React.useCallback(() => setVisible(false));
const fadeIn = React.useCallback(() => setVisible(true));
useAnimation(ref, {opacity: visible ? 1 : 0}, {animate: visible});

Hover Me;

// Using Animate
const [visible, setVisible] = React.useState(false);
const instantHide = React.useCallback(() => setVisible(false));
const fadeIn = React.useCallback(() => setVisible(true));

Hover Me
;
```

## Setting current values and velocity

`useAnimation` returns an object containing all the Rebound springs, indexed by
property name. This gives you full control if you need it, including the option
of calling `setCurrentValue` and `setVelocity` on the springs directly. This is
useful for swipes and drags, where you want to override the spring animation
while dragging, and preserve velocity when the drag ends.

```js
const ref = React.useRef();
const springs = useAnimation(ref, {translateX: restingPosition});

const onSwipeMove = React.useCallback(() => {
springs.translateX.setCurrentValue(currentPosition);
});

const onSwipeEnd = React.useCallback(() => {
springs.translateX.setVelocity(200);
});

;
```

When using `Animate`, you can override the current value and velocity of an
animation using the public methods `setCurrentValue` and `setVelocity` on the
component instance.

```js
const animation = React.useRef();

const onSwipeMove = React.useCallback(() => {
animation.current.setCurrentValue('translateX', currentPosition);
});

const onSwipeEnd = React.useCallback(() => {
animation.current.setVelocity('translateX', 200);
});


;
```

## Supported properties

This is the full list of properties you can animate:

### Transforms

- **translateX**: number in px
- **translateY**: number in px
- **translateZ**: number in px
- **scaleX**: number representing the scale ratio (1 is the default)
- **scaleY**: number representing the scale ratio (1 is the default)
- **rotateX**: number in deg
- **rotateY**: number in deg
- **rotateZ**: number in deg
- **skewX**: number in deg
- **skewY**: number in deg

### Position and opacity

- **top**: number in px
- **left**: number in px
- **right**: number in px
- **bottom**: number in px
- **width**: number in px
- **height**: number in px
- **opacity**: number between 0 and 1

### Colors

**Warning**: animating colors causes a paint on every frame. Consider animating using opacity instead.

- **color**: array of numbers, either [r, g, b] or [r, g, b, a]
- **background**: array of numbers, either [r, g, b] or [r, g, b, a]
- **backgroundColor**: array of numbers, either [r, g, b] or [r, g, b, a]
- **borderBottomColor**: array of numbers, either [r, g, b] or [r, g, b, a]
- **borderColor**: array of numbers, either [r, g, b] or [r, g, b, a]
- **borderLeftColor**: array of numbers, either [r, g, b] or [r, g, b, a]
- **borderRightColor**: array of numbers, either [r, g, b] or [r, g, b, a]
- **borderTopColor**: array of numbers, either [r, g, b] or [r, g, b, a]
- **outlineColor**: array of numbers, either [r, g, b] or [r, g, b, a]
- **textDecorationColor**: array of numbers, either [r, g, b] or [r, g, b, a]

### Text

**Warning**: animating text properties can create slow and jittery animations. Consider using scale and translate transforms instead.

- **fontSize**: number in px
- **lineHeight**: number in px
- **letterSpacing**: number in px