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
When you move, rotate, or resize a motion component (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: "anticipate".
export function Example() {
return (
<motion.div
animate={{ rotate: 45, scale: 1.5 }}
transition={{ ease: "anticipate", duration: 2 }}
/>
);
}
transition property – An easing curveIt lets the div move back a little — in anticipation of what’s about to happen.
Easing curves like this one (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 which is the spring’s damping ratio. The lower the value (the default is 10), the more it will oscillate. Here I made it 3:
export function Example() {
return (
<motion.div
animate={{ scale: 1.5 }}
transition={{ type: "spring", damping: 3 }}
/>
);
}
transition property – Spring settingsRepeat 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 thrice (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 CodeSandbox, whichever comes first).
export function Example() {
return (
<motion.div
animate={{ rotate: 360 }}
transition={{
ease: "linear",
duration: 2,
repeat: Infinity,
delay: 1
}}
/>
);
}
transition property – Repeat after a delayWith 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 code below, the div will wait 1 second between every 2-second rotation:
export function Example() {
return (
<motion.div
animate={{ rotate: 360 }}
transition={{
duration: 2,
repeat: Infinity,
delay: 1,
repeatDelay: 1
}}
/>
);
}
transition property – Delay between repetitionsrepeatDelay 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 (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 in an earlier Framer Motion version, which was fitting, as you can see in this example:
export function Example() {
return (
<motion.div
style={{
width: 150,
height: 150,
borderRadius: 30,
backgroundColor: "#fff",
y: -90
}}
animate={{ y: 70, rotate: 360 }}
transition={{
delay: 1,
duration: 2,
ease: [0.075, 0.82, 0.165, 1],
repeat: Infinity,
repeatType: "reverse"
}}
/>
);
}
transition property – Reverse animation with Bézier curveBé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 changing 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 defines how all the 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 Example() {
return (
<motion.div
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
}
}}
/>
);
}
transition property – Separate transition values 1When 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 Example() {
return (
<motion.div
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 }
}}
/>
);
}
transition property – Separate Transition values 2Including transition settings
Let’s say you have a rotating box that you want to grow when you hover over it. You can use a whileHover for the hover animation (one of the gesture animations).
That code could look like this, a continuing rotate animation with a transition that makes it "linear", with a duration of 2 seconds and a repeat of Infinity.
export function Example() {
return (
<motion.div
animate={{ rotate: 360 }}
transition={{ ease: "linear", duration: 2, repeat: Infinity }}
whileHover={{ scale: 2 }}
/>
);
}
transition property – Including Transition settings – First tryAnd the whileHover doubles the size of the div. The only problem is: The whileHover animation is now also 2 seconds, and it also repeats.
You can solve this by including the transition settings with an animation. Here I include the settings for the rotation inside animate so that the whileHover can fall back to its default settings.
export function Example() {
return (
<motion.div
animate={{
rotate: 360,
transition: { ease: "linear", duration: 3, repeat: Infinity }
}}
whileHover={{ scale: 2 }}
/>
);
}
transition property – Including Transition settings – Fixed
2 thoughts on “The Transition Property”
What’s the difference if I use transition inside animate object and transition outside animate ?
This is what I am thinking right now: if I use transition outside animate object then it means this is global and it will affect all its animation. Correct me if I am wrong.
Yes, that’s it. When you just put values in the
transitionproperty, it will affect all the animations (what’s inanimate, gesture animations, exit animations, layout animations, etc.)To tweak a certain animation, you have two options: You add ‘transition’ to the animation itself, like here:
This transition is then applied to all the properties your animating:
rotateandscale.Or you define inside the transition object how a certain property should animate, like here:
Here,
scalewill use a spring animation instead of the globally defined easing.