Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/teodosii/react-tweenful

Animation engine designed for React
https://github.com/teodosii/react-tweenful

animation-engine animation-library react react-animation react-component react-tween

Last synced: about 1 month ago
JSON representation

Animation engine designed for React

Awesome Lists containing this project

README

        

[![npm version](https://badgen.net/npm/v/react-tweenful)](https://www.npmjs.com/package/react-tweenful) [![Minified & Gzipped size](https://badgen.net/bundlephobia/minzip/react-tweenful)](https://bundlephobia.com/result?p=react-ttweenful)

# react-tweenful

Looking for an amazing React library for animating stuff? Look no more, we've got you covered!

## Demo

https://teodosii.github.io/react-tweenful/

## Features

* Loop support (infinite or up to a specific number)
* Wide variety of easings (bezier, predefined and custom easing)
* Delayed animations (before and after)
* Events support
* Negative delay support to mimic CSS animations
* Percent based animations to mimic CSS animations (e.g. `0%`, `50%`, `100%`)
* `Tweenful` component for animating DOM nodes
* `SVG` component to animate SVG nodes
* `Observer` component for mount/unmount animations
* `ObserverGroup` component to handle child transition (list removal/insertion, page transition etc)

## Getting started

```
npm install react-tweenful
```

### Development

In order to build the project and run it on your local machine, you'll need to build both the `site` project and the library itself. The `site` project will have a dependency of `react-tweenful` and there you'll be able to play with the examples.

```
npm run build:library:dev
npm run start
```

Or if you want to be able to modify both projects at once and let webpack watch the changes and do the build for you, then open 2 separate terminals and run the following commands

```
npm run watch:library:dev
```
And in a separate terminal run
```
npm run start
```

Both commands will instruct webpack to watch for changes.
Navigate to `http://localhost:8080/react-tweenful` or whatever port you're running the application on.

## Usage

`react-tweenful` exports the following:

* `Tweenful` - component to animate DOM elements. It requires a DOM node to perform animation on.
* `SVG` - component to animate SVG elements. It requires a SVG node to perform animation on.
* `Observer` - component to animate mounting and unmounting of an element.
* `ObserverGroup` - component to watch over a list of `Observer` elements such as list removal/insertion or route transition

A couple of utility functions are also exported to help you out animating:

* `percentage` for percentage based animations
* `bezier` for bezier easings
* `elastic` for elastic easing

Import the needed component, for example `Tweenful`

```jsx
import Tweenful, { elastic } from 'react-tweenful';
```

`Tweenful` requires a node to render on which it will perform the animation. We've got most of the DOM nodes covered in the form of namespacing such as `Tweenful.div`, `Tweenful.span` and so on.

```jsx
const Example = () => (

);
```

Voila!

## Examples

### Observer

View animation [here](https://teodosii.github.io/react-tweenful/observer)

Usage of `Observer` component together with `Tweenful`. Animate movement with `Tweenful` and subscribe to mount and unmount with `Observer`.

![Observer](https://github.com/teodosii/react-tweenful/raw/master/gif/observer.gif "Observer")

```jsx
import React, { useEffect, useState } from 'react';
import Tweenful, { Observer, elastic } from 'react-tweenful';

const props = {
delay: 200,
render: true,
duration: 1600,
easing: elastic(1, 0.1),
loop: false,
animate: { translateX: '400px' },
events: {
onAnimationStart: () => console.log('AnimationStart'),
onAnimationEnd: () => console.log('AnimationEnd')
}
};

const ObserverDemo = () => {
const [shouldRender, setShouldRender] = useState(true);

useEffect(() => {
setTimeout(() => setShouldRender(false), 3000);
}, []);

return (





);
};
```

### ObserverGroup

View animation [here](https://teodosii.github.io/react-tweenful/notifications)

Usage of `ObserverGroup` component to watch for mounting and unmounting over a list of notifications

![Notifications](https://github.com/teodosii/react-tweenful/raw/master/gif/notifications.gif "Notifications")

```jsx

{this.state.notifications.map(notification => (

))}

```

### Animate route transition

View animation [here](https://teodosii.github.io/react-tweenful/transition)

Usage of `ObserverGroup` to animate route change

![Routing](https://github.com/teodosii/react-tweenful/raw/master/gif/transition.gif "Routing")

```jsx
import React from 'react';
import { Route, Switch, NavLink } from 'react-router-dom';
import ObserverGroup from 'react-tweenful/ObserverGroup';
import Observer from 'react-tweenful/Observer';

const colors = {
red: '#EE4266',
yellow: '#FDB833',
blue: '#296EB4',
green: '#0EAD69'
};

const Red = () =>

;
const Yellow = () =>
;
const Blue = () =>
;
const Green = () =>
;

class RouteTransitionDemo extends React.Component {
constructor(props) {
super(props);
}

render() {
const { location } = this.props;

return (



  • Red

  • Yellow

  • Blue

  • Green










Not Found
} />





);
}
}

export default RouteTransitionDemo;

```

### Prism

View animation [here](https://teodosii.github.io/react-tweenful/rotating-svg)

`react-tweenful` in action powering a super awesome looking animation.

![Prism](https://github.com/teodosii/react-tweenful/raw/master/gif/rotating-svg.gif "Prism")

```jsx
import React from 'react';
import { SVG } from 'react-tweenful';

const WAVE_COUNT = 16;
const offset = 40;
const waveLength = 375;
const duration = 1500;

const waves = new Array(WAVE_COUNT).fill(0).map((wave, i) => ({
key: i + 1,
style: {
transformOrigin: '500px 500px',
opacity: 4 / WAVE_COUNT,
mixBlendMode: 'screen',
fill: `hsl(${(360 / WAVE_COUNT) * (i + 1)}, 100%, 50%)`,
transform: `rotate(${(360 / WAVE_COUNT) * i}deg) translate(${waveLength}px, ${offset}px)`
},
rotate: `${(360 / WAVE_COUNT) * (i + 1)}deg`,
translate: `${waveLength}px ${offset}px`,
angle: `${(360 / WAVE_COUNT) * (i + 1)}deg`,
delay: (duration / WAVE_COUNT) * (i + 1) * -3,
path:
'M-1000,1000V388c86-2,111-38,187-38s108,38,187,38,111-38,187-38,108,38,187,38,111-38,187-38,108,38,187,38,111-38,187-38,109,38,188,38,110-38,187-38,108,38,187,38,111-38,187-38,108,38,187,38,111-38,187-38,108,38,187,38,111-38,187-38,109,38,188,38c0,96,0,612,0,612Z'
}));

const RotatingSvg = () => {
return (








{waves.map(wave => (

))}


);
};
```

### SVG

View animation [here](https://teodosii.github.io/react-tweenful/svg)

An example animating SVG `path` and `fill` properties one after the other.

![SVG](https://github.com/teodosii/react-tweenful/raw/master/gif/svg-path.gif "SVG")

### Gradients

View animation [here](https://teodosii.github.io/react-tweenful/gradients)

An example using `elastic` easing to animate gradient boxes.

![Gradients](https://github.com/teodosii/react-tweenful/raw/master/gif/gradients.gif "Gradients")

```jsx
import React from 'react';
import Tweenful, { elastic } from 'react-tweenful';

const Gradients = () => {
const elements = new Array(10)
.fill(0)
.map((_e, i) => (

));

return (


{elements}


);
};
```

### Loader

View animation [here](https://teodosii.github.io/react-tweenful/loading-circles)

![Loader](https://github.com/teodosii/react-tweenful/raw/master/gif/rotating-circles.gif "Loader")

```jsx
import React from 'react';
import Tweenful, { percentage } from 'react-tweenful';

const rotate = percentage({
'0%': { translate: '-50% -50%', rotate: '0deg' },
'50%': { translate: '-50% -50%', rotate: '0deg' },
'80%': { translate: '-50% -50%', rotate: '360deg' },
'100%': { translate: '-50% -50%', rotate: '360deg' }
});
const dot1Animate = percentage({
'0%': { scale: 1 },
'20%': { scale: 1 },
'45%': { translate: '16px 12px', scale: 0.45 },
'60%': { translate: '160px 150px', scale: 0.45 },
'80%': { translate: '160px 150px', scale: 0.45 },
'100%': { translate: '0px 0px', scale: 1 }
});
const dot2Animate = percentage({
'0%': { scale: 1 },
'20%': { scale: 1 },
'45%': { translate: '-16px 12px', scale: 0.45 },
'60%': { translate: '-160px 150px', scale: 0.45 },
'80%': { translate: '-160px 150px', scale: 0.45 },
'100%': { translate: '0px 0px', scale: 1 }
});
const dot3Animate = percentage({
'0%': { scale: 1 },
'20%': { scale: 1 },
'45%': { translateY: '-18px', scale: 0.45 },
'60%': { translateY: '-180px', scale: 0.45 },
'80%': { translateY: '-180px', scale: 0.45 },
'100%': { translateY: '0px', scale: 1 }
});

const LoadingCircles = () => {
return (















);
};

```

### Bouncing Balls

View animation [here](https://teodosii.github.io/react-tweenful/bouncing-balls)

Bouncing balls illustrate negative delay support in `react-tweenful`

![Bouncing Balls](https://github.com/teodosii/react-tweenful/raw/master/gif/bouncing-ball.gif "Bouncing Balls")

```jsx
import React from 'react';
import { SVG, percentage, elastic } from 'react-tweenful';

const circles = new Array(10).fill(0).map((_e, i) => ({
loop: true,
fill: `hsl(${(i + 1) * 20 - 20}, 70%, 70%)`,
delay: ((i + 1) * 1500) / -10,
duration: 1500,
easing: elastic(2, 0.9),
transform: {
translate: '0 100px'
},
style: {
transformOrigin: `${-200 + 120 * (i + 1)}px 250px`
},
animate: percentage({
'0%': { translate: '0px 100px', scale: 1 },
'50%': { translate: '0px -100px', scale: 0.3 },
'100%': { translate: '0px 100px', scale: 1 }
}),
r: 35,
cx: 100 * i + 50,
cy: 250
}));

const BouncingBalls = () => {
return (



{circles.map((circle, i) => (

))}


);
};
```

## API

**Update in progress. Stay in touch!**

## Note

A couple of the animations shown here have been initially created for CodePen by other folks. My only contribution to them was to convert them to `react-tweenful` to show real world examples on animating stuff.

## License

MIT