feat(patterns): add icicles blizzard and rime winter effects
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
72
src/patterns/rime.py
Normal file
72
src/patterns/rime.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import random
|
||||
import utime
|
||||
|
||||
|
||||
class Rime:
|
||||
"""Slow frost build-up on a chilly background — gentle random brightening then decay."""
|
||||
|
||||
def __init__(self, driver):
|
||||
self.driver = driver
|
||||
|
||||
def run(self, preset):
|
||||
colors = preset.c if preset.c else [(220, 235, 255), (255, 255, 255), (185, 220, 255)]
|
||||
num = self.driver.num_leds
|
||||
if num <= 0:
|
||||
while True:
|
||||
yield
|
||||
return
|
||||
|
||||
# n1: spawn tendency (like twinkle upper range)
|
||||
chill = max(1, min(255, int(preset.n1) if int(preset.n1) > 0 else 36))
|
||||
# n2: decay per refresh (subtract from glow buffer)
|
||||
melt = max(1, min(255, int(preset.n2) if int(preset.n2) > 0 else 12))
|
||||
# n3: how many LEDs can flash brighter per refresh (cap)
|
||||
spark_cap = max(1, min(num, int(preset.n3) if int(preset.n3) > 0 else 3))
|
||||
|
||||
glow = [0] * num
|
||||
last = utime.ticks_ms()
|
||||
|
||||
while True:
|
||||
d_ms = max(1, int(preset.d))
|
||||
now = utime.ticks_ms()
|
||||
if utime.ticks_diff(now, last) >= d_ms:
|
||||
base_bg = preset.background_or(colors)
|
||||
bg = self.driver.apply_brightness(base_bg, preset.b)
|
||||
|
||||
for i in range(num):
|
||||
if glow[i] > melt:
|
||||
glow[i] -= melt
|
||||
else:
|
||||
glow[i] = 0
|
||||
|
||||
spawned = 0
|
||||
tries = spark_cap + num // 8
|
||||
for _ in range(tries):
|
||||
if spawned >= spark_cap:
|
||||
break
|
||||
if random.randint(0, 255) >= chill:
|
||||
continue
|
||||
j = random.randint(0, num - 1)
|
||||
glow[j] = min(255, glow[j] + random.randint(80, 200))
|
||||
spawned += 1
|
||||
|
||||
palette = colors
|
||||
for i in range(num):
|
||||
g = glow[i]
|
||||
fg = palette[i % len(palette)]
|
||||
hi = self.driver.apply_brightness(fg, preset.b)
|
||||
mix = max(0, min(255, g))
|
||||
self.driver.n[i] = (
|
||||
(hi[0] * mix + bg[0] * (255 - mix)) // 255,
|
||||
(hi[1] * mix + bg[1] * (255 - mix)) // 255,
|
||||
(hi[2] * mix + bg[2] * (255 - mix)) // 255,
|
||||
)
|
||||
|
||||
self.driver.n.write()
|
||||
last = utime.ticks_add(last, d_ms)
|
||||
|
||||
if not preset.a:
|
||||
yield
|
||||
return
|
||||
|
||||
yield
|
||||
Reference in New Issue
Block a user