Skip to content

Repository files navigation

🎈 Pip & Bean — The Big Slide Day

A hand-crafted, paper-cut storybook cartoon for little kids, rendered entirely from HTML + SVG + GSAP using HyperFrames — no video editor, no timeline app. The whole ~4-minute episode is a set of deterministic, seek-safe compositions that render straight to MP4.

The story: Pip loves to bounce and Bean loves to build. When a grumpy new kid, Milo, shows up and stomps through the fun, Pip & Bean discover that grumpy on the outside is often just lonely on the inside — and that kindness is sunshine you can share. The weather literally follows the kindness: the world dims when Milo is unkind and blooms back to full sun when the three become friends.


✨ What's inside

  • Five acts (compositions/a1a5), mounted into one root timeline in index.html.
  • Original cast — Pip, Bean, and Milo are drawn as inline SVG and animated procedurally (blinks, talk-sync mouths, bounces, elastic overshoots).
  • Emotion-driven art direction — a desaturated overlay for sad beats, a gray cloud that hides the sun, warm sunbursts for the payoff. Light canvas throughout; sadness is never "dark."
  • Curved motion — characters ride the slide along a real GSAP MotionPath that hugs the chute (steep at the top, flattening into the run-out), not a straight line.
  • Procedural stage kit (lib/stage-kit.js) — a seeded (deterministic) scenery layer: the oak tree is generated geometry, grass tufts and wildflowers sprout along every ground line, and everything sways in an analytic, seek-safe wind. Generated props measure the real .ground element and plant themselves on it — grounding is guaranteed by construction, never by hand-typed pixel offsets.
  • Single-sourced props — the slide, sandcastles, and sandboxes are kit-built too (data-kit="slide|castle|sandbox" + a data-kit-sink depth): one canonical slide instead of three copies, castles with seeded sand speckles and wind-swayed pennants, sandboxes scattered with seeded pebbles and a starfish.
  • Playful transitions — circle-iris wipes, vertical pushes, and a blur crossfade for the sad wind-down.
  • Full voiceover + music + SFX — narrator, Pip, Bean, and Milo, over soft CC0 music and cartoon SFX (assets resolved locally; see Assets below).

🎨 Design language

Display type Baloo 2 (800) — chunky storybook headlines & name tags
Voice type Patrick Hand — speech bubbles & narrator caption band
Canvas cream #FFF6E4, sky #C9E9F4, ink #4A3B2F
Accents coral #FF7A45, sun #FFD34E, grass #A8D879
Cast Pip orange #FF9F4A · Bean green #7BC96F · Milo #A8A0B5 → #9B7BE0

📚 Documentation

doc what's in it
docs/ARCHITECTURE.md script→TTS→timeline→render pipeline, acts, audio tracks
docs/STAGE-CONTRACT.md the spatial rules the stage audit enforces, and how to waive one
docs/STAGE-KIT.md the procedural stage kit API: data-kit props, bubble anchoring, wind
docs/EPISODE.md story, cast, act-by-act beats, key timestamps
docs/WORKFLOW.md dev loop, visual verification, render performance
docs/DECISIONS.md engineering decision log — read before changing things
docs/YOUTUBE.md publishing/scheduling episodes to the @pipandbean channel
docs/EPISODE-02-PLAN.md brief for episode 2 and the multi-episode repo restructure
docs/EPISODE-03-PLAN.md brief for episode 3, The Broken Pinwheel

🚀 Run it

npm run dev          # live preview server (keep running)
npm run check        # the gate: framework checks + stage audit
npm run check:stage  # stage audit alone — the spatial contract, 291 sampled moments
npm run render       # render to MP4 (GPU-accelerated)
npm run publish      # publish and get a shareable link

npm run render is tuned for a fast local render (--gpu --browser-gpu --workers 8). For a maximum-quality pass use npm run render:quality.

The stage audit

Hand-placed cartoon staging drifts: a bubble stops pointing at its speaker, a prop ends up hanging in mid-air, a line plays over a shot its speaker is not in. The framework's own checks cannot see any of that, so this project ships tools/stage-audit.mjs — it loads the same bundled HTML the renderer screenshots, seeks the real timeline to every voice line and act seam, and measures the frame against the rules in docs/STAGE-CONTRACT.md. Deliberate exceptions are declared in the markup with data-stage-allow-*.

📁 Project structure

One episode per directory under episodes/; everything reusable is shared at the root.

episodes/01-big-slide-day/
  index.html          root timeline — mounts the five acts + audio tracks
  compositions/a1..a5 the five acts (self-contained HTML compositions)
  script.json         per-line voiceover script (speaker + text)
  timeline.json       act/line timing map
  voice_manifest.json measured MP3 durations
  meta.json           project id + title
  hyperframes.json    the HyperFrames project file (the CLI runs from here)
  assets -> ../../assets   symlink: the CLI needs them inside the project
  lib    -> ../../lib      symlink: same reason
  renders/            rendered MP4s              (git-ignored)

lib/stage-kit.js      seeded procedural scenery, bubble anchoring, wind — shared
tools/stage-audit.mjs geometric stage audit (npm run check:stage)
episode.py            resolves --episode for the generators
gen_tts.py            script.json -> assets/voices/<episode>/*.mp3
gen_index.py          timeline.json -> the episode's index.html
inject_fonts.py       inlines the fonts into each act
upload_youtube.py     publishes/schedules to @pipandbean (channel-wide)
frame.md              creative brief: concept, palette, type, audio plan
assets/               fonts, bgm, sfx, voices/<episode>/  (git-ignored)

Every command defaults to 01-big-slide-day; override with EP=<slug>:

EP=03-broken-pinwheel npm run check
python3 gen_index.py --episode 03-broken-pinwheel

🔊 Assets

Media (fonts, voices, background music, SFX) and rendered output are git-ignored to keep the repo lightweight — this repository holds the source of the composition. All music and sound effects are CC0 / public domain; character voices are generated TTS. Regenerate or re-resolve locally before rendering.

🛠️ Built with

  • HyperFrames — HTML-to-video rendering
  • GSAP 3 + MotionPathPlugin — animation & curved motion
  • Inline SVG for every character, prop, and background

♥ Pip & Bean — a kindness story for the very young.

About

Pip & Bean — The Big Slide Day: a paper-cut storybook kids' cartoon rendered from HTML + SVG + GSAP with HyperFrames

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages