Bare yard becomes a finished pool. Empty room becomes a staged interior. The camera holds still; the subject changes.
Get started Β· Case studies Β· How it works Β· What it costs Β· New to Claude Code?
Heroes built with this technique, scrubbing back to back. Real recordings, not highlight edits: every one is driven at the same constant 400Β px/second, roughly the pace of an unhurried browsing scroll, so the clip lengths differ because the heroes do. This plays by itself, and GitHub puts a pause button on it. Open the full-quality MP4 to scrub it frame by frame. Measurements and case studies in examples/.
Note
You'll need a kie.ai account β that's
where the models run, and you pay them directly. A typical hero is about $2.55. That link is
a Black Line Ops affiliate link: sign up through it and we earn a referral credit at no extra
cost to you. It changes nothing about what a run costs, and the rates quoted in
references/kie-api.md cite kie.ai's own pages with
plain, unreferred links so you can check every number.
You give it a photograph and a sentence β or, if the thing does not exist yet, just the sentence. It:
- Draws the opening frame, when there is no photo. The idea becomes a photographic description, the description is rendered, and the storyboard is then written against that frame. One image, about $0.05. Skip this step and everything below is identical.
- Writes a storyboard β a multimodal model looks at your photo and plans the steps.
- Renders keyframe stills β image-to-image from your photo, so the real building, fence and skyline stay recognisable instead of drifting into generic AI scenery.
- Stops and shows you a contact sheet. Nothing expensive happens until you approve.
- Tweens between approved stills with Kling's first/last-frame video model.
- Cuts the videos into numbered WebP frames plus a small
config.js, and can wire the canvas scrub engine into your page.
The finished hero is just images a canvas paints. No video element, no runtime AI, no streaming β which is why it scrubs smoothly, works offline once deployed, and doesn't stall on iOS.
Which of the two skills do I want?
Ask whether the camera moves.
| scroll-scrub-hero (this one) | scroll-flight (coming soon) | |
|---|---|---|
| Camera | locked, one fixed viewpoint | travels through a world |
| Subject | the subject changes state | the world holds still, you fly |
| Starts from | one or two real photographs | an idea, no photo needed |
| Good for | before β after, bare yard β finished pool | "fly through our factory / city / process" |
SKILL.md |
what Claude reads β the interview, then the pipeline |
scripts/ |
storyboard β keyframes β tween β build-frames, plus doctor.mjs and pricing.mjs |
references/ |
prompting, page wiring, the kie.ai contract and cost model |
examples/ |
four real client builds, measured β frame counts, weights, what went wrong |
scripts/seams.mjs |
measures every join and names the segment to re-run |
test/ |
323 tests, no network, nothing billable β run on Linux, macOS and Windows with a real ffmpeg on every push |
docs/how-it-works.md |
why the frames approach beats seeking a video |
Works in Claude Code, Codex, Cursor and most other SKILL.md-compatible agents. Pick whichever
line matches your setup.
Any agent β the skills CLI (easiest)
Installs into whichever agents it finds on your machine (75+ supported, Codex and Cursor included). It will ask which ones to target if it can't tell.
npx skills add Black-Line-Ops/scroll-scrub-heroFor Codex this lands in .agents/skills/ for the project, or ~/.codex/skills/ globally.
Claude Code β as a plugin
/plugin marketplace add Black-Line-Ops/scroll-scrub-hero
/plugin install scroll-scrub-hero@scroll-scrub-hero
Claude Code β from a .skill file
Open it with Claude (drag it in, or use the Save skill button when Claude shows it). It installs into your profile and is available in every project.
By hand
Drop the folder into your agent's skills directory and restart it.
| Claude Code (macOS / Linux) | ~/.claude/skills/scroll-scrub-hero/ |
| Claude Code (Windows) | C:\Users\<you>\.claude\skills\scroll-scrub-hero\ |
| Codex (project) | .agents/skills/scroll-scrub-hero/ |
| Codex (global) | ~/.codex/skills/scroll-scrub-hero/ |
SKILL.md must sit at the top level of the scroll-scrub-hero folder β not nested inside a
second folder of the same name, which is the usual unzip accident.
Note where it landed. Everything below addresses the scripts through a SKILL variable holding
that path, which is what lets you run them from your own project directory instead of from inside
the skill.
| Node 18+ | for the scripts (node --version) |
| Git | the skills CLI clones this repo to install it (git --version) |
| ffmpeg + ffprobe | for cutting frames β winget install Gyan.FFmpeg, brew install ffmpeg-full (Homebrew's plain ffmpeg is a slim build with no WebP encoder), or apt install ffmpeg |
| A kie.ai account with credits | this is where the models run β sign up |
No npm install. Every import is a Node builtin.
Never set any of this up before? The plain-English starter guide walks through installing all of it from scratch on Windows or Mac, including what a terminal is. Skip it if none of that is news.
Get an API key from kie.ai β API keys, then set it as an environment variable.
Windows PowerShell
This terminal only:
$env:KIE_API_KEY = "your-key-here"Permanently, then reopen your terminal:
[Environment]::SetEnvironmentVariable("KIE_API_KEY","your-key-here","User")macOS / Linux / Git Bash
This shell only:
export KIE_API_KEY="your-key-here"Permanently:
echo 'export KIE_API_KEY="your-key-here"' >> ~/.zshrcThen point SKILL at the folder you installed into and run the preflight. This is the only check
this README asks you to run β it covers the install, the tools and the key in one command:
Set it to the folder the skill actually landed in β the one holding SKILL.md. The table
above lists where each host installs; if you are not sure, run the preflight from inside that
folder once and it prints the exact line to use.
# macOS / Linux / Git Bash
SKILL="/absolute/path/to/scroll-scrub-hero"
node "$SKILL/scripts/doctor.mjs"# Windows PowerShell
$SKILL = "C:\absolute\path\to\scroll-scrub-hero"
node "$SKILL/scripts/doctor.mjs"The first thing it checks is that path. It works out where it is running from, names the install
it recognises, prints a ready-to-paste SKILL= line for both shells, and fails if $SKILL is
already pointing somewhere else β a run split across two copies of the skill is the version of
this mistake that does not announce itself.
It verifies Node, ffmpeg, that your ffmpeg can actually encode WebP, your key, that kie.ai accepts it, and that every route the pipeline calls still exists β and prints the exact fix for anything missing. It then shows the money: your credit balance in credits and dollars, what a default run costs, and every rate with the page it was read from. None of that spends anything.
Important
The scripts only ever read the key from the environment β they never write it anywhere. Your
shell may still record the command in its history: on macOS/Linux a leading space usually keeps
it out, and the PowerShell SetEnvironmentVariable form stores it in your user environment
rather than a file.
Easiest way is to just ask Claude, in a project where the skill is installed:
Build me a scroll hero from
photos/backyard.jpgβ bare grass through to a finished pool with water in it.
You do not need to know what a keyframe is. Claude runs a short interview first β six multiple-choice questions about what you want, each option priced, each with a recommended default you can just take β then shows you the forecast, drives the pipeline, and stops at the contact sheet for your approval before anything expensive happens.
Driving it by hand
Run all four from the same scratch directory, never from inside the skill folder, and use absolute paths for anything outside it:
mkdir -p ~/scrub/jones && cd ~/scrub/jones
SKILL="/absolute/path/to/scroll-scrub-hero" # the folder holding SKILL.md; doctor.mjs prints this line for you
node "$SKILL/scripts/storyboard.mjs" --ref /abs/path/photo.jpg --idea "bare grass to finished pool" --steps 6
node "$SKILL/scripts/storyboard.mjs" --idea "empty lot to finished house" --steps 6 # no photo: frame 1 is generated
node "$SKILL/scripts/keyframes.mjs" --storyboard storyboard.json # then open keyframes/contact-sheet.html
node "$SKILL/scripts/tween.mjs" --storyboard storyboard.json --mode pro --duration 5 --yes
node "$SKILL/scripts/build-frames.mjs" --segments segments/ --storyboard storyboard.json --out /abs/path/site/assets/hero-scroll/frames/That last line is long on purpose. A trailing \ to wrap it is a bash-ism, and this project
supports PowerShell, where the paste would break.
Staying in one directory matters: the scripts record their progress in _state.json files beside
their output, and that is also what lets you resume a run instead of paying twice.
Warning
The two steps that spend credits ask before doing it. When something other than a person at a
keyboard is running them β Claude, a script, CI β there is nothing to answer the prompt, so they
take --yes. Treat it as signing for the cost.
This matters more than any setting.
- Wide beats tight. A shot with buildings, a fence and a horizon gives the model landmarks to hold onto. A tight crop of a lawn gives it nothing, and the sequence drifts.
- Even, flat light. Harsh shadows move as the model invents, which reads as a time jump.
- One clear subject area that will change, with everything else static.
- Two photos are better than one. If you have a genuine before and after of the same view,
pass the second to
storyboard.mjs --ref2β the pipeline pins the last keyframe to the real finished photo instead of imagining it, and copies it in rather than paying to generate it. (--ref2goes onstoryboard.mjsonly;keyframes.mjsreads it back out ofstoryboard.json.)
You pay kie.ai directly for what you generate. A typical six-step hero is about $2.55 β a handful of stills at 5 cents each, plus five video segments at about 45 cents each. The stills are cheap; the video is the whole bill.
| Six steps, 2K stills, 5 s clips | Estimate |
|---|---|
Rough test (--mode std, 1280Γ720) |
~$2.05 |
Final (--mode pro, 1920Γ1080) β the default |
~$2.55 |
--mode 4K (3840Γ2160) |
~$8.68 |
Four steps is about $1.55 and ten is about $4.55, at final quality. Every figure here is an estimate from a dated rate table read off kie.ai's own pages on 2026-08-07 β not a quote.
Before it spends, each script prints what it is about to generate, what that should cost in credits
and dollars, the arithmetic behind the number, the page the rate came from, and your account
balance β then waits for a yes. node scripts/doctor.mjs shows all of that for free before you
start. What gets recorded is whatever kie.ai reports as creditsConsumed, per item, in
keyframes/_state.json and segments/_state.json; the run compares that against the estimate when
it finishes and tells you how to pin your own rate if the table is off for your account.
Two habits keep it sane: approve the contact sheet before tweening, and regenerate single items
(--only 3) rather than whole batches. The full cost model, with the provenance of every rate and
how to override them, is in references/kie-api.md.
| Symptom | Cause | Fix |
|---|---|---|
| Hard cut mid-scroll | two keyframes disagree structurally | regenerate the later one, or insert an intermediate step |
| Subject drifts over the sequence | compounding error from chaining | re-anchor that keyframe to the original photo |
| Furniture/objects "grow" out of the floor | motion prompt isn't physical | describe one process with real verbs |
| Hero feels heavy on mobile | too many frames or too wide | lower --per-clip or --width |
| A task never finishes | it may still be running | query the saved taskId before regenerating, or you pay twice |
More detail lives in references/prompting.md (getting good frames)
and references/hero-wiring.md (getting it into a page).
We are a Tampa Bay web studio. This skill is the same pipeline behind the scroll heroes on our client sites β packaged, documented and given away, because the interesting part was never the code. If you want one of these built for you rather than building it yourself, that is what we do.
This is the whole pipeline, free, MIT. But if you would rather not run it yourself β or you want the hero designed into a page rather than dropped into one β that is the day job. Rates and contact are on blacklinedesign.website.
Special thanks to Titus Byron (@Prxdigy-exe), Security Analyst Intern at Black Line Ops. Titus contributed debugging, security hardening, operational support, and fixes for several important issues in scroll-scrub-hero.
scroll-scrub-hero is free and MIT-licensed. If this project saved you time or helped you build something, you can support its continued development:
MIT β see LICENSE. Use it on client work freely, commercial or otherwise. If it is useful, a mention is appreciated but not required.
