← back to Prestige Car Wash Video
src/Card.tsx
72 lines
import { AbsoluteFill, useCurrentFrame, interpolate, Easing, spring, useVideoConfig } from 'remotion';
import type { Section } from './sections';
const FONT = 'Inter, "SF Pro Display", system-ui, -apple-system, sans-serif';
// Full-screen title card used for intro / act dividers / outro.
export const Card: React.FC<{ s: Section }> = ({ s }) => {
const f = useCurrentFrame();
const { fps } = useVideoConfig();
const pop = spring({ frame: f, fps, config: { damping: 200, mass: 0.7 } });
const y = interpolate(pop, [0, 1], [30, 0]);
const eyebrowO = interpolate(f, [2, 16], [0, 1], { extrapolateRight: 'clamp' });
const subO = interpolate(f, [14, 30], [0, 1], { extrapolateRight: 'clamp' });
const lineW = interpolate(f, [10, 34], [0, 320], { easing: Easing.out(Easing.cubic), extrapolateRight: 'clamp' });
return (
<AbsoluteFill style={{ alignItems: 'center', justifyContent: 'center' }}>
<div style={{ textAlign: 'center', transform: `translateY(${y}px)` }}>
<div
style={{
opacity: eyebrowO,
fontFamily: FONT,
fontWeight: 700,
fontSize: 26,
letterSpacing: 8,
textTransform: 'uppercase',
color: s.accent,
}}
>
{s.act}
</div>
<div
style={{
opacity: pop,
marginTop: 22,
fontFamily: FONT,
fontWeight: 900,
fontSize: 108,
lineHeight: 1.0,
color: '#f4f9ff',
textShadow: '0 10px 50px rgba(0,0,0,0.5)',
}}
>
{s.title}
</div>
<div
style={{
width: lineW,
height: 4,
borderRadius: 4,
background: s.accent,
margin: '30px auto 0',
}}
/>
<div
style={{
opacity: subO,
marginTop: 26,
fontFamily: FONT,
fontWeight: 500,
fontSize: 34,
color: '#c2d2e8',
}}
>
{s.sub}
</div>
</div>
</AbsoluteFill>
);
};