Animation
Motion for React offers a number of ways to animate your UI. Scaling from extremely simple prop-based animations, to more complex orchestration.
Basic animations
You'll perform almost all animations on a <motion />
component. This is basically a DOM element with motion superpowers.
For basic animations, you can update values on the animate
prop:
When any value in its animate prop changes, the component will automatically animate to the new target.
Animatable values
Motion can animate any CSS value, even those that can't be animated by browsers, like mask-image
. It supports:
Numbers:
0
,100
etc.Strings containing numbers:
"0vh"
,"10px"
etc.Colors: Hex, RGBA, HSLA.
Complex strings containing multiple numbers and/or colors (like
box-shadow
).display: none/block
andvisibility: hidden/visible
.
Value type conversion
In general, values can only be animated between two of the same type (i.e "0px"
to "100px"
).
However, x
, y
, width
, height
, top
, left
, right
and bottom
can animate between different value types.
Additionally, hex, RGBA and HSLA can be animated between on another.
Transforms
Unlike CSS, Motion can animate every transform axis independently:
Translate:
x
,y
,z
Scale:
scale
,scaleX
,scaleY
Rotate:
rotate
,rotateX
,rotateY
,rotateZ
Skew:
skew
,skewX
,skewY
Perspective:
transformPerspective
motion
components have enhanced style
props, allowing you to set individual transforms:
Animating transforms independently provides great flexibility, especially around gestures.
Independent transforms perform great, but Motion's hybrid engine also uniquely offers hardware acceleration by setting transform
directly.
SVG note: For SVG components, x
and y
attributes can be set using attrX
and attrY
.
Transform origin
transform-origin
has three shortcut values that can be set and animated individually:
originX
originY
originZ
If set as numbers, originX
and Y
default to a progress value between 0
and 1
. originZ
defaults to pixels.
CSS variables
Motion for React can animate the value of CSS variables, and also use CSS variables as animation targets.
Animating CSS variables
Sometimes it's convenient to be able to animate a CSS variable to animate many children:
Note: Animating the value of a CSS variable always triggers paint, therefore it can be more performant to use MotionValue
s to setup this kind of animation.
CSS variables as animation targets
HTML motion
components accept animation targets with CSS variables:
SVG line drawing
Line drawing animations can be created with many different SVG elements using three special properties: pathLength
, pathSpacing
and pathOffset
.
All three are set as a progress value between 0
and 1
, 1
representing the total length of the path.
Path animations are compatible with circle
, ellipse
, line
, path
, polygon
, polyline
and rect
elements.
Transitions
By default, Motion will create appropriate transitions for snappy animations based on the type of value being animated.
For instance, physical properties like x
or scale
are animated with spring physics, whereas values like opacity
or color
are animated with duration-based easing curves.
However, you can define your own animations via the transition
prop.
Enter animations
When a motion
component is first created, it'll automatically animate to the values in animate
if they're different from those initially rendered, which you can either do via CSS or via the initial
prop.
You can also disable the enter animation entirely by setting initial={false}
. This will make the element render with the values defined in animate
.
Exit animations
You can also easily animate elements as they exit the DOM.
In React, when a component is removed, it's usually removed instantly. Motion provides the AnimatePresence
component which keeps elements in the DOM while they perform an exit
animation.
Keyframes
Values in animate
can be set as a series of keyframes. This will animate through each value in sequence.
We can use a value's current state as the initial keyframe by setting it to null
.
This way, if a keyframe animation is interrupting another animation, the transition will feel more natural.
By default, each keyframe is spaced naturally throughout the animation. You can override this by setting the times
option via transition
.
times
is an array of progress values between 0
and 1
, defining where in the animation each keyframe should be positioned.
Gesture animations
Motion for React has shortcut props for animating to/from a target when a gesture starts/ends.
It supports hover
, tap
, drag
, focus
and inView
.
Variants
Setting animate
as a target is useful for simple, single-element animations. But sometimes we want to orchestrate animations that propagate throughout the DOM. We can do so with variants.
Variants are a set of named targets.
They're passed to motion
components via the variants
prop:
These variants can now be referred to by a label, wherever you can define an animation target:
You can also define multiple variants via an array:
Propagation
This is already useful for reusing and combining animation targets. But it becomes powerful for orchestrating animations throughout trees.
Variants will flow down through motion
components. So in this example when the ul
enters the viewport, all of its children with a "visible" variant will also animate in:
Orchestration
By default, this children animations will start simultaneously with the parent. But with variants we gain access to new transition
props like when
, delayChildren
, staggerChildren
and staggerDirection
.
Dynamic variants
Each variant can be defined as a function that resolves when a variant is made active.
These functions are provided a single argument, which is passed via the custom
prop:
This way, variants can be resolved differently for each animating element.
Animation controls
Declarative animations are ideal for most UI interactions. But sometimes we need to take manual control over animation playback.
The useAnimate
hook can be used for:
Animating any HTML/SVG element (not just
motion
components).Complex animation sequences.
Controlling animations with
time
,speed
,play()
,pause()
and other playback controls.
Animate content
By passing a MotionValue
as the child of a motion
component, it will render its latest value in the HTML.
This is more performant than setting React state as the motion
component will set innerHTML
directly.