The Transition Property
With the animate
property, you define which properties should animate and to what value. How things should move — what you might call the ‘animation options’ — those you set with another property, transition
.
- An easing curve
- Spring settings
- Repeat and delay
- Delay between repetitions
- Repeat type and Bézier curves
- Transition settings per property
An easing curve
When you move, rotate, or resize a frame or motion element (animating physical properties), it will, by default, happen with a spring animation. However, you can select a different type. Here I picked one of the easing curves: "
.
export function An_easing_curve(Component): ComponentType {
return (props) => {
return (
<Component
{...props}
animate={{ rotate: 45, scale: 1.5 }}
transition={{ ease: "anticipate", duration: 2 }}
/>
)
}
}
It lets the frame move back a little — in anticipation of what’s about to happen.
Easing curves like this one (called tween curves) can also have a duration
. I picked 2
seconds. When you omit
, you’ll get the default value: 0.3
seconds.
Transition, transition
, Tween, duration
Spring settings
Let’s go back to that default spring. You can adjust a bunch of its settings; one of them is the spring’s damping
ratio. The lower the value (the default is 10
), the more it will oscillate. Here I changed it to 3
:
export function Spring_settings(Component): ComponentType {
return (props) => {
return (
<Component
{...props}
animate={{ scale: 1.5 }}
transition={{ type: "spring", damping: 3 }}
/>
)
}
}
Repeat and delay
Add a repeat
value to make an animation run more than once. For instance, with a repeat
of 2
, the animation will run three times (two extra after the initial one).
Or you set it to Infinity
and have it repeat till the end of time (or until you close the preview, whichever comes first).
export function Repeat_after_delay(Component): ComponentType {
return (props) => {
return (
<Component
{...props}
animate={{ rotate: 360 }}
transition={{
ease: "linear",
duration: 2,
repeat: Infinity,
delay: 1,
}}
/>
)
}
}
With delay
, you add a pause before the start of the animation (also in seconds). It will only delay the beginning of the initial animation; and not insert pauses between the repetitions.
I gave this animation a "linear"
easing to get a steady rotation at a constant speed.
Delay between repetitions
You can also add a pause between the repetitions of a repeat
, with another setting: repeatDelay
.
With the below override, the frame will wait 1
second between every 2
-second rotation:
export function Delay_between_repetitions(Component): ComponentType {
return (props) => {
return (
<Component
{...props}
animate={{ rotate: 360 }}
transition={{
duration: 2,
repeat: Infinity,
delay: 1,
repeatDelay: 1,
}}
/>
)
}
}
repeatDelay
works with all three repeat types (more about those next).
Repeat type and Bézier curves
Your animation can repeat in a few different ways. The default repeatType
(used in the former examples) is "loop"
: the animation will just start over. The other two, "mirror"
and "reverse"
, make it go back and forth.
Repeat types | |
---|---|
"loop" | The default type. The animation simply runs again. |
"mirror" | Flips the from and to values. The animation runs forward, backward, then forward again, etc. (This was called flip in earlier versions.) |
"reverse" | Does the same but also reverses the animation curve. So when the animation starts slowly, the reverse animation will end slowly. |
"reverse"
was called yoyo
previously, which was fitting, as you can see in this example:
export function Reverse_with_Bezier(Component): ComponentType {
return (props) => {
const { style, ...rest } = props
return (
<Component
{...rest}
style={{ ...style, y: -90 }}
animate={{ y: 70, rotate: 360 }}
transition={{
delay: 1,
duration: 2,
ease: [0.075, 0.82, 0.165, 1],
repeat: Infinity,
repeatType: "reverse",
}}
/>
)
}
}
Bézier curves
Typically, you give ease
one of the (11) predefined easing curves, like "
, "
, or "linear"
. But you can also give it an array with the four numbers that define a Bézier curve.
In this example, I used a stronger ease-out ([0.075, 0.82, 0.165, 1]
) to make the yo-yo effect even more noticeable.
Repeating spring animations
Since the change to this new repeatType
syntax (in Framer Motion 2.5), you can also repeat spring animations.
Matt Perry posted this project as an example:
export default function App() {
return (
<motion.div
className="handle"
initial={{ x: -200 }}
animate={{ x: 200 }}
transition={{
type: "spring",
repeat: Infinity,
repeatType: "mirror",
repeatDelay: 0.1
}}
/>
);
}
Transition settings per property
The transition
property is a bit like the animation options you could give a layer in Classic: it defines how all the frame’s properties will animate. However, you can override that global setting and provide distinct values for one or more properties, like here for rotate
:
Example 1
export function Separate_transition_values_1(Component): ComponentType {
return (props) => {
const { style, ...rest } = props
return (
<Component
{...rest}
style={{ ...style, y: -90 }}
animate={{
y: 70,
rotate: 360,
}}
transition={{
delay: 1,
duration: 2,
ease: [0.075, 0.82, 0.165, 1],
repeat: Infinity,
repeatType: "reverse",
rotate: {
delay: 1,
duration: 2,
ease: "linear",
repeat: Infinity,
},
}}
/>
)
}
}
When defining separate transition settings for a property, the global values will be ignored. That’s why the rotate
animation now defaults back to a repeat type of "loop"
(and also why we need to give it the same 1
-second delay
and 2
-second duration
).
Example 2
In this second example, I added a spring animation to a smaller scale
of 0.8
. Again, the globally set values are ignored (repeat
, repeatType
, …), so this scale animation runs just once.
export function Separate_transition_values_2(Component): ComponentType {
return (props) => {
const { style, ...rest } = props
return (
<Component
{...rest}
style={{ ...style, y: -90 }}
animate={{
y: 70,
rotate: 360,
scale: 0.8,
}}
transition={{
delay: 1,
duration: 2,
ease: [0.075, 0.82, 0.165, 1],
repeat: Infinity,
repeatType: "reverse",
rotate: {
delay: 1,
duration: 2,
ease: "linear",
repeat: Infinity,
},
scale: { delay: 1, type: "spring", damping: 3 },
}}
/>
)
}
}