This is how it looks like.
The "Create of the Week" text and the badges on the bottom use this component. Here's the component:
import { translateY } from "@remotion/animation-utils";
import { Children, CSSProperties, ReactNode } from "react";
import { Easing, interpolate, useCurrentFrame } from "remotion";
type SlideRevealProps = {
className?: string,
style?: CSSProperties,
speedFrame?: number,
direction?: "up" | "down",
children: ReactNode,
}
const SlideReveal = ({ className: classNames, style, speedFrame = 15, direction = "down", children }: SlideRevealProps) => {
const containerClassNames = classNames ? `flex gap-4 ${classNames}` : "flex gap-4";
const frame = useCurrentFrame();
return (
<div className={containerClassNames} style={style}>
{
Children.map(children, (child, index) => {
const startFrame = index * speedFrame; // Each child starts animating 15 frames apart
const opacity = interpolate(
frame,
[startFrame, startFrame + speedFrame], // Animate opacity over 15 frames
[0, 1],
{ easing: Easing.out(Easing.ease), extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }
);
const trY = interpolate(
frame,
[startFrame, startFrame + speedFrame], // Animate translateY over 15 frames
[direction === 'down' ? -20 : 20, 0],
{ easing: Easing.out(Easing.ease), extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }
);
return (
<div key={index} style={{ opacity, transform: translateY(trY) }}>
{child}
</div>
);
})
}
</div>
)
}
export default SlideReveal
Basically, what this component does is:
Iterate over each
children
with theirindex
.Interpolate on
translateY
andopacity
based on theirindex
andframe
.