From 303620211e3b0e2210d3e0bbb9c20764a0875135 Mon Sep 17 00:00:00 2001 From: Metbcy Date: Sat, 9 May 2026 22:00:48 +0000 Subject: [PATCH 1/4] feat(scene): add --lottie overlay support to vibe scene add Wire --lottie , --lottie-position, --lottie-scale, --lottie-opacity, and --lottie-no-loop flags into the scene add command. When supplied, the Lottie file is copied into assets/ and a web component is layered on top of the selected preset's content. Position/scale/opacity vocabulary mirrors vibe edit motion-overlay so users and agents get consistent behavior across both paths. Closes #208 (scene helper milestone). --- .../src/commands/_shared/scene-html-emit.ts | 109 +++++++++++++++++- packages/cli/src/commands/scene.ts | 67 ++++++++++- 2 files changed, 173 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/_shared/scene-html-emit.ts b/packages/cli/src/commands/_shared/scene-html-emit.ts index 540dbf38..cfaeef6f 100644 --- a/packages/cli/src/commands/_shared/scene-html-emit.ts +++ b/packages/cli/src/commands/_shared/scene-html-emit.ts @@ -41,6 +41,40 @@ export interface SceneTranscriptWord { end: number; } +/** + * Position value for Lottie overlays. Mirrors the vocabulary used by + * `vibe edit motion-overlay --position`. + */ +export type LottiePosition = + | "full" + | "center" + | "top-left" + | "top-right" + | "bottom-left" + | "bottom-right"; + +export const LOTTIE_POSITIONS: readonly LottiePosition[] = [ + "full", + "center", + "top-left", + "top-right", + "bottom-left", + "bottom-right", +] as const; + +export interface LottieOverlayInput { + /** Project-relative path to the `.json` or `.lottie` file (e.g. "assets/logo.lottie"). */ + src: string; + /** Overlay position. Defaults to "full". */ + position?: LottiePosition; + /** Scale factor (0.01-2). Defaults to 1. */ + scale?: number; + /** Opacity (0-1). Defaults to 1. */ + opacity?: number; + /** Whether the animation loops. Defaults to true. */ + loop?: boolean; +} + export interface EmitSceneInput { /** Kebab-case scene id; appears in `data-composition-id` and template id. */ id: string; @@ -69,6 +103,12 @@ export interface EmitSceneInput { * their headlines are intentionally static. */ transcript?: SceneTranscriptWord[]; + /** + * Optional Lottie animation overlay. When supplied, a `` + * element is layered on top of the preset's content. Uses the same + * position/scale/opacity vocabulary as `vibe edit motion-overlay`. + */ + lottie?: LottieOverlayInput; } const GSAP_CDN = "https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"; @@ -534,6 +574,67 @@ function buildPreset(input: Required` markup + module script for a Lottie overlay + * layer. Returns `{ markup, script }` to splice into the scene template. + */ +function buildLottieOverlay(input: LottieOverlayInput): { markup: string; script: string } { + const loop = (input.loop ?? true) ? " loop" : ""; + const style = lottieOverlayStyle(input); + const markup = ``; + const script = ``; + return { markup, script }; +} + /** * Emit the full per-scene HTML. Returns a complete `