feat: add math_wave color strip source type
Lint & Test / test (push) Has been cancelled

Mathematical wave generator that produces per-LED colors from
configurable waveform layers (sine, triangle, sawtooth, square) with
superposition, mapped through a gradient palette. Supports sync clocks,
bindable speed, and up to 8 wave layers.

- Storage model with wave validation and apply_update
- Numpy-vectorized stream with gradient LUT color mapping
- API schemas (create/update/response) and route registration
- Frontend editor with dynamic wave layer rows, gradient picker,
  speed widget, and IconSelect waveform selectors
- i18n in en/ru/zh
This commit is contained in:
2026-04-05 00:41:07 +03:00
parent edc6d27e2e
commit ace24715c8
16 changed files with 977 additions and 5 deletions
@@ -39,6 +39,7 @@
<option value="processed" data-i18n="color_strip.type.processed">Processed</option>
<option value="key_colors" data-i18n="color_strip.type.key_colors">Key Colors</option>
<option value="game_event" data-i18n="color_strip.type.game_event">Game Event</option>
<option value="math_wave" data-i18n="color_strip.type.math_wave">Math Wave</option>
</select>
</div>
@@ -730,6 +731,38 @@
</div>
</div>
<!-- Math Wave section -->
<div id="css-editor-math-wave-section" style="display:none">
<div class="form-group">
<div class="label-row">
<label data-i18n="color_strip.math_wave.gradient">Color Gradient:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="color_strip.math_wave.gradient.hint">The gradient used to color the wave output. Wave values are mapped to positions along this gradient.</small>
<select id="css-editor-math-wave-gradient"></select>
<div id="css-editor-math-wave-gradient-container"></div>
</div>
<div class="form-group">
<div class="label-row">
<label><span data-i18n="color_strip.math_wave.speed">Speed:</span></label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="color_strip.math_wave.speed.hint">Animation speed multiplier. Higher values make the wave move faster.</small>
<div id="css-editor-math-wave-speed-container"></div>
</div>
<div class="form-group">
<div class="label-row">
<label data-i18n="color_strip.math_wave.waves">Wave Layers:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="color_strip.math_wave.waves.hint">Add multiple wave layers that are combined together. Each wave has its own waveform, frequency, amplitude, phase and offset.</small>
<div id="css-editor-math-wave-layers"></div>
<button type="button" class="btn btn-secondary btn-sm" onclick="mathWaveAddLayer()" style="margin-top:6px">
<span data-i18n="color_strip.math_wave.add_wave">+ Add Wave</span>
</button>
</div>
</div>
<!-- Shared LED count field -->
<div id="css-editor-led-count-group" class="form-group">
<div class="label-row">