From b48caaa591f09c8a0b1f1ba041bfe99a220c32d4 Mon Sep 17 00:00:00 2001 From: Satyam Rastogi Date: Sat, 30 May 2026 01:52:29 +0530 Subject: [PATCH] feat(film): timing config (8 sequences, 265s, 30fps) --- marketing/product-film/src/Root.tsx | 9 ++++--- marketing/product-film/src/timing.test.ts | 22 ++++++++++++++++ marketing/product-film/src/timing.ts | 31 +++++++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 marketing/product-film/src/timing.test.ts create mode 100644 marketing/product-film/src/timing.ts diff --git a/marketing/product-film/src/Root.tsx b/marketing/product-film/src/Root.tsx index 32f980d..48b76be 100644 --- a/marketing/product-film/src/Root.tsx +++ b/marketing/product-film/src/Root.tsx @@ -1,15 +1,16 @@ import { Composition } from "remotion"; import { Film } from "./Film"; +import { TOTAL_FRAMES, FPS, WIDTH, HEIGHT } from "./timing"; export const Root: React.FC = () => { return ( ); }; diff --git a/marketing/product-film/src/timing.test.ts b/marketing/product-film/src/timing.test.ts new file mode 100644 index 0000000..edd8504 --- /dev/null +++ b/marketing/product-film/src/timing.test.ts @@ -0,0 +1,22 @@ +import { describe, it, expect } from "vitest"; +import { DURATIONS, TOTAL_FRAMES, FPS, SEQUENCE_ORDER } from "./timing"; + +describe("timing", () => { + it("uses 30 fps", () => { + expect(FPS).toBe(30); + }); + it("has all 8 sequences in order", () => { + expect(SEQUENCE_ORDER).toEqual([ + "coldOpen", "promise", "pillar1", "pillar2", "pillar3", "pillar4", "pillar5", "craneClose", + ]); + }); + it("every duration is a positive integer number of frames", () => { + for (const key of SEQUENCE_ORDER) { + expect(DURATIONS[key]).toBeGreaterThan(0); + expect(Number.isInteger(DURATIONS[key])).toBe(true); + } + }); + it("TOTAL_FRAMES equals 265 seconds at 30fps", () => { + expect(TOTAL_FRAMES).toBe(7950); + }); +}); diff --git a/marketing/product-film/src/timing.ts b/marketing/product-film/src/timing.ts new file mode 100644 index 0000000..358c347 --- /dev/null +++ b/marketing/product-film/src/timing.ts @@ -0,0 +1,31 @@ +export const FPS = 30; +export const WIDTH = 1920; +export const HEIGHT = 1080; + +const sec = (s: number) => Math.round(s * FPS); + +export const SEQUENCE_ORDER = [ + "coldOpen", + "promise", + "pillar1", + "pillar2", + "pillar3", + "pillar4", + "pillar5", + "craneClose", +] as const; + +export type SequenceKey = (typeof SEQUENCE_ORDER)[number]; + +export const DURATIONS: Record = { + coldOpen: sec(12), + promise: sec(8), + pillar1: sec(45), + pillar2: sec(45), + pillar3: sec(50), + pillar4: sec(45), + pillar5: sec(45), + craneClose: sec(15), +}; + +export const TOTAL_FRAMES = SEQUENCE_ORDER.reduce((acc, k) => acc + DURATIONS[k], 0);