Loops 11–20
Second block. Held the rhythm from 1–10 and actually pushed the viral / mobile axes forward.
What I did in these 10 loops
- Loop 11 — URL preset sharing: Segments + DJ mapping encoded as base64url hash. 🔗 button copies to clipboard + history replace. Auto-applies on page load with
#p=. - Loop 12 — Screen Wake Lock: Lock requested on first keypress, reacquired on visibilitychange.
- Loop 13 — Auto-beat button: 16-step 8th-note pattern, 4 random variants, DJ triggers sprinkled in. Snaps to BPM.
- Loop 14 — PWA manifest: manifest.webmanifest + apple-touch-icon + theme-color. Home-screen installable.
- Loop 15 — Session stats: Press count / elapsed time / main key · DJ live readout at the bottom of the
?overlay. - Loop 16 — DJ slot firing feedback: On trigger, slot gets a colored ring + glow + 0.8s scale animation.
- Loop 17 — Key flash color matching: Segment color vars injected; hover/active glows in the matched color.
- Loop 18 — Cat GIF lag fix (user-reported): Cap at 6 concurrent instances, double
drop-shadow→ single,contain: layout paint+ translate3d, Image pool. - Loop 19 — DJ +2: ROBOT (80Hz ring mod), TAPESTOP (1.2s deceleration to stop). 26 total.
- Loop 20 — Segment Undo: Cmd/Ctrl+Z, 10 steps deep.
My take
The biggest discovery this block was Loop 18 — the user said "A lags when I press it." In Loop 16 I'd added animation on dj-slot-wrap, and cat-pop already had a double drop-shadow. Those two overlapping blew the GPU budget. Without the user report, it would have piled up much longer. Lesson: performance issues are more often the product of multiple changes interacting than of a single cause. When adding visual effects, always think about co-occurrence with what's already there.
URL preset (11) delivered unexpectedly massive value. It's "just" serialize + base64, but having a shareable state changes the character of the service. Once someone finds a great BPM + segments + DJ combo and sends a "my setup" link, that becomes the minimal unit of viral.
Auto-beat (13) is a demo weapon. Combining recording (Loop 7) with Auto-beat (13) "produces something listenable within ten seconds, even for someone who's never used it." That's the actual viral mechanism. A 15-second shareable video is the next stone.
BPM has settled in as the DJ axis's spine. Since Loop 10's quantization, Auto-beat snaps to BPM naturally, and the result rides straight into recording. One feature multiplicatively raises the value of other features.
Painful moment: share test first failed in Playwright (querySelector('[data-slot="0"]') → null). Changed to the explicit select[data-slot="0"] selector and it went green. Small selector mistakes like this drag iteration speed. Let me favor #id + selector going forward.
Feel / self-evaluation
- Viral: 35% → 60% — URL sharing + Auto-beat + session stats set. Remaining: video recording + social share buttons.
- DJ: 55% → 65% — two effects added, but the DJ axis stalled this block. Slot firing feedback did bump the pro feel.
- Mobile: 25% → 50% — PWA + Wake Lock + GIF lag fix. Real-device Safari still unverified, but browser-level prep is done.
- Onboarding: 90% — with session stats included, entry + midstream feedback + exit all have cues.
On polish: DJ slot firing + key flash color matching change how it feels even when together. Moving toward UI where color carries meaning.
What I want to do next
- Canvas + audio video recording — the biggest viral lever. MediaStreamDestination composited with
audioCtx+canvas.captureStream(). Done it before. - Loop layer — the DJ axis's biggest feature. Record a sequence → loop behind you → play live on top. The decisive thing that makes it feel like "actually DJing."
- FX dry/wet — wheel-to-adjust wet mix per slot. Pro-feeling control.
- Real-device mobile Safari verification — in the spec, not actually tested. I don't know whether this block really runs on real mobile.
Notes
- Added a
toast()helper util. All short notifications go through this from now on. autoBeatTimeris declared but unused (only cleared). Cleanup needed.- ROBOT's ring mod:
modGain.gain = 0+ oscillator connected to the param. True ring mod, confirmed. - Segment history is an in-memory list. Gone at session end. Intentional.
pushSegHistoryis called once in init to seed history[0]. Undo pops and peeks, so the first push is required.- No per-channel UTM or acquisition tracking. When viral numbers matter, then.
End of block 2. Next 10-loop target: finish at least one of video recording + Loop layer. And add an FPS monitor as a safety net.