feat(remotion): FlexStory scene engine — ordered editable scene-blocks (Phase 1)
Turns a template into an ordered list of editable scene blocks instead of one monolithic composition — the foundation for the scene-based template engine (all Renderforest-style types, per-scene editable duration, add/duplicate/ delete/reorder). Render-side only; backend wiring is Phase 2. - src/scenes/types.ts: SceneInstance/BlockProps/SceneBlock + withDefaults/clamp. - src/scenes/chrome.tsx: shared 2.5D Three.js backdrop (parallax camera, blobs, particles, optional 3D confetti) + grain/vignette/progress/kicker/transition. - src/scenes/blocks/*: Core 6 blocks — TitleCard, CharacterScene (full room + vendored CC0 character behind a desk), ImageCaption, KineticQuote, Slideshow, OutroCTA — each with editable fields + its own duration range. - src/scenes/registry.ts: the block registry (blockId -> block). - src/compositions/FlexStory.tsx: the sequencer — stacks blocks in <Sequence>, clamps per-scene duration, and computes composition length dynamically via calculateMetadata (so add/delete/reorder/duration all flow to the render). - StoryScenes.tsx: the 2.5D story proof this productizes; docs/TEMPLATE_BRIEF.md: the guided creator flow + Template Spec. Verified: all 6 blocks render via FlexStory in 16:9/1:1/9:16; a custom props override (reordered scenes, custom characters/durations/colors) renders correctly and the total length tracks Σ per-scene durations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import type { SceneBlock } from "./types";
|
||||
import { TitleCardBlock } from "./blocks/TitleCard";
|
||||
import { CharacterSceneBlock } from "./blocks/CharacterScene";
|
||||
import { ImageCaptionBlock } from "./blocks/ImageCaption";
|
||||
import { KineticQuoteBlock } from "./blocks/KineticQuote";
|
||||
import { SlideshowBlock } from "./blocks/Slideshow";
|
||||
import { OutroCTABlock } from "./blocks/OutroCTA";
|
||||
|
||||
/**
|
||||
* The scene-block registry. A FlexStory template is an ordered list of these
|
||||
* blocks; new template types = new blocks. Each block declares its editable
|
||||
* fields + duration range (so the studio can clamp per-block, not globally).
|
||||
*/
|
||||
export const SCENE_BLOCKS: Record<string, SceneBlock> = {
|
||||
[TitleCardBlock.id]: TitleCardBlock,
|
||||
[CharacterSceneBlock.id]: CharacterSceneBlock,
|
||||
[ImageCaptionBlock.id]: ImageCaptionBlock,
|
||||
[KineticQuoteBlock.id]: KineticQuoteBlock,
|
||||
[SlideshowBlock.id]: SlideshowBlock,
|
||||
[OutroCTABlock.id]: OutroCTABlock,
|
||||
};
|
||||
|
||||
export const BLOCK_LIST = Object.values(SCENE_BLOCKS);
|
||||
export const getBlock = (id: string): SceneBlock | undefined => SCENE_BLOCKS[id];
|
||||
Reference in New Issue
Block a user