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:
@@ -3,6 +3,8 @@ import { ASPECTS } from "./lib/aspect";
|
||||
import { TEMPLATES } from "./templates";
|
||||
import { Three3DTest } from "./compositions/Three3DTest";
|
||||
import { AssetSheet } from "./compositions/AssetSheet";
|
||||
import { StoryScenes, STORY_SCENES_DURATION } from "./compositions/StoryScenes";
|
||||
import { FlexStory, flexStorySchema, flexStoryDefaults, calcFlexStoryMetadata } from "./compositions/FlexStory";
|
||||
import {
|
||||
IlluminatedCircles,
|
||||
illuminatedCirclesSchema,
|
||||
@@ -124,6 +126,36 @@ export const RemotionRoot: React.FC = () => {
|
||||
height={1080}
|
||||
/>
|
||||
|
||||
{/* 2.5D story scenes proof (Three.js room + flat CC0 characters) — dev preview */}
|
||||
{ASPECTS.map((a) => (
|
||||
<Composition
|
||||
key={`StoryScenes-${a.id}`}
|
||||
id={`StoryScenes-${a.id}`}
|
||||
component={StoryScenes}
|
||||
durationInFrames={STORY_SCENES_DURATION * FPS}
|
||||
fps={FPS}
|
||||
width={a.width}
|
||||
height={a.height}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* FlexStory — the scene engine: an ordered list of editable scene blocks,
|
||||
duration computed dynamically from the per-scene durations. */}
|
||||
{ASPECTS.map((a) => (
|
||||
<Composition
|
||||
key={`FlexStory-${a.id}`}
|
||||
id={`FlexStory-${a.id}`}
|
||||
component={FlexStory}
|
||||
durationInFrames={26 * FPS}
|
||||
fps={FPS}
|
||||
width={a.width}
|
||||
height={a.height}
|
||||
schema={flexStorySchema}
|
||||
defaultProps={flexStoryDefaults}
|
||||
calculateMetadata={calcFlexStoryMetadata}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Branded templates — each registered in all three aspects. A template may
|
||||
supply a dedicated component per aspect (componentsByAspect) when its
|
||||
design differs structurally; otherwise the shared `component` adapts
|
||||
|
||||
Reference in New Issue
Block a user