import {
AbsoluteFill,
Img,
staticFile,
useCurrentFrame,
useVideoConfig,
interpolate,
spring,
Sequence,
Easing,
} from "remotion";
// Cinematic letterbox bars
const LetterBox: React.FC = () => (
<>
>
);
// Scan lines for that heist movie feel
const ScanLines: React.FC<{ opacity?: number }> = ({ opacity = 0.1 }) => {
const frame = useCurrentFrame();
const offset = (frame * 2) % 4;
return (
);
};
// Glitch effect text
const GlitchText: React.FC<{
children: string;
style?: React.CSSProperties;
}> = ({ children, style }) => {
const frame = useCurrentFrame();
const glitchOffset = Math.sin(frame * 0.5) * 2;
const shouldGlitch = frame % 30 < 3;
return (
{shouldGlitch && (
<>
{children}
{children}
>
)}
{children}
);
};
// Scene 1: The Setup - "They took something from you"
const SetupScene: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const fadeIn = interpolate(frame, [0, fps * 0.5], [0, 1], {
extrapolateRight: "clamp",
});
const textReveal = interpolate(frame, [fps * 0.5, fps * 2], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
const typewriterLength = Math.floor(textReveal * 28);
const fullText = "They took something from you";
const displayText = fullText.slice(0, typewriterLength);
// Flicker effect
const flicker = frame % 60 < 2 ? 0.3 : 1;
return (
{/* Dramatic spotlight */}
{/* Main text */}
{displayText}
{/* Blinking cursor */}
{typewriterLength < fullText.length && (
_
)}
{/* Bottom text */}
);
};
// Scene 2: The Crew - Mood emojis as heist team
const CrewScene: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const crew = [
{ emoji: "😊", name: "THE OPTIMIST", color: "#10b981", role: "INFILTRATION" },
{ emoji: "😤", name: "THE MUSCLE", color: "#ef4444", role: "FIREPOWER" },
{ emoji: "🤔", name: "THE BRAINS", color: "#3b82f6", role: "STRATEGY" },
{ emoji: "😌", name: "THE COOL", color: "#8b5cf6", role: "EXTRACTION" },
];
return (
{/* Title */}
{/* Crew grid */}
{crew.map((member, i) => {
const delay = i * 8;
const memberProgress = spring({
frame: frame - delay,
fps,
config: { damping: 12, stiffness: 100 },
});
return (
{member.emoji}
{member.name}
{member.role}
);
})}
);
};
// Scene 3: The Plan - Blueprint style
const PlanScene: React.FC = () => {
const frame = useCurrentFrame();
const { fps, width, height } = useVideoConfig();
// Grid lines drawing animation
const gridProgress = interpolate(frame, [0, fps * 2], [0, 1], {
extrapolateRight: "clamp",
});
return (
{/* Blueprint grid */}
{/* Phone blueprint */}
{/* Target markers */}
{/* Entry point */}
ENTRY POINT
{/* Title */}
{/* Steps */}
{["DOWNLOAD", "TAP MOOD", "REPEAT"].map((step, i) => (
))}
);
};
// Scene 4: The Execution - Dramatic mood selection
const ExecutionScene: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const moods = ["😢", "😕", "😐", "🙂", "😊"];
const selectedIndex = 4; // Great mood
// Dramatic slow reveal
const revealProgress = interpolate(frame, [0, fps * 2], [0, 1], {
extrapolateRight: "clamp",
easing: Easing.out(Easing.cubic),
});
// Finger approaching
const fingerProgress = interpolate(frame, [fps * 2, fps * 3], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
// Selection flash
const selectFlash = frame > fps * 3 && frame < fps * 3.5;
return (
{/* Dramatic lighting */}
{selectFlash && (
)}
{/* Mood buttons */}
{moods.map((mood, i) => {
const isSelected = i === selectedIndex && frame > fps * 3;
const buttonProgress = interpolate(
revealProgress,
[i * 0.15, i * 0.15 + 0.3],
[0, 1],
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
);
return (
{mood}
);
})}
{/* Approaching finger/cursor */}
👆
{/* "ACQUIRED" text */}
{frame > fps * 3.2 && (
MOOD ACQUIRED
)}
);
};
// Scene 5: The Getaway - Success celebration
const GetawayScene: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const logoProgress = spring({
frame,
fps,
config: { damping: 10, stiffness: 80 },
});
// Vault door opening effect
const vaultOpen = interpolate(frame, [0, fps], [0, 1], {
extrapolateRight: "clamp",
easing: Easing.out(Easing.cubic),
});
return (
{/* Vault doors */}
{/* Bright light behind vault */}
{/* App icon revealed */}
Feels
TAKE BACK YOUR EMOTIONS
);
};
// Main composition - 25 seconds total
export const ConceptHMoodHeist: React.FC = () => {
const { fps } = useVideoConfig();
return (
);
};