Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
react-motion
Advanced tools
react-motion is a popular library for creating animations in React applications. It leverages the physics-based animation approach to create smooth and natural transitions. The library is highly flexible and allows developers to animate various properties of their components with ease.
Basic Animation
This example demonstrates a basic animation where a div element moves horizontally from 0 to 100 pixels using the spring function.
```jsx
import React from 'react';
import { Motion, spring } from 'react-motion';
const BasicAnimation = () => (
<Motion defaultStyle={{ x: 0 }} style={{ x: spring(100) }}>
{style => <div style={{ transform: `translateX(${style.x}px)` }}>Hello World</div>}
</Motion>
);
export default BasicAnimation;
```
Staggered Motion
This example shows how to create a staggered animation where multiple items move one after another, creating a cascading effect.
```jsx
import React from 'react';
import { StaggeredMotion, spring } from 'react-motion';
const StaggeredAnimation = () => (
<StaggeredMotion
defaultStyles={[{ x: 0 }, { x: 0 }, { x: 0 }]}
styles={prevInterpolatedStyles => prevInterpolatedStyles.map((_, i) => {
return i === 0
? { x: spring(100) }
: { x: spring(prevInterpolatedStyles[i - 1].x) };
})}
>
{interpolatingStyles => (
<div>
{interpolatingStyles.map((style, i) => (
<div key={i} style={{ transform: `translateX(${style.x}px)` }}>Item {i}</div>
))}
</div>
)}
</StaggeredMotion>
);
export default StaggeredAnimation;
```
Transition Motion
This example demonstrates how to use TransitionMotion to animate the addition and removal of items in a list, with smooth transitions for entering and leaving elements.
```jsx
import React from 'react';
import { TransitionMotion, spring } from 'react-motion';
class TransitionAnimation extends React.Component {
state = { items: ['a', 'b', 'c'] };
willEnter() {
return { opacity: 0 };
}
willLeave() {
return { opacity: spring(0) };
}
render() {
return (
<TransitionMotion
styles={this.state.items.map(item => ({ key: item, style: { opacity: spring(1) } }))}
willEnter={this.willEnter}
willLeave={this.willLeave}
>
{interpolatedStyles => (
<div>
{interpolatedStyles.map(config => (
<div key={config.key} style={{ opacity: config.style.opacity }}>{config.key}</div>
))}
</div>
)}
</TransitionMotion>
);
}
}
export default TransitionAnimation;
```
react-spring is a spring-physics based animation library that is highly flexible and performant. It provides a more modern API compared to react-motion and supports hooks, making it a popular choice for new React projects.
framer-motion is a powerful animation library that offers a simple and declarative API for creating animations. It supports keyframes, spring animations, and gestures, and is known for its ease of use and rich feature set.
react-transition-group is a low-level animation library that provides more control over the animation lifecycle. It is often used for more complex animations where developers need fine-grained control over the transition states.
import {Motion, spring} from 'react-motion';
// In your render...
<Motion defaultStyle={{x: 0}} style={{x: spring(10)}}>
{value => <div>{value.x}</div>}
</Motion>
Animate a counter from 0
to 10
. For more advanced usage, see below.
Npm: npm install --save react-motion
Bower: do not install with bower install react-motion
, it won't work. Use bower install --save https://npmcdn.com/react-motion/bower.zip
. Or in bower.json
:
{
"dependencies": {
"react-motion": "https://npmcdn.com/react-motion/bower.zip"
}
}
then include as
<script src="bower_components/react-motion/build/react-motion.js"></script>
<script src="https://npmcdn.com/react-motion/build/react-motion.js"></script>
(Module exposed as `ReactMotion`)
For React-native: previous react-motion v0.3.* supported a dedicated build for RN, which has now been made obsolete since RN v0.18. This library should Just Work under the new React-Native 0.18+.
git clone https://github.com/chenglou/react-motion.git
cd react-motion
npm install
To try the demos locally:
npm start
.npm run build-demos
and open the static demos/demo_name/index.html
file directly. Don't forget to use production mode when testing your animation's performance!To build the repo yourself: npm run prerelease
.
For 95% of use-cases of animating components, we don't have to resort to using hard-coded easing curves and duration. Set up a stiffness and damping for your UI element, and let the magic of physics take care of the rest. This way, you don't have to worry about petty situations such as interrupted animation behavior. It also greatly simplifies the API.
This library also provides an alternative, more powerful API for React's TransitionGroup
.
Coming from 0.3. to 0.4.0? Here's the upgrade guide.*
Exports:
spring
.Motion
StaggeredMotion
TransitionMotion
presets
Here's the well-annotated public Flow type definition file (you don't have to use Flow with React-motion, but the types help document the API below).
Used in conjunction with the components below. Specifies the how to animate to the destination value, e.g. spring(10, {stiffness: 120, damping: 17})
means "animate to value 10, with a spring of stiffness 120 and damping 17".
val
: the value.
config
: optional, for further adjustments. Possible fields:
stiffness
: optional, defaults to 170
.damping
: optional, defaults to 26
.precision
: optional, defaults to 0.01
. Specifies both the rounding of the interpolated value and the speed (internal).It's normal not to feel how stiffness and damping affect your spring; use Spring Parameters Chooser to get a feeling. Usually, you'd just use the list of tasteful stiffness/damping presets below.
{stiffness, damping}
Commonly used spring configurations used like so: spring(10, presets.wobbly)
or spring(20, {...presets.gentle, precision: 0.1})
. See here.
<Motion defaultStyle={{x: 0}} style={{x: spring(10)}}>
{interpolatingStyle => <div style={interpolatingStyle} />}
</Motion>
Required. The Style
type is an object that maps to either a number
or an OpaqueConfig
returned by spring()
above. Must keep the same keys throughout component's existence. The meaning of the values:
OpaqueConfig
returned from spring(x)
: interpolate to x
.number
x
: jump to x
, do not interpolate.Optional. The PlainStyle
type maps to number
s. Defaults to an object with the same keys as style
above, whose values are the initial numbers you're interpolating on. Note that during subsequent renders, this prop is ignored. The values will interpolate from the current ones to the destination ones (specified by style
).
Required function.
interpolatedStyle
: the interpolated style object passed back to you. E.g. if you gave style={{x: spring(10), y: spring(20)}}
, you'll receive as interpolatedStyle
, at a certain time, {x: 5.2, y: 12.1}
, which you can then apply on your div
or something else.
Return: must return one React element to render.
Animates a collection of items whose values depend on each other, creating a natural, springy, "staggering" effect like so. This is preferred over hard-coding a delay for an array of Motions
to achieve a similar (but less natural-looking) effect.
<StaggeredMotion
defaultStyles={[{h: 0}, {h: 0}, {h: 0}]}
styles={prevInterpolatedStyles => prevInterpolatedStyles.map((_, i) => {
return i === 0
? {h: spring(100)}
: {h: spring(prevInterpolatedStyles[i - 1].h)}
})}>
{interpolatingStyles =>
<div>
{interpolatingStyles.map((style, i) =>
<div key={i} style={{border: '1px solid', height: style.h}} />)
}
</div>
}
</StaggeredMotion>
Aka "the current spring's destination value is the interpolating value of the previous spring". Imagine a spring dragging another. Physics, it works!
Required function. Don't forget the "s"!
previousInterpolatedStyles
: the previously interpolating (array of) styles (undefined
at first render, unless defaultStyles
is provided).
Return: must return an array of Style
s containing the destination values, e.g. [{x: spring(10)}, {x: spring(20)}]
.
Optional. Similar to Motion
's defaultStyle
, but an array of them.
Required function. Similar to Motion
's children
, but accepts the array of interpolated styles instead, e.g. [{x: 5}, {x: 6.4}, {x: 8.1}]
Helps you to do mounting and unmounting animation.
You have items a
, b
, c
, with their respective style configuration, given to TransitionMotion
's styles
. In its children
function, you're passed the three interpolated styles as params; you map over them and produce three components. All is good.
During next render, you give only a
and b
, indicating that you want c
gone, but that you'd like to animate it reaching value 0
, before killing it for good.
Fortunately, TransitionMotion
has kept c
around and still passes it into the children
function param. So when you're mapping over these three interpolated styles, you're still producing three components. It'll keep interpolating, while checking c
's current value at every frame. Once c
reaches the specified 0
, TransitionMotion
will remove it for good (from the interpolated styles passed to your children
function).
This time, when mapping through the two remaining interpolated styles, you'll produce only two components. c
is gone for real.
const Demo = React.createClass({
getInitialState() {
return {
items: [{key: 'a', size: 10}, {key: 'b', size: 20}, {key: 'c', size: 30}],
};
},
componentDidMount() {
this.setState({
items: [{key: 'a', size: 10}, {key: 'b', size: 20}], // remove c.
});
},
willLeave() {
// triggered when c's gone. Keeping c until its width/height reach 0.
return {width: spring(0), height: spring(0)};
},
render() {
return (
<TransitionMotion
willLeave={this.willLeave}
styles={this.state.items.map(item => ({
key: item.key,
style: {width: item.size, height: item.size},
}))}>
{interpolatedStyles =>
// first render: a, b, c. Second: still a, b, c! Only last one's a, b.
<div>
{interpolatedStyles.map(config => {
return <div key={config.key} style={{...config.style, border: '1px solid'}} />
})}
</div>
}
</TransitionMotion>
);
},
});
First, two type definitions to ease the comprehension.
TransitionStyle
: an object of the format {key: string, data?: any, style: Style}
.
key
: required. The ID that TransitionMotion
uses to track which configuration is which across renders, even when things are reordered. Typically reused as the component key
when you map over the interpolated styles.
data
: optional. Anything you'd like to carry along. This is so that when the previous section example's c
disappears, you still get to access c
's related data, such as the text to display along with it.
style
: required. The actual starting style configuration, similar to what you provide for Motion
's style
. Maps keys to either a number or an OpaqueConfig
returned by spring()
.
TransitionPlainStyle
: similar to above, except the style
field's value is of type PlainStyle
, aka an object that maps to numbers.
Required. Accepts either:
an array of TransitionStyle
configs, e.g. [{key: 'a', style: {x: spring(0)}}, {key: 'b', style: {x: spring(10)}}]
.
a function similar to StaggeredMotion
, taking the previously interpolating styles (undefined
at first call, unless defaultStyles
is provided), and returning the previously mentioned array of configs. You can do staggered mounting animation with this.
Optional. Similar to the other components' defaultStyle
/defaultStyles
.
Required function. Similar to other two components' children
. Receive back an array similar to what you provided for defaultStyles
, only that each style
object's number value represent the currently interpolating value.
Optional. Defaults to () => null
. The magic sauce property.
styleThatLeft
: the e.g. {key: ..., data: ..., value: ...}
object from the styles
array, identified by key
, that was present during a previous render, and that is now absent, thus triggering the call to willLeave
.
Return: null
to indicate you want the TransitionStyle
gone immediately. A Style
object to indicate you want to reach transition to the specified value(s) before killing the TransitionStyle
.
Optional. Defaults to styleThatEntered => stripStyle(styleThatEntered.style)
. Where stripStyle
turns {x: spring(10), y: spring(20)}
into {x: 10, y: 20}
.
styleThatEntered
: similar to willLeave
's, except the TransitionStyle
represents the object whose key
value was absent during the last render
, and that is now present.
Return: a defaultStyle
-like PlainStyle
configuration, e.g. {x: 0, y: 0}
, that serves as the starting values of the animation. Under this light, the default provided means "a style config that has the same starting values as the destination values".
Note that willEnter
and defaultStyles
serve different purposes. willEnter
only triggers when a previously inexistent TransitionStyle
inside styles
comes into the new render.
Hard-coded duration goes against fluid interfaces. If your animation is interrupted mid-way, you'd get a weird completion animation if you hard-coded the time. That being said, in the demo section there's a great Spring Parameters Chooser for you to have a feel of what spring is appropriate, rather than guessing a duration in the dark.
TransitionMotion
container itself?You don't. Unless you put it in another TransitionMotion
...
See StaggeredMotion
ref
doesn't work in the children function.React string refs won't work:
<Motion style={...}>{currentValue => <div ref="stuff" />}</Motion>
This is how React works. Here's the callback ref solution.
FAQs
A spring that solves your animation problems.
We found that react-motion demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.