Skip to main content

Animating properties

Animation is all about how properties change over time. Let's start with a simple example, let's say we want to create a fade in animation.

If we want to fade the text in over 20 frames, we need to gradually change the opacity style over time so that it goes from 0 to 1.

tsx
export const MyVideo = () => {
const frame = useCurrentFrame();
 
const opacity = frame >= 20 ? 1 : frame / 20;
 
return (
<div
style={{
flex: 1,
textAlign: "center",
fontSize: "7em",
opacity: opacity,
}}
>
Hello World!
</div>
);
};
tsx
export const MyVideo = () => {
const frame = useCurrentFrame();
 
const opacity = frame >= 20 ? 1 : frame / 20;
 
return (
<div
style={{
flex: 1,
textAlign: "center",
fontSize: "7em",
opacity: opacity,
}}
>
Hello World!
</div>
);
};

Using the interpolate helper function

Using the interpolate function can make animations more readable. The function takes 4 arguments:

  1. The input value
  2. The range values which the input can assume
  3. The range of values that you want to map the input to
  4. Optional settings
tsx
import { interpolate, useCurrentFrame } from "remotion";
 
export const MyVideo = () => {
const frame = useCurrentFrame();
 
const opacity = interpolate(frame, [0, 20], [0, 1], {
extrapolateRight: "clamp",
});
 
return (
<div
style={{
flex: 1,
textAlign: "center",
fontSize: "7em",
opacity: opacity,
}}
>
Hello World!
</div>
);
};
tsx
import { interpolate, useCurrentFrame } from "remotion";
 
export const MyVideo = () => {
const frame = useCurrentFrame();
 
const opacity = interpolate(frame, [0, 20], [0, 1], {
extrapolateRight: "clamp",
});
 
return (
<div
style={{
flex: 1,
textAlign: "center",
fontSize: "7em",
opacity: opacity,
}}
>
Hello World!
</div>
);
};

In this example, we map the frames 0 to 20 to their opacity values (0, 0.05, 0.1, 0.15 ...) and use the extrapolateRight setting to clamp the output so that it never becomes bigger than 1.

Using spring animations

Spring animations are a beautiful way to put things into motion and make them natural. Remotion includes a helper function to make spring animations easy! This time, let's animate the scale of the text.

tsx
import { spring, useCurrentFrame, useVideoConfig } from "remotion";
 
export const MyVideo = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
 
const scale = spring({
fps,
from: 0,
to: 1,
frame,
});
 
return (
<div
style={{
flex: 1,
textAlign: "center",
fontSize: "7em",
}}
>
<div style={{ transform: `scale(${scale})` }}>Hello World!</div>
</div>
);
};
tsx
import { spring, useCurrentFrame, useVideoConfig } from "remotion";
 
export const MyVideo = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
 
const scale = spring({
fps,
from: 0,
to: 1,
frame,
});
 
return (
<div
style={{
flex: 1,
textAlign: "center",
fontSize: "7em",
}}
>
<div style={{ transform: `scale(${scale})` }}>Hello World!</div>
</div>
);
};

You should see the text 'jump in'. The default spring configuration leads to a little bit of overshoot, meaning the text will bounce a little bit. See the reference page about the spring() function to learn how to customize your spring animations.

Always animate using useCurrentFrame()

caution

Watch out for flickering issues during rendering that arise if you write animations that are not driven by useCurrentFrame() - for example CSS transitions.

Read more about how Remotion's rendering works - understanding it will help you avoid issues down the road.