motion-ad
Back to list

danny/motion-ad

Motion Ad

GitHub

Produce short motion-graphics video ads for any product as rendered MP4s, with GSAP-driven HTML beats and frame-by-frame capture.

VideoMotionFrontend0 demos

Real-world examples not captured yet

This skill shows a gallery of live HTML demos (CDN libraries welcome — GSAP, Three.js, etc.) rendered inline via srcdoc.

Skill markdown
# Motion Ad

Builds a sound-off-friendly motion-graphics ad as one HTML page driven by a paused GSAP timeline, then renders it frame by frame into an H.264 MP4. The bundled [assets/template.html](assets/template.html) is a finished 15s 4:5 ad (hook + phone → before/after scan reveal → 3D wall of outputs → showcase carousel + social proof → brand-color CTA end card). All brand and product content sits in one `CONFIG` object at the top of its script — start there and rewrite beats rather than building from zero. Missing images render as labelled placeholders, so the ad previews before real assets exist.

## CRITICAL

- **Claims must match the page the ad links to.** Read the destination page (WebFetch, or its source if it's in the current repo) before writing copy. Prices, counts, speeds, guarantees and "free" claims must appear on that page. If the user asks for copy that contradicts the page, do it, but flag the mismatch once.
- **Only use real assets** — the user's own images or ones pulled from their live site with `scripts/fetch-images.cjs`. Never invent customers, reviews, ratings or results. If the proof row has no real number to show, set `proof: null`.
- **Never fabricate a person.** If a beat needs more images of someone than exist, use crops/mirrors of real ones and say so.
- **Deliver to `~/Downloads/` with a versioned name** (`<brand>-<topic>-ad-4x5-v2.mp4`). Never overwrite an earlier version.
- **Match the brand**, not the template defaults: primary/accent/page colors, font, logo, tone. Default to no hype, no exclamation marks, no emoji unless the brand uses them.

## Workflow

```
- [ ] Step 1: Research product + destination page
- [ ] Step 2: Set up workdir and gather assets
- [ ] Step 3: Write the storyboard + copy
- [ ] Step 4: Fill CONFIG / edit the timeline
- [ ] Step 5: Render stills, review, fix
- [ ] Step 6: Render full MP4, spot-check transitions, deliver
```

### Step 1: Research

- Ask for (or infer from context) the product, the destination URL, the audience and the format (4:5 feed by default, 9:16 for stories/reels).
- WebFetch the destination page and the homepage/pricing for current facts: headline promise, prices, ratings/review counts, speed, what's free vs paid.
- Pull the brand: colors, font family and logo from the site's CSS/design system, or ask.

### Step 2: Workdir + assets

```bash
S=~/.claude/skills/motion-ad           # wherever this skill is installed
W=<scratchpad>/video && mkdir -p $W/a && cd $W
(cd $S/scripts && npm install)        # one-time: playwright-core + gsap, no browser download
cp $S/assets/template.html index.html
cp $S/scripts/node_modules/gsap/dist/gsap.min.js .
node $S/scripts/fetch-images.cjs --url <destination-url>   # -> a/web/NN.jpg + images.json
python3 $S/scripts/contact-sheet.py images a/web           # -> images.jpg, Read it to pick assets
```

Put the logo(s) in `a/` (light-background and, if available, a white version). Pick the hero before/after pair for the clearest transformation — for a SaaS product that can be "messy input → finished output" screenshots rather than photos. Portrait (≈4:5) images fill the hero and showcase cards best. Ask the user if they want specific images, and use theirs over scraped ones when offered.

### Step 3: Storyboard

Keep 4–5 beats in 15s, one short headline per beat (≤ ~20 chars per line at 82px), big enough to read muted. Template beats and the `CONFIG` fields that drive them:

| Time | Beat | CONFIG fields |
|---|---|---|
| 0–2.2s | Hook headline, phone scrolls a screen capture, finger taps the input | `hook`, `screen`, `screenScroll`, `tap` |
| 2.2–5.4s | Tapped card grows into the hero; scan beam reveals before → after; benefit pills | `reveal`, `before`, `after`, `beforeLabel`, `afterLabel`, `benefits` |
| 5.5–8.7s | Hero shrinks into a tilted 3D wall of outputs | `scale`, `scaleChip`, `gallery` |
| 8.7–11.8s | Showcase carousel (3 cards, optional "before" inset) + proof row | `proofHl`, `showcase`, `showChip`, `proof` |
| 11.8–15s | Brand-color circle wipe → logo, CTA headline, chip, button tap | `cta.headline`, `cta.chip`, `cta.button`, `cta.foot` |

If a beat doesn't fit the product, change or cut it in the timeline rather than forcing it (e.g. no phone step for a desktop tool — start on the hero card).

### Step 4: Fill CONFIG / edit the timeline

- Set `brand`, `logo`, `logoOnDark`, `colors`, and change the Google Fonts `<link>` plus `--font` to the brand font.
- Headlines: `*word*` or `*several words*` marks the accent color, `\n` forces a line break.
- Image paths are relative to `index.html` (e.g. `a/web/03.jpg`). Crop/mirror with PIL when an image needs a different framing.
- Adjust `tap` so the finger lands on the relevant spot of `screen` after it scrolls by `screenScroll`.
- Keep `window.seek`, `window.DURATION`, `window.ready` and the `?render` autoplay guard intact — `render.cjs` depends on them.
- For 9:16, change `html,body,#stage` to 1080×1920, re-space the vertical positions (headl

…

More from danny