Skip to content

AliceLJY/scenecast

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

scenecast

Turn a paginated HTML deck into an element-level motion video. The HTML stays the only visual source — no template, no front-end framework.

scenecast demo

Why

Most "HTML → video" tools either flip through whole pages like a slideshow, or lock you into a template system whose look isn't your HTML. scenecast animates your poster, element by element — the HTML you wrote is the only visual source, so the video looks exactly like your page, just moving.

  • Your HTML is the source of truth — palette, layout, fonts are all inherited.
  • Declarative — describe motion with data-anim attributes; write zero JS.
  • Deterministic — seek-based rendering, frame-accurate and reproducible.
  • No front-end framework — no GSAP, no React; just your HTML and a tiny engine.

How it works

scenecast opens your HTML in headless Chromium (Playwright), injects a dependency-free, seek-based animation engine that reads your data-anim attributes, steps a virtual clock frame by frame while screenshotting each scene, then encodes the frames to MP4, WebM, or GIF with ffmpeg (chosen by the output file extension).

Install

git clone https://github.com/AliceLJY/scenecast.git && cd scenecast
npm install playwright            # the only runtime dependency (peer)
npx playwright install chromium   # one-time browser download

Run it locally — clone and run. The npm name scenecast belongs to an unrelated package, so don't npm i scenecast. Want a short scenecast command? Run npm link once inside the repo (otherwise use node src/cli.mjs).

scenecast also needs ffmpeg on your PATH:

Playwright is a peer dependency, so you pick the version. By default scenecast tries Playwright's bundled Chromium and falls back to system Chrome when the bundled browser is not installed; pass --channel chrome to require system Chrome explicitly.

Quick start

Mark each page with data-scene, and add data-anim to the elements you want to move:

<section data-scene data-scene-duration="4">
  <h1 data-anim="fade-left" data-anim-delay="0.1">Hello</h1>
  <span data-anim="count-up" data-anim-delay="0.6">128</span>
</section>
<section data-scene>
  <p data-anim="fade-up">The HTML you wrote is the only visual source.</p>
</section>

Render it (from the cloned repo, or scenecast render … after npm link):

node src/cli.mjs render deck.html -o out.mp4

Or from Node:

import { renderHtmlToVideo } from "./src/index.mjs"; // path within the cloned repo

await renderHtmlToVideo({ input: "deck.html", output: "out.mp4" });

Declarative animation

Scenes

attribute meaning
data-scene marks an element as one scene (a page / shot)
data-scene-duration="5" seconds this scene lasts (overrides --scene-duration)

Element animation

Add data-anim to any element inside a scene:

data-anim effect
fade fade in
fade-up / fade-down fade + slide vertically
fade-left / fade-right fade + slide horizontally
zoom-in fade + scale up
count-up count a number from 0 up to the element's final value
draw draw on an SVG line / path (stroke draw-on)
highlight tween text color toward data-anim-color

Modifiers (all optional):

attribute default meaning
data-anim-delay 0 start time within the scene (seconds)
data-anim-duration 0.6 animation length (seconds)
data-anim-ease outCubic linear / outQuad / outCubic / outQuint / outBack
data-anim-distance preset slide distance in px for fade-*
data-anim-rotate extra rotation in deg, "from to" e.g. "9 -1.6" (works on any preset)
data-anim-scale scale endpoints, "from" (to 1) or "from to"
data-anim-color target color for highlight (hex or rgb())
data-anim-base a transform to keep, e.g. translateX(-50%)

Stagger

Put data-anim-stagger on a container; its direct children enter in sequence, each offset by the step (seconds). A child and any animated elements inside it move together as one unit:

<div class="cards" data-anim-stagger="0.15">
  <div class="card" data-anim="fade-up"></div>
  <div class="card" data-anim="fade-up"></div>
  <div class="card" data-anim="fade-up"></div>
</div>

CLI

scenecast render <input.html> -o <output.mp4|.webm|.gif> [options]
option default
-o, --output output file; codec by extension: .mp4 / .webm / .gif (required)
--scene-selector [data-scene] which elements are scenes
--scene-duration 5 seconds per scene
--fps 30 frames per second
--width / --height 1920 / 1080 output size
--deck-width / --deck-height 1200 / 675 your HTML's per-scene design size
--scale 2 capture device scale factor (sharper text)
--channel bundled Chromium e.g. chrome for system Chrome
--voiceover audio file; also writes *-voiceover.mp4 (mp4 output only)
--keep-frames off keep the intermediate PNG frames

A runnable example lives in demo/demo.html; npm run demo renders it.

Notes & limitations

  • Only render HTML you trust. scenecast opens your HTML in a real browser and executes its scripts with network access. Don't feed it untrusted pages.
  • Your existing CSS animations / transitions are not captured. Frames are seek-driven and grabbed with animations: "disabled"; motion comes from data-anim, not from CSS keyframes.
  • transform animations on inline elements (fade-*, zoom-in) promote them to inline-block, which can change wrapping and baseline. Prefer animating block / inline-block elements, or use highlight (color only) for inline text.
  • Nested data-anim-stagger is not supported — the outermost container wins.
  • data-anim-base is manual. If an element already has a CSS transform you want to keep, repeat it there.
  • count-up reads the element's final text. It handles integers, decimals, and a leading unit/sign, but not arbitrary formats; thousands separators are dropped while counting.

Requirements

  • Node ≥ 18
  • Playwright (peer dependency) + a browser (npx playwright install chromium)
  • ffmpeg on PATH

License

MIT © AliceLJY

About

Render paginated HTML decks into deterministic element-level motion videos with Playwright and ffmpeg.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors