feat(compiler): capture and replay Lottie animations
lottie-web renders vector animations from a JSON document at runtime. As third-party JS it falls outside the declarative CSS path and the WAAPI / reveal / marquee probes, so clones shipped the empty container and the animation was gone. This adds a Lottie subset to Stage 5 motion: capture the deterministic part — the source JSON (materialized local file, or inline animationData) plus playback config — and emit a fixed DittoLottie client that re-mounts lottie-web on the cid'd container. Capture (compiler/src/capture/lottie.ts): in-page detector covering lottie-web's registry (animationData in memory), <lottie-player>/<dotlottie-player>, Elementor data-settings (source_json.url), and generic markup. Keyed by data-cid-cap. motion.ts merges it into MotionCapture; capture.ts registers source URLs as assets so the existing fallback fetch downloads + materializes them to /assets/cloned/lottie. Generate (compiler/src/generate/lottie.ts): buildLottieSpec resolves cap->cid and source URL->materialized local path (or embeds inline animationData), then emits DittoLottie + wire/import helpers, mirroring DittoMotion. app.ts writes the component, wires import+JSX, and injects lottie-web into the generated package.json. Delivery (compiler/src/cli.ts): stripDeliveryDataCids now treats DittoLottie as a runtime consumer, so its container keeps a semantic data-ditto-id anchor instead of being stripped (without this the animation never finds its mount point). Lottie-free clones stay byte-identical. Verified end-to-end: cloning a page with a <lottie-player> scrapes the JSON, emits a wired DittoLottie, and lottie-web mounts and plays the captured animation (rendered SVG viewBox matches the source JSON). Unit tests cover buildLottieSpec resolution + drop rules. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
co-authored by
claude-flow
parent
7d0e85ddb4
commit
048fd8cdad
@@ -826,6 +826,11 @@ export async function captureSite(opts: {
|
||||
if (opts.motion && vw === canonical) {
|
||||
try { motion = await captureMotion(page, { log }); }
|
||||
catch (e) { log({ event: "motion_error", error: String(e).slice(0, 200) }); }
|
||||
// Register lottie source JSONs as assets so the asset stage downloads + materializes
|
||||
// them (the in-page detector only records the URL; the fallback fetch grabs the file).
|
||||
for (const l of motion?.lotties ?? []) {
|
||||
if (l.src) recordAsset(l.src, "lottie", null, null, "lottie");
|
||||
}
|
||||
}
|
||||
|
||||
perViewport.push({
|
||||
|
||||
Reference in New Issue
Block a user