Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
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
10
. For more advanced usage, see below.
Npm:
npm install react-motion
Bower:
bower install react-motion
1998 Script Tag:
<script src="path/to/react-motion/build/react-motion.js"></script>
(Module exposed as ReactMotion
)
Or build it yourself from the repo: git clone https://github.com/chenglou/react-motion.git && cd react-motion && npm install && npm run prerelease
For React-native, instead of require('react-motion')
, do require('react-motion/native')
.
(P.S. Don't forget to compile for production when you test your animation's performance!)
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
.
The library exports Motion
, StaggeredMotion
, TransitionMotion
, presets
, spring
and utils
.
spring: number -> ?[stiffness, damping] -> ConfigurationObject
(Note: not the Spring
component in version <0.3.0.)
The pervasive helper used to specify the how to animate to the destination value, e.g. spring(10, [120, 17])
returns an opaque configuration that describes "an animation to the value 10, with a physics spring's stiffness of 120 and damping of 17". spring(10)
without the spring configuration array defaults to [170, 26]
. See below for more usage and see here for a list of convenient configurations the library exports.
Props:
defaultStyle: ?Object
Optional. The value when the component first renders (ignored in subsequent renders). Accepts an object of arbitrary keys, mapping to initial values you want to animate, e.g. {x: 0, y: 10}
.
style: Object
Required. Must have the same keys throughout component's existence. Must have the same keys as defaultStyle
(if provided). Similar to defaultStyle
, but asks for a spring
configuration as the destination value: {x: spring(10), y: spring(20, [120, 17])}
.
If a plain number is provided rather than a spring
config, instead of giving an interpolated value in the children function param below, we'll jump straight to that number value.
children: Object -> ?ReactElement
Required function, which is passed an interpolated style object, e.g. {x: 5.2, y: 12.1}
. Must returns a React element to render.
<Motion defaultStyle={{x: 0}} style={{x: spring(10, [120, 17])}}>
{interpolatedStyle => <div>{interpolatedStyle.x}</div>}
</Motion>
When you want to animate a list of items, you can certainly create an array of Motion
s and animate each. However, you often want to "stagger" them, i.e. animate items in one after another with a delay. Hard-coding this duration goes against the very purpose of spring physics. Instead, here's a natural, physics-based alternative, where "the destination position of an item depends on the current position of another".
defaultStyles: ?Array<Object>
Optional. Similar to Motion
's defaultStyle
, except an array of styles.
styles: ?Array<Object> -> Array<Object>
Required function. Takes as argument the previous array of styles (which is undefined
at first render, unless defaultStyles
is provided!). Return the array of styles containing the destination values.
children: Array<Object> -> ?ReactElement
A 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}]
<StaggeredMotion
defaultStyles={[{x: 0}, {x: 10}, {x: 20}]}
styles={prevStyles => prevStyles.map((_, i) => {
return i === 0
? {x: spring(this.state.mouseX)} // first item follows mouse's x position
: prevStyles[i - 1]; // item i follow the position of the item before it, creating a natural staggering spring
})}>
{interpolatedStyles =>
<div>
{interpolatedStyles.map((style, i) =>
<div key={i} style={{left: style.x}} />
)}
</div>
}
</StaggeredMotion>
The magic component that helps you to do mounting and unmounting animation. Unlike React's TransitionGroup
, instead of retaining a few items in a list when they disappear, TransitionMotion
diffs on the shape of its styles
object prop.
The general idea
Let TransitionMotion
's styles
be {myKey1: {x: spring(30)}, myKey2: {x: spring(20)}}
. The interpolated styles passed to the children
function, after a moment, would be {myKey1: {x: 15.1}, myKey2: {x: 8.2}}
.
A few renders later, you kill myKey1
and its style config, i.e. pass the new styles
as {myKey2: {x: spring(20)}}
. TransitionMotion detects a missing key, but retains the key in the interpolated values as {myKey1: ..., myKey2: ...}
.
This is when TransitionMotion
calls the prop willLeave
that you provide, passing myKey2
as argument. You're asked to return a final style config (for example, {x: spring(50)}
) for myKey1
, representing the style values that, when interpolatedStyles.myKey1
reaches them, allows TransitionMotion
to truly kill myKey1
and its style config from the interpolated styles.
In summary: styles
is {k1: {x: spring(30)}, k2: {x: spring(20)}}
. Next render, styles
is {k2: {x: spring(20)}}
. The interpolated styles passed to children aren't affected, but remember that the k2: configReturnedFromWillLeave
(say, {x: spring(50)}
) part doesn't exist in the actual styles
anymore. Moments later, interpolated styles reach {k1: {x: 50}, k2: {x: 19.2}}
; it then re-renders, kills k1
and become {k2: {x: 19.2}}
. All this time, you're mapping over the interpolate styles and rendering two items, until the last render.
Similar but simpler logic for willEnter
.
defaultStyles: ?Object<string, Object>
Optional. Accepts an object of the format {myKey1: styleObject, myKey2: styleObject}
where each styleObject
is similar to Motion
's defaultStyle
. The keys must be unique non-number IDs (number keys in JS object screws with keys enumeration order, which is important when you map over it in children
function).
styles: Object | (?Object -> Object)
Required. Accepts an object similar to defaultStyles
, but where styleObject
has spring
configurations: {myKey1: {x: spring(10)}, myKey2: {y: spring(20)}}
. Alternatively, also accepts a function which takes a prevStyles
parameter (just like StaggeredMotion
; you can do staggered unmounting animation!), and returns the destination styles.
willEnter: (string, Object, Object, Object, Object) -> Object
Not a very helpful type definition...
Optional. Pass a function that takes the arguments (keyFromStylesThatJustEntered, correspondingStyleOfKey, styles, currentInterpolatedStyle, currentSpeed)
, and that returns a style object similar to a defaultStyle
.
Defaults to a function that returns correspondingStyleOfKey
, in this case {x: spring(20)}
.
willLeave: (string, Object, Object, Object, Object) -> Object
Optional. Pass a function that takes the arguments keyThatJustLeft, correspondingStyleOfKey, styles, currentInterpolatedStyle, currentSpeed)
and that return a style object containing some spring(...)
as the destination configuration.
Optional, defaults to correspondingStyleOfKey
, i.e. immediately killing the key from the interpolated values.
children: Object -> ?ReactElement
A required function. Similar to Motion
's children
, but accepts the object of interpolated styles instead.
const Demo = React.createClass({
getInitialState() {
return {
blocks: {
a: 'I am a',
b: 'I am b',
c: 'I am c',
},
};
},
getStyles() {
let configs = {};
Object.keys(this.state.blocks).forEach(key => {
configs[key] = {
opacity: spring(1),
text: this.state.blocks[key], // not interpolated
};
});
return configs;
},
// not used here! We don't add any new item
willEnter(key) {
return {
opacity: spring(0), // start at 0, gradually expand
text: this.state.blocks[key], // this is really just carried around so
// that interpolated values can still access the text when the key is gone
// from actual `styles`
};
},
willLeave(key, style) {
return {
opacity: spring(0), // make opacity teach 0, after which we can kill the key
text: style.text,
};
},
handleClick(key) {
const {...newBlocks} = this.state.blocks;
delete newBlocks[key];
this.setState({blocks: newBlocks});
},
render() {
return (
<TransitionMotion
styles={this.getStyles()}
willEnter={this.willEnter}
willLeave={this.willLeave}>
{interpolatedStyles =>
<div>
{Object.keys(interpolatedStyles).map(key => {
const {text, ...style} = interpolatedStyles[key];
return (
<div onClick={this.handleClick.bind(null, key)} style={style}>
{text}
</div>
);
})}
</div>
}
</TransitionMotion>
);
},
});
presets
Some tasteful, commonly used spring presets you can plug into your style
like so: {val: 10, config: presets.wobbly}
. See here.
utils
Since TransitionMotion
dictates styles
to be an object, manipulating keys could be a little more tedious than manipulating arrays. Here are the common scenarios' solutions:
{newKey: myConfigForThisKey, ...oldConfigs}
.{...oldConfigs, newKey: myConfigForThisKey}
.utils.reorderKeys
function.Note: object keys creation order is now guaranteed by the specs, except for integer keys, which follow ascending order and should not be used with TransitionMotion
. Fortunately, you can just add a letter to your key to turn them into "true" strings.
reorderKeys: (Object, Function) -> Object
utils.reorderKeys({a: 1, b: 2}, (keysArray) => ['b', 'a']) // gives {b: 2, a: 1}
Function
will receive, as arguments, the array of keys in Object
and should return a new array of keys (with e.g. order changed and/or keys removed). reorderKeys
will then return a new object of the same shape as object
, but with the keys in the order Function
dictated.
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.
0.3.0 (September 30th 2015)
FAQs
A spring that solves your animation problems.
The npm package react-motion receives a total of 0 weekly downloads. As such, react-motion popularity was classified as not popular.
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
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
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.