import React from "react"; import { AbsoluteFill, Interactive, interpolate, useCurrentFrame } from "remotion"; import { AppCursor, Ripple, TopBar, } from "../components/ui"; import { COLORS, bodyFont, headingFont, HIT, SNAP } from "../theme"; /** * Scene 5 — Choosing Context (10.6–14.6s) * ------------------------------------------------------------ * First UI moment. The app, in close-up: top bar drops in, the * context selector card unfolds, and the oversized cursor walks * three clicks — Grade 10 → Science → Chapter 4 · Photosynthesis. * Each click: ripple ring + pill flips black + micro-bounce + * subtle camera push. Then a confirmation row locks the context. */ export const CHOOSING_FRAMES = 240; // 4.0s @ 60fps type StepType = "grade" | "subject" | "chapter"; const GRADE_OPTIONS = ["Grade 6", "Grade 7", "Grade 8", "Grade 9", "Grade 10", "Grade 11", "Grade 12"]; const SUBJECT_OPTIONS = ["Mathematics", "Science", "History", "Language Arts", "English", "Geography"]; const CHAPTER_OPTIONS = ["Ch 1 · Nutrition in Plants", "Ch 2 · Photosynthesis", "Ch 3 · Respiration", "Ch 4 · Human Body", "Ch 5 · Food Chains", "Ch 6 · Adaptations"]; // beat frames const CARD_IN = 10; const CLICK1 = 78; const CLICK2 = 126; const CLICK3 = 174; const CONFIRM = 214; export const ChoosingContext: React.FC = () => { const frame = useCurrentFrame(); const step: StepType = frame < CLICK1 ? "grade" : frame < CLICK2 ? "subject" : frame < CLICK3 ? "chapter" : "chapter"; const options = step === "grade" ? GRADE_OPTIONS : step === "subject" ? SUBJECT_OPTIONS : CHAPTER_OPTIONS; const pickIdx = step === "grade" ? 4 : step === "subject" ? 1 : 1; // Grade 10 / Science / Ch2 // camera push-in per click (pulses) const push = 1 + interpolate(frame, [CLICK1, CLICK1 + 10], [0, 0.016], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: SNAP }) + interpolate(frame, [CLICK2, CLICK2 + 10], [0, 0.02], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: SNAP }) + interpolate(frame, [CLICK3, CLICK3 + 10], [0, 0.024], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: SNAP }); // card entrance const cardIn = interpolate(frame, [CARD_IN, CARD_IN + 16], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: SNAP, }); const cardY = 560 + (1 - cardIn) * 46; // Simple cursor path: move to target, click, move to next target const curClick = (from: number, to: number, at: number) => { const t = interpolate(frame, [at, at + 16], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: HIT, }); return from + (to - from) * t; }; const press = (at: number) => interpolate(frame, [at, at + 6], [1, 0], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: SNAP, }); // cursor position timeline let cx = 640, cy = 760, cp = 0; if (frame < 56) { cx = 1180 - (1180 - 476) * interpolate(frame, [24, 56], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: HIT }); cy = 900; } else if (frame < CLICK1) { cx = curClick(476, 476, 56); cy = 732; } else if (frame < CLICK1 + 8) { cx = 470; cy = 728; cp = press(CLICK1); } else if (frame < CLICK2 - 12) { cx = curClick(470, 460, CLICK1 + 8); cy = 728 + (880 - 728) * interpolate(frame, [CLICK1 + 8, CLICK2 - 12], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: HIT }); } else if (frame < CLICK2 + 8) { cx = 460; cy = 876; cp = press(CLICK2); } else if (frame < CLICK3 - 14) { cx = curClick(460, 480, CLICK2 + 8); cy = 876 + (1030 - 876) * interpolate(frame, [CLICK2 + 8, CLICK3 - 14], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: HIT }); } else if (frame < CLICK3 + 10) { cx = 480; cy = 1026; cp = press(CLICK3); } else { cx = curClick(480, 300, CLICK3 + 10); cy = 1026 + (620 - 1026) * interpolate(frame, [CLICK3 + 10, CLICK3 + 26], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: HIT }); } const cursorOpacity = interpolate(frame, [24, 40], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: SNAP, }); // ripple activations const ripples = [ , , , ]; // confirm row const confirmIn = interpolate(frame, [CONFIRM, CONFIRM + 16], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: SNAP, }); return ( = CLICK1 }, { label: "Science", active: frame >= CLICK2 }, { label: "Ch 2", active: frame >= CLICK3 }, ]} /> {/* selector card */}
{step === "grade" ? "Choose your standard" : step === "subject" ? "Choose your subject" : "Choose your chapter"}
{step === "grade" ? "For CBSE · Grades 6–12" : step === "subject" ? "For Grade 10" : "Grounded in your textbook"}
{/* options list (3-col grid for grades, list for subject/chapter) */}
{options.map((opt, i) => { const isPick = i === pickIdx; const lit = isPick && frame >= (step === "grade" ? CLICK1 : step === "subject" ? CLICK2 : CLICK3); return (
{opt}
); })}
{/* cursor + ripples */} {ripples} {/* confirm bar */} {frame >= CONFIRM && (
Grade 10 · Science · Chapter 2 · Photosynthesis
)}
); }; // (Ripple is imported from ../components/ui)