Add a broad set of new pattern modules and matching pattern smoke scripts so the new effects can be validated directly on-device.
58 lines
1.9 KiB
Python
58 lines
1.9 KiB
Python
import utime
|
|
|
|
|
|
class GradientScroll:
|
|
def __init__(self, driver):
|
|
self.driver = driver
|
|
|
|
def _render(self, colors, phase, brightness):
|
|
num_leds = self.driver.num_leds
|
|
color_count = len(colors)
|
|
if num_leds <= 0 or color_count <= 0:
|
|
return
|
|
if color_count == 1:
|
|
self.driver.fill(self.driver.apply_brightness(colors[0], brightness))
|
|
return
|
|
|
|
full_span = color_count * 256
|
|
phase_shift = (phase * full_span) // 256
|
|
for i in range(num_leds):
|
|
pos = ((i * full_span) // num_leds + phase_shift) % full_span
|
|
idx = pos // 256
|
|
frac = pos & 255
|
|
|
|
c1 = colors[idx]
|
|
c2 = colors[(idx + 1) % color_count]
|
|
blended = (
|
|
c1[0] + ((c2[0] - c1[0]) * frac) // 256,
|
|
c1[1] + ((c2[1] - c1[1]) * frac) // 256,
|
|
c1[2] + ((c2[2] - c1[2]) * frac) // 256,
|
|
)
|
|
self.driver.n[i] = self.driver.apply_brightness(blended, brightness)
|
|
self.driver.n.write()
|
|
|
|
def run(self, preset):
|
|
"""Scrolling blended gradient.
|
|
|
|
n1: phase step amount (default 1)
|
|
"""
|
|
colors = preset.c if preset.c else [(255, 0, 0), (0, 0, 255)]
|
|
phase = self.driver.step % 256
|
|
step_amount = max(1, int(preset.n1) if int(preset.n1) > 0 else 1)
|
|
last_update = utime.ticks_ms()
|
|
|
|
while True:
|
|
delay_ms = max(1, int(preset.d))
|
|
now = utime.ticks_ms()
|
|
if utime.ticks_diff(now, last_update) >= delay_ms:
|
|
self._render(colors, phase, preset.b)
|
|
phase = (phase + step_amount) % 256
|
|
self.driver.step = phase
|
|
last_update = utime.ticks_add(last_update, delay_ms)
|
|
|
|
if not preset.a:
|
|
yield
|
|
return
|
|
|
|
yield
|