Animating properties
Animation works by changing properties over time.
Let's create a simple fade in animation.
If we want to fade the text in over 60 frames, we need to gradually change the opacity
over time so that it goes from 0 to 1.
FadeIn.tsxtsx
export constFadeIn = () => {constframe =useCurrentFrame ();constopacity =Math .min (1,frame / 60);return (<AbsoluteFill style ={{justifyContent : "center",alignItems : "center",backgroundColor : "white",fontSize : 80,}}><div style ={{opacity :opacity }}>Hello World!</div ></AbsoluteFill >);};
FadeIn.tsxtsx
export constFadeIn = () => {constframe =useCurrentFrame ();constopacity =Math .min (1,frame / 60);return (<AbsoluteFill style ={{justifyContent : "center",alignItems : "center",backgroundColor : "white",fontSize : 80,}}><div style ={{opacity :opacity }}>Hello World!</div ></AbsoluteFill >);};
Using the interpolate helper function
Using the interpolate()
function can make animations more readable.
The function takes 4 arguments:
- The input value
- The range values which the input can assume
- The range of values that you want to map the input to
- Optional settings
tsx
import {interpolate ,useCurrentFrame } from "remotion";export constMyVideo = () => {constframe =useCurrentFrame ();constopacity =interpolate (frame , [0, 60], [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 constMyVideo = () => {constframe =useCurrentFrame ();constopacity =interpolate (frame , [0, 60], [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 60 to their opacity values (0, 0.0166, 0.033, 0.05 ...
) and use the extrapolateRight
setting to clamp the output so that it never becomes bigger than 1.
Using spring animations
Spring animations are a natural animation primitive. By default, they animate from 0 to 1 over time. This time, let's animate the scale of the text.
tsx
import {spring ,useCurrentFrame ,useVideoConfig } from "remotion";export constMyVideo = () => {constframe =useCurrentFrame ();const {fps } =useVideoConfig ();constscale =spring ({fps ,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 constMyVideo = () => {constframe =useCurrentFrame ();const {fps } =useVideoConfig ();constscale =spring ({fps ,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 documentation page for spring()
to learn how to customize it.
Always animate using useCurrentFrame()
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.