RipplesEffectModule¶
A 2D radial sine-wave ripple effect. Writes animated concentric coloured rings into a EffectsLayer each
loop(). Introduced in Release 3, Sprint 1.
What it does¶
On each loop() call, RipplesEffectModule draws a single dancing sine-wave curve across the 2D pixel grid. The algorithm is a direct port of MoonLight's 3D Ripples effect projected onto a 2D display:
d = |x − width/2| / 9.899495 × height
phase = d / ripple_interval + time_interval
y = floor(height/2 × (1 + sin(phase)))
For each x column exactly one pixel is lit at the computed y row. The buffer is cleared to black each frame so only the wave curve is visible. Colour cycles through a hue wheel over time (HSV, saturation and value at full), giving the wave a shifting rainbow colour similar to MoonLight's palette sampling.
Controls¶
| Parameter | Source | Default | Description |
|---|---|---|---|
layer |
setInput("layer", ...) |
— | EffectsLayer* to write into; width/height come from the layer |
speed |
setProps / loadState |
50 | Animation speed (0 = stopped, 99 = fast) |
interval |
setProps / loadState |
128 | Wavefront spacing — low = tight ripples, high = wide rings (1–255) |
enabled |
auto (StatefulModule) | true | When false, loop() is skipped |
layer is a data-flow input wired by the ModuleManager before setup() via the "inputs" field in state/modulemanager.json. speed and interval are persisted controls saved to state/<id>.json.
Platform notes¶
Uses sqrtf, sinf, fmodf. The module owns no pixel memory — allocation is in EffectsLayer. On ESP32, the FPU handles the per-pixel float math; ripple_interval and time_interval are hoisted out of the inner loop so only sqrtf + sinf run per pixel.
Test coverage¶
Live pipeline: test1 — Ripples pipeline — full DriverLayer + GridLayout + EffectsLayer + RipplesEffectModule pipeline verified on PC and ESP32; non-zero checksums asserted each run.