Trying to make layout transitions simple
Check it out at https://react-layout-transition.surge.sh/
This project aims to provide React components that can ✨ automagically ✨ animate between changes in your layout. Inspired by existing solutions on native platforms, it hopes to bring similar functionality and ease to the web.
These are some great pieces with example code on how to use the native platform feature
- React Native’s LayoutAnimation is Awesome - Justin Poliachik (Medium)
- Animate all the Things. Transitions in Android - Andrey Kulikov (Medium)
Note: This is a very early implementation so do expect loads of bugs and missing features (but also be sure to report them)
react-layout-transition is available on the npm registry and can be installed via npm/yarn
npm install --save react-layout-transition
You should have npm installed if you have Node.js
Or you can download Node.js from https://nodejs.org/en/ which comes with npm
You can also include it directly using script tags via the unpkg CDN
<script src='https://unpkg.com/react-layout-transition/dist/react-layout-transition.min.js'></script>
A component that animates state based changes in layout in certain parts of your view.
Can handle the addition and removal of DOM nodes (as shown below)
Find the code for above example here here
An abstract class that must be extended by your component
Must also implement the getInterpolator
function that returns an Interpolator. (see section below)
class MyComponent extends LayoutTransitionGroup {
this.interpolator = new CssInterpolator();
getInterpolator() {
return this.interpolator;
}
// must call superclass method if you implement componentDidUpdate
componentDidUpdate(prevProps, prevState) {
super.componentDidUpdate(prevProps, prevState);
// your code here
}
// other methods and React lifecycle methods
}
✨ this is where the magic happens ✨
parameters
stateUpdateFn
: (currState) => newState
A function that takes in the the current state and returns the new state. Identical to the first parameter of React'ssetState
refs
: Ref[] | Ref
The React ref to the HTML element whose top level children will be animated
A container around the views to transition between that animates shared elements, between their initial and final position. It classifies elements as shared if you mark them with the same id in both the intial and final layout component and does the rest for you.
Find the code for above example here here
class Demo extends React.Component {
interpolator = new CssInterpolator();
state = {
toggle: true,
};
render() {
return (
<div>
// animates when toggle is changed to false
<SharedElementTransitionGroup interpolator={this.interpolator}>
{this.state.toggle && <Page1 />}
{!this.state.toggle && <Page2 />}
</SharedElementTransitionGroup>
</div>
);
}
}
interpolator
: Interpolator
Pass an instance of the interpolator you would like to use for the animation. (see section below)
Make sure you mark the shared elements with the same id
s
class Page1 extends React.Component {
render() {
return (
<div style={this.props.style} ref={this.props.innerRef}>
<p>...</p>
<div className='vertical-flex'>
// this is where the magic happens ✨
<img id="hero" className='img-style' src='image1.jpg' />
<img id="another-one" className='img-style' src='image2.jpg' />
</div>
<p>...</p>
</div>
);
}
}
class Page2 extends React.Component {
render() {
return (
<div style={this.props.style} ref={this.props.innerRef}>
// this is where the magic happens ✨
<img id="hero" className='img-style' src='image1.jpg' />
<p>...</p>
<img id="another-one" className='img-style' src='image2.jpg' />
</div>
);
}
}
Interpolators are classes that implement certain methods that are called to perform the animation. This allows seperation of animation logic from the rest of the code and also enables different kinds of animations and techniques.
There are 2 kinds of interpolators in the interpolators
directory.
import CssInterpolator from 'react-layout-transition/interpolators/CssInterpolator';
const interpolator = new CssInterpolator(timing, easing);
Uses CSS transforms to animate elements.
The constructor takes two optional parameters
timing
: number
the number milliseconds the transition takes
default: 300easing
: string
the easing function for the transition
default: 'ease-in-out'
import SpringInterpolator from 'react-layout-transition/interpolators/SpringInterpolator';
const interpolator = new SpringInterpolator(stiffness, damping, precision);
Uses CSS transforms to animate elements.
The constructor takes three optional parameters
stiffness
: number
the number milliseconds the transition takes
default: 170damping
: number
the easing function for the transition
default: 26precision
: number
the easing function for the transition
default: 0.01
You can write your own interpolators as long as you implement the correct functions
import Interpolator from 'react-layout-transition/interpolators/Interpolator';
class MyInterpolator extends Interpolator {
play(
element: HTMLElement,
invertObject: {sx: number; sy: number; x: number; y: number},
reverse: boolean,
callback?: () => void,
): void;
playMultiple(
element: HTMLElement[],
invertObject: Array<{sx: number; sy: number; x: number; y: number}>,
reverse: boolean,
callback?: () => void,
): void;
}
The invertObject
is an object that contains the delta of initial and final values of
- scale in X-axis (sx)
- scale in Y-axis (sy)
- translation in X-axis (x)
- translation in Y-axis (y)
Please do report any bugs you encounter and point to me any examples and use cases that could be used to improve this
If you like the direction the project is headed in and want to help please do reach out!