addmotion
Submit Free API key

Lyric video — word-synced karaoke type

Lyrics appear word by word on exact timestamps, with a generative background driven by song time — every frame a pure function of t.

Prompt

# Lyric video — word-synced karaoke type

## Format (read first)
- 1920×1080 (16:9), 60fps, 8.0s = 480 frames
- Target: Single HTML file

## Brief
A word-synced lyric video for "Upping the odds". Timings are exact: 0.0 we | 0.3 keep | 0.6 upping | 1.0 the | 1.3 odds | 2.4 every | 2.7 night | 3.0 a | 3.2 little | 3.6 more | 4.8 hold | 5.1 on | 5.4 to | 5.6 the | 5.9 signal. The current word is highlighted; past words in the line stay visible but dimmed.

## Look
- Palette (background, accent, text): #08080c, #ff4fd8, #f5f5f5
- Type: Display sans 120px/900, lines centered, max 5 words per line.

## Beats (exact timings)
1. 0.0–8.0s — For each timed word: it appears at its timestamp with a 90ms scale-in (1.15→1) and becomes the highlighted word (accent color). The previous word drops to 70% opacity. A new line starts after a pause > 0.8s or 5 words. Background: a slow generative field (noise-displaced grid or particles) whose intensity follows the word density.

## Motion rules
- Everything is a pure function of time t: no setTimeout, no accumulated state between frames.
- Word timings must hit the frame nearest their timestamp at 60fps.

## Known failure modes — avoid these
- Using Math.random() per frame — seed a PRNG so the background is deterministic.

## Build
- Output ONE self-contained HTML file. No CDNs, web fonts, images or scripts from URLs.
- The stage is exactly 1920×1080 and scales to fit the window (letterbox) while keeping the aspect ratio.
- Expose window.__addmotion = { width: 1920, height: 1080, fps: 60, duration: 8, seek(t) } where seek(t) renders the exact frame for time t in seconds.
- Make every frame a pure function of t: compute positions from t (with easing functions you define) rather than accumulating state. Use requestAnimationFrame only to call seek(performance.now()/1000 % duration) for live preview.
- If you use CSS @keyframes, seek(t) must set animation-play-state: paused and a negative animation-delay of -t seconds on every animated element.
- To export MP4, step seek(t) frame by frame in a headless browser, screenshot each frame, and encode with ffmpeg.

## Done when
- [ ] Rendering frame N twice gives identical pixels
- [ ] Each word appears on its timestamp ±1 frame
- [ ] You scrubbed the start, middle and end of every beat and nothing overlaps, clips or jumps

Before writing code, restate the beat list with frame numbers. Then build it in one pass.

More like this

16:9

Showreel — beat-synced cuts

Kinetic type · addmotion studio
16:9

Kinetic headline stagger

Kinetic type · Kinetic Lab (demo)
16:9

Split-line text reveal

Kinetic type · Kinetic Lab (demo)
16:9

RGB glitch title

Kinetic type · Kinetic Lab (demo)
Lyric video — word-synced karaoke type · addmotion