Skip to content

feat(pool): Rotate — a constant slow turn of the whole pool, under every mode - #131

Merged
pyramation merged 1 commit into
mainfrom
feat/pool-rotate
Sep 19, 2026
Merged

pyramation merged 1 commit into
mainfrom
feat/pool-rotate

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

A Rotate slider for the Pool: a constant, slow carousel of the whole field about the layout centre, layered under Flow / Spiral / Droplets and under the stirred current. It's a parameter rather than a mode so it composes: Hold + Rotate is a painted picture that orbits; Droplets + Rotate is ripples on a turning pond. Spiral (gesture-shaped, settles) and the current (stirred, decays) are unchanged — Rotate is the one thing that keeps turning on its own.

@wavegrid/pool

PoolSettings.rotate?: number   // -1..1, default 0; sign = direction (positive = clockwise on screen)
ROTATE_LAP_SECONDS = 20        // full deflection = one lap in 20 s
rotateOmega(r) = clamp(r,-1,1) * 2π / ROTATE_LAP_SECONDS

In PoolField.step, rotOmega eases toward rotateOmega(settings.rotate) on a 3 s clock (so moving the slider never jerks the lights), and every source — blobs and droplet rings — is rotated about (0.5, 0.5) by rotOmega·dt after its own motion. Uses the layout square's centre, not the fixtures, so it works for any configured layout.

Server

pool_settings accepts rotate, clamped to −1..1, non-numbers ignored; persisted with the other Pool settings, echoed to all UIs.

UI

Bipolar slider in the Pool group (centre = off, double-click resets), readout shows ↻/↺ and magnitude. app.tsx includes rotate in the server-echo comparison so other iPads' changes propagate.

Tests

  • pool: rotate: 1 carries a held spot ~a quarter lap in 5 s (minus the ease-in), radius preserved; -0.5 goes the other way; 0 stays put.
  • server: clamp (-3 → -1) and type validation ('fast' ignored).

Link to Devin session: https://app.devin.ai/sessions/c4872c2982734093bdee80d04a7d5ceb
Open in Devin Desktop: https://app.devin.ai/desktop/session/c4872c2982734093bdee80d04a7d5ceb?variant=devin
Requested by: @pyramation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@tenki-reviewer

tenki-reviewer Bot commented Sep 19, 2026

Copy link
Copy Markdown

Review complete. No blocking issues — approved ✅; 1 nitpick below.

🧹 Nitpicks (1) — 🟢 1 low
  • 🟢 Orphaned spiral comment above rotateOmega (pool-field.ts:164) — Inserting rotateOmega (pool-field.ts:166) and its doc comment between the pre-existing spiral-spin comment and spiralOmega orphaned that comment, so it now sits above rotateOmega (where its 'a lap takes 20s to 2min' text is wrong — rotateOmega always laps in ROTATE_LAP_SECONDS) while spiralOmega at line 170 is left without its description.

This PR introduces per-source rotation (rotateOmega), spiral-drift motion, and expanded pool settings on both sides of the wire, plus UI controls on the pool tab. The server validates and clamps the new numeric rotate setting (falling back to the previous value), broadcasts the extended pool_settings DTO, and tests cover the new field.

Files Change
packages/pool/src/pool-field.ts + test Adds rotateOmega/spiral-drift motion math and its unit tests.
packages/server/src/server.ts + test Broadens pool_settings DTO with rotate validation/clamping and broadcast.
packages/ui/src/app.tsx, pool-tab.tsx Adds rotate/spread/turn UI controls wired to the new settings.

Reviewers focused on correctness, the realtime messaging schema, and the animation math. The one low-severity issue is a displaced JSDoc comment that now misdescribes rotateOmega and leaves spiralOmega undocumented; no functional defects were confirmed, so this is a merge-with-comment rather than a request for changes.

Reviewed commit: 6be5add

@pyramation
pyramation merged commit a0e3feb into main Sep 19, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant