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

  1. Canvas + audio video recording — the biggest viral lever. MediaStreamDestination composited with audioCtx + canvas.captureStream(). Done it before.
  2. 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."
  3. FX dry/wet — wheel-to-adjust wet mix per slot. Pro-feeling control.
  4. 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.
  • autoBeatTimer is 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.
  • pushSegHistory is 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.