import { useCurrentFrame, useVideoConfig, interpolate, spring } from 'remotion';
import { C } from '../lib/colors';
import { rand, clampLerp, easeInOut } from '../lib/easings';
import { BEAT } from '../HeroVideo';
// Beat 2 — the wow moment.
//
// The collapsed prompt point at (960, 540) detonates RADIALLY into ~60
// glowing particles that scatter spherically, then magnetically snap into
// target slots along a SERVER SCHEMATIC. Particles are supporting players:
// small enough that the schematic — the thing being built — reads as the
// primary subject. Schematic strokes on IN PARALLEL with the convergence
// so the eye always has something to anchor to.
const PARTICLE_COUNT = 60;
const SERVER_W = 720;
const SERVER_H = 420;
const CX = 960;
const CY = 540;
function targetSlot(i: number) {
const N = PARTICLE_COUNT;
if (i < N / 2) {
// perimeter walk
const t = i / (N / 2);
const perim = 2 * (SERVER_W + SERVER_H);
const d = t * perim;
const left = CX - SERVER_W / 2;
const top = CY - SERVER_H / 2;
let px = left;
let py = top;
if (d < SERVER_W) { px = left + d; py = top; }
else if (d < SERVER_W + SERVER_H) { px = left + SERVER_W; py = top + (d - SERVER_W); }
else if (d < 2 * SERVER_W + SERVER_H) { px = left + SERVER_W - (d - SERVER_W - SERVER_H); py = top + SERVER_H; }
else { px = left; py = top + SERVER_H - (d - 2 * SERVER_W - SERVER_H); }
return { x: px, y: py };
}
// Inside the box: three tool rows
const j = i - N / 2;
const perRow = Math.ceil(N / 2 / 3);
const row = Math.floor(j / perRow);
const col = (j % perRow) / Math.max(1, perRow - 1);
const rowY = CY - 90 + row * 90;
const rowX = CX - SERVER_W / 2 + 50 + col * (SERVER_W - 100);
return { x: rowX, y: rowY };
}
export function TransformScene() {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const local = frame - BEAT.transform.in;
const sceneIn = clampLerp(frame, BEAT.transform.in, BEAT.transform.in + 6);
const sceneOut = 1 - clampLerp(frame, BEAT.transform.out - 8, BEAT.transform.out);
const sceneAlpha = Math.min(sceneIn, sceneOut);
// Schematic strokes on IN PARALLEL with the convergence — starts at
// local 8 instead of 30 so the box is visible before particles arrive.
const strokeT = easeInOut(clampLerp(local, 8, 55));
// Ports + rows show up as schematic completes
const innerT = clampLerp(local, 35, 65);
const portPulse = clampLerp(local, 55, 90);
// Scan-line — diagonal pass once the schematic is fully drawn
const scanT = clampLerp(local, 55, 90);
// Central core glow — visible throughout Beat 2 so the eye has an
// anchor even when particles are mid-flight. Pulses softly.
const coreAlpha = clampLerp(local, 0, 12) * (1 - clampLerp(local, 95, 110) * 0.4);
const corePulse = 1 + 0.25 * Math.sin(local * 0.18);
return (
{/* Central core — a hint of radial glow at the explosion origin.
Toned down from earlier versions so the schematic, not the core,
carries the visual weight. */}
{/* Particles — 60 small glowing dots radiating from a single origin.
They support the schematic; they do not dominate it. */}
{/* Server schematic */}
{/* Corner labels — bigger and earlier */}