UNPKG

@ginden/blinkstick-v2

Version:
86 lines 3.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.wave = wave; const complex_frame_1 = require("../frame/complex-frame"); const tsafe_1 = require("tsafe"); /** * @summary Build wave effect * * @remarks Build wave effect by time-line stitching – this guarantees the overall * duration is exactly: * animationDuration + lagMs × (ledCount - 1) * and avoids the subtle frame-cutting rules of * `convertSimpleFramesToComplexFrame`. * @experimental * @category Animation */ function wave(animation, { fillWith = [0, 0, 0], ledCount, lagMs }) { (0, tsafe_1.assert)(ledCount > 0, 'ledCount must be greater than 0'); (0, tsafe_1.assert)(lagMs >= 0, 'lagMs must be greater than or equal to 0'); const srcFrames = Array.isArray(animation) ? animation.slice() : Array.from(animation); if (srcFrames.length === 0) { return []; } // Pre-compute cumulative end-times of the source animation (relative to its // own start, i.e. LED-0). const cumulativeEnds = [0]; for (const f of srcFrames) cumulativeEnds.push(cumulativeEnds.at(-1) + f.duration); // Collect every timestamp at which *any* LED may change colour. const changeTs = []; for (let led = 0; led < ledCount; led += 1) { const offset = led * lagMs; for (const t of cumulativeEnds) changeTs.push(offset + t); } changeTs.sort((a, b) => a - b); // de-dupe const uniq = []; for (const t of changeTs) if (uniq[uniq.length - 1] !== t) uniq.push(t); // Helper: colour of given LED at (inclusive) time `t`. function colourAt(led, t) { const start = led * lagMs; if (t < start) return [...fillWith]; let rel = t - start; for (const f of srcFrames) { if (rel < f.duration) return f.rgb; rel -= f.duration; } return srcFrames[srcFrames.length - 1].rgb; } return { *[Symbol.iterator]() { const MIN_MS = 10; // do not emit frames shorter than this let prev = null; for (let i = 0; i < uniq.length - 1; i += 1) { const start = uniq[i]; const end = uniq[i + 1]; const duration = end - start; const colours = Array.from({ length: ledCount }, (_, led) => colourAt(led, start)); const frame = new complex_frame_1.ComplexFrame(colours, duration); if (!prev) { prev = frame; continue; } if (frame.duration < MIN_MS) { // Merge very short slice into previous frame to avoid excessive FPS. prev.duration += frame.duration; continue; } // Emit previous frame now that we know the current one is long enough. yield prev; prev = frame; } if (prev) { yield prev; } }, }; } //# sourceMappingURL=wave.js.map