Skip to main content

Custom presentations

This page describes how to create your own custom effect for <TransitionSeries>.

Concept

A presentation is a higher order component which wraps around the entering slide as well as the exiting slide and which implements an effect based on three parameters:

The current presentationProgress, influenced by the timing of the transition


The presentationDirection, either entering or exiting


The presentationDurationInFrames (available from v4.0.153)
4
Additional developer-defined passedProps

Boilerplate

A custom presentation is a function which returns an object of type TransitionPresentation.
It is an object with a React component (component) and React props which are passed to the component as passedProps.

custom-presentation.tsx
import type {TransitionPresentation} from '@remotion/transitions'; type CustomPresentationProps = { width: number; height: number; }; export const customPresentation = ( props: CustomPresentationProps, ): TransitionPresentation<CustomPresentationProps> => { return {component: StarPresentation, props}; };

The component is a React component which receives the following props:

children: The markup to wrap around


presentationDirection: Either "entering" or "exiting"


presentationProgress: A number between 0 and 1 which represents the progress of the transition.


passedProps: The custom props passed to the presentation



StarPresentation.tsx
import type {TransitionPresentationComponentProps} from '@remotion/transitions'; import {AbsoluteFill} from 'remotion'; const StarPresentation: React.FC< TransitionPresentationComponentProps<CustomPresentationProps> > = ({children, presentationDirection, presentationProgress, passedProps}) => { return ( <AbsoluteFill> <AbsoluteFill>{children}</AbsoluteFill> </AbsoluteFill> ); };

Example

The following example implements a star mask transition:

Based on the passedProps height and width , the inner radius of the star is calculated that will completely fill the canvas.


Using @remotion/shapes, an SVG path is calculated, and grown from zero to the full size of the canvas.
3
The presentationProgress is used to interpolate the shape size.
4
@remotion/paths is used to center the star in the middle of the canvas.


A clipPath is used to clip the entering slide. Inside the container, the children get rendered.


The effect is disabled if presentationDirection is set to "exiting"



StarPresentation.tsx
import {getBoundingBox, translatePath} from '@remotion/paths'; import {makeStar} from '@remotion/shapes'; import type {TransitionPresentationComponentProps} from '@remotion/transitions'; import React, {useMemo, useState} from 'react'; import {AbsoluteFill, random} from 'remotion'; export type CustomPresentationProps = { width: number; height: number; }; const StarPresentation: React.FC< TransitionPresentationComponentProps<CustomPresentationProps> > = ({children, presentationDirection, presentationProgress, passedProps}) => { const finishedRadius = Math.sqrt(passedProps.width ** 2 + passedProps.height ** 2) / 2; const innerRadius = finishedRadius * presentationProgress; const outerRadius = finishedRadius * 2 * presentationProgress; const {path} = makeStar({ innerRadius, outerRadius, points: 5, }); const boundingBox = getBoundingBox(path); const translatedPath = translatePath( path, passedProps.width / 2 - boundingBox.width / 2, passedProps.height / 2 - boundingBox.height / 2, ); const [clipId] = useState(() => String(random(null))); const style: React.CSSProperties = useMemo(() => { return { width: '100%', height: '100%', clipPath: presentationDirection === 'exiting' ? undefined : `url(#${clipId})`, }; }, [clipId, presentationDirection]); return ( <AbsoluteFill> <AbsoluteFill style={style}>{children}</AbsoluteFill> {presentationDirection === 'exiting' ? null : ( <AbsoluteFill> <svg> <defs> <clipPath id={clipId}> <path d={translatedPath} fill="black" /> </clipPath> </defs> </svg> </AbsoluteFill> )} </AbsoluteFill> ); };

Example usage:

MyComp.tsx
export const MyComp: React.FC = () => { const {width, height} = useVideoConfig(); return ( <TransitionSeries> <TransitionSeries.Sequence durationInFrames={70}> <Letter color="orange">A</Letter> </TransitionSeries.Sequence> <TransitionSeries.Transition presentation={customPresentation({width, height})} timing={springTiming({ durationInFrames: 45, config: { damping: 200, }, durationRestThreshold: 0.0001, })} /> <TransitionSeries.Sequence durationInFrames={60}> <Letter color="pink">B</Letter> </TransitionSeries.Sequence> </TransitionSeries> ); };

References

See the source code for already implemented presentations for a useful reference.

See also