Files
Sportstime/marketing-videos/src/components/KineticText.tsx
Trey t 5f5b137e64 feat: add marketing video mode and Remotion marketing video project
Add debug-only Marketing Video Mode toggle that enables hands-free
screen recording across the app: auto-scrolling Featured Trips carousel,
auto-filling trip wizard, smooth trip detail scrolling via CADisplayLink,
and trip options auto-sort with scroll.

Add Remotion marketing video project with 6 scene compositions using
image sequences extracted from screen recordings, varied phone entrance
animations, and deduped frames for smooth playback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:07:35 -06:00

72 lines
1.7 KiB
TypeScript

import React from "react";
import { interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";
import { THEME } from "../theme";
type KineticTextProps = {
words: string[];
fontSize?: number;
color?: string;
delay?: number;
staggerFrames?: number;
textShadow?: string;
textAlign?: "center" | "left" | "right";
lineHeight?: number;
};
export const KineticText: React.FC<KineticTextProps> = ({
words,
fontSize = 72,
color = THEME.colors.white,
delay = 0,
staggerFrames = 3,
textShadow = THEME.textShadow,
textAlign = "center",
lineHeight = 1.2,
}) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
return (
<div
style={{
display: "flex",
flexWrap: "wrap",
justifyContent: textAlign === "center" ? "center" : "flex-start",
gap: `0 ${fontSize * 0.25}px`,
fontFamily: THEME.font.heading,
fontSize,
fontWeight: 800,
color,
textShadow,
lineHeight,
}}
>
{words.map((word, i) => {
const wordDelay = delay + i * staggerFrames;
const entrance = spring({
frame: frame - wordDelay,
fps,
config: { damping: 14, mass: 0.6, stiffness: 140 },
});
const opacity = interpolate(entrance, [0, 1], [0, 1]);
const translateY = interpolate(entrance, [0, 1], [30, 0]);
return (
<span
key={`${word}-${i}`}
style={{
display: "inline-block",
opacity,
transform: `translateY(${translateY}px)`,
}}
>
{word}
</span>
);
})}
</div>
);
};