Browse Source

add more effects

tuanchris 3 months ago
parent
commit
37f28f64c5
1 changed files with 405 additions and 0 deletions
  1. 405 0
      modules/led/dw_leds/effects/basic_effects.py

+ 405 - 0
modules/led/dw_leds/effects/basic_effects.py

@@ -675,6 +675,397 @@ def mode_juggle(seg: Segment) -> int:
 
 
     return FRAMETIME
     return FRAMETIME
 
 
+def mode_meteor(seg: Segment) -> int:
+    """Meteor shower effect with trails"""
+    if seg.call == 0:
+        seg.aux0 = 0
+        seg.aux1 = 0
+
+    # Fade all pixels
+    seg.fade_out(200)
+
+    size = 1 + ((seg.intensity * seg.length) >> 8)
+    cycle_time = 10 + (255 - seg.speed)
+    iteration = seg.now() // cycle_time
+
+    if iteration != seg.step:
+        seg.aux0 = (seg.aux0 + 1) % (seg.length + size)
+        seg.step = iteration
+
+    # Draw meteor head and tail
+    if seg.aux0 < seg.length:
+        for i in range(size):
+            pos = seg.aux0 - i
+            if 0 <= pos < seg.length:
+                brightness = 255 - (i * 200 // max(1, size))
+                color = color_blend(0, seg.color_from_palette(pos), brightness)
+                # Add to existing color for brighter effect
+                existing = seg.get_pixel_color(pos)
+                seg.set_pixel_color(pos, color_add(existing, color))
+
+    return FRAMETIME
+
+def mode_pride(seg: Segment) -> int:
+    """Pride flag colors moving effect"""
+    counter = seg.now() * ((seg.speed >> 3) + 1)
+
+    # Pride flag colors (6 stripes)
+    pride_colors = [
+        (0xE4, 0x00, 0x3A),  # Red
+        (0xFF, 0x8C, 0x00),  # Orange
+        (0xFF, 0xED, 0x00),  # Yellow
+        (0x00, 0x81, 0x1F),  # Green
+        (0x00, 0x4C, 0xFF),  # Blue
+        (0x76, 0x01, 0x89),  # Purple
+    ]
+
+    for i in range(seg.length):
+        # Determine which stripe this pixel belongs to
+        stripe_size = max(1, seg.length // 6)
+        offset = (counter >> 7) & 0xFF
+        stripe_idx = ((i + offset) // stripe_size) % 6
+
+        r, g, b = pride_colors[stripe_idx]
+        color = (r << 16) | (g << 8) | b
+
+        # Intensity controls blending with background
+        if seg.intensity < 255:
+            color = color_blend(seg.get_color(1), color, seg.intensity)
+
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_pacifica(seg: Segment) -> int:
+    """Ocean/water simulation"""
+    if seg.call == 0:
+        seg.data = [0] * seg.length
+
+    counter = seg.now() * ((seg.speed >> 4) + 1)
+
+    for i in range(seg.length):
+        # Create multiple layered waves
+        wave1 = sin8(((i * 5) + (counter >> 5)) & 0xFF)
+        wave2 = sin8(((i * 3) + (counter >> 3)) & 0xFF)
+        wave3 = sin8(((i * 7) + (counter >> 6)) & 0xFF)
+
+        # Combine waves
+        brightness = (wave1 + wave2 + wave3) // 3
+
+        # Blue-green ocean colors
+        if brightness < 64:
+            # Deep blue
+            r, g, b = 0, 0, 60 + brightness
+        elif brightness < 128:
+            # Blue-cyan
+            val = brightness - 64
+            r, g, b = 0, val * 2, 100 + val
+        else:
+            # Cyan-white (foam)
+            val = brightness - 128
+            r, g, b = val, 128 + val, 180 + (val // 2)
+
+        # Apply intensity
+        brightness = 128 + ((brightness - 128) * seg.intensity // 255)
+        color = (r << 16) | (g << 8) | b
+        color = color_blend(0, color, brightness)
+
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_plasma(seg: Segment) -> int:
+    """Plasma effect"""
+    counter = seg.now() * ((seg.speed >> 3) + 1)
+
+    for i in range(seg.length):
+        # Create plasma using multiple sine waves
+        phase1 = sin8(((i * 16) + (counter >> 5)) & 0xFF)
+        phase2 = sin8(((i * 8) + (counter >> 6)) & 0xFF)
+        phase3 = sin8((counter >> 4) & 0xFF)
+
+        # Combine phases
+        hue = (phase1 + phase2 + phase3) & 0xFF
+        color = color_wheel(hue)
+
+        # Intensity controls saturation
+        if seg.intensity < 255:
+            color = color_blend(color, WHITE, 255 - seg.intensity)
+
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_dissolve(seg: Segment) -> int:
+    """Random pixel dissolve/fade"""
+    if seg.call == 0:
+        seg.data = [0] * seg.length
+        for i in range(seg.length):
+            seg.data[i] = random.randint(0, 255)
+
+    cycle_time = 20 + (255 - seg.speed)
+    iteration = seg.now() // cycle_time
+
+    if iteration != seg.step:
+        # Randomly update some pixels
+        for i in range(seg.length):
+            if random.randint(0, 255) < seg.intensity:
+                seg.data[i] = random.randint(0, 255)
+
+        seg.step = iteration
+
+    for i in range(seg.length):
+        brightness = seg.data[i]
+        color = color_blend(seg.get_color(1),
+                          seg.color_from_palette(i),
+                          brightness)
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_glitter(seg: Segment) -> int:
+    """Sparkle glitter overlay"""
+    # Fill with base color
+    for i in range(seg.length):
+        seg.set_pixel_color(i, seg.color_from_palette(i))
+
+    # Add random sparkles based on intensity
+    sparkle_chance = seg.intensity
+    num_sparkles = max(1, (seg.length * sparkle_chance) // 255)
+
+    for _ in range(num_sparkles):
+        if random.randint(0, 255) < seg.speed:
+            pos = random.randint(0, seg.length - 1)
+            seg.set_pixel_color(pos, WHITE)
+
+    return FRAMETIME
+
+def mode_confetti(seg: Segment) -> int:
+    """Random colored pixels"""
+    seg.fade_out(224)
+
+    cycle_time = 10 + (255 - seg.speed)
+    iteration = seg.now() // cycle_time
+
+    if iteration != seg.step:
+        # Add random confetti
+        density = 1 + (seg.intensity >> 5)
+        for _ in range(density):
+            pos = random.randint(0, seg.length - 1)
+            hue = random.randint(0, 255)
+            color = color_wheel(hue)
+            seg.set_pixel_color(pos, color)
+
+        seg.step = iteration
+
+    return FRAMETIME
+
+def mode_sinelon(seg: Segment) -> int:
+    """Sine wave colored dot"""
+    seg.fade_out(224)
+
+    counter = seg.now() * ((seg.speed >> 2) + 1)
+    phase = (counter >> 8) & 0xFFFF
+
+    # Calculate position using sine
+    pos = (sin16(phase) + 32768) * seg.length // 65536
+    pos = max(0, min(seg.length - 1, pos))
+
+    # Color rotates
+    hue = (counter >> 7) & 0xFF
+    color = color_wheel(hue)
+
+    # Intensity controls trail length (via fade)
+    if seg.intensity < 255:
+        color = color_blend(0, color, seg.intensity)
+
+    seg.set_pixel_color(pos, color)
+
+    return FRAMETIME
+
+def mode_candle(seg: Segment) -> int:
+    """Flickering candle simulation"""
+    if seg.call == 0:
+        seg.data = [128] * seg.length
+
+    # Random flicker for each pixel
+    for i in range(seg.length):
+        # Small random changes
+        change = random.randint(-20, 20)
+        seg.data[i] = max(30, min(255, seg.data[i] + change))
+
+        # Speed affects flicker rate
+        if seg.speed > 128 and random.randint(0, 255) < (seg.speed - 128):
+            seg.data[i] = random.randint(50, 200)
+
+        # Warm orange/yellow color
+        brightness = seg.data[i]
+        r = brightness
+        g = (brightness * 2) // 3
+        b = (brightness * seg.intensity) // 512  # Intensity controls blue
+
+        color = (r << 16) | (g << 8) | b
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_aurora(seg: Segment) -> int:
+    """Northern lights effect"""
+    if seg.call == 0:
+        seg.data = [0] * seg.length
+
+    counter = seg.now() * ((seg.speed >> 4) + 1)
+
+    for i in range(seg.length):
+        # Multiple slow-moving waves
+        wave1 = sin8(((i * 3) + (counter >> 6)) & 0xFF)
+        wave2 = sin8(((i * 5) + (counter >> 7) + 85) & 0xFF)
+        wave3 = sin8(((i * 2) + (counter >> 5) + 170) & 0xFF)
+
+        # Aurora colors: green, blue, purple
+        brightness = (wave1 + wave2 + wave3) // 3
+
+        if brightness < 85:
+            # Green
+            r, g, b = 0, brightness * 2, brightness // 2
+        elif brightness < 170:
+            # Blue-green
+            val = brightness - 85
+            r, g, b = 0, 100 + val, 100 + val
+        else:
+            # Purple-pink
+            val = brightness - 170
+            r, g, b = val * 2, val, 150 + val
+
+        # Apply intensity for brightness variation
+        brightness_mod = 128 + ((brightness - 128) * seg.intensity // 255)
+        color = (r << 16) | (g << 8) | b
+        color = color_blend(0, color, brightness_mod)
+
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_rain(seg: Segment) -> int:
+    """Rain drops falling"""
+    if seg.call == 0:
+        seg.data = [0] * seg.length
+        seg.aux0 = 0
+
+    seg.fade_out(235)
+
+    cycle_time = 15 + (255 - seg.speed)
+    iteration = seg.now() // cycle_time
+
+    if iteration != seg.step:
+        # New rain drops
+        if random.randint(0, 255) < seg.intensity:
+            pos = random.randint(0, min(5, seg.length - 1))  # Start near beginning
+            seg.data[pos] = 255
+
+        # Move drops down
+        new_data = [0] * seg.length
+        for i in range(seg.length - 1):
+            if seg.data[i] > 0:
+                # Drop moves forward
+                if i + 1 < seg.length:
+                    new_data[i + 1] = seg.data[i] - 10
+        seg.data = new_data
+
+        seg.step = iteration
+
+    # Draw rain drops (blue)
+    for i in range(seg.length):
+        if seg.data[i] > 0:
+            brightness = seg.data[i]
+            color = color_blend(0, seg.color_from_palette(i), brightness)
+            seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_halloween(seg: Segment) -> int:
+    """Halloween orange and purple"""
+    counter = seg.now() * ((seg.speed >> 3) + 1)
+
+    # Alternating orange and purple
+    orange = (0xFF << 16) | (0x44 << 8) | 0x00
+    purple = (0x88 << 16) | (0x00 << 8) | 0xFF
+
+    for i in range(seg.length):
+        # Create moving pattern
+        phase = ((i * 255 // max(1, seg.length)) + (counter >> 7)) & 0xFF
+        wave = sin8(phase)
+
+        # Blend between orange and purple
+        if wave < 128:
+            color = orange
+        else:
+            color = purple
+
+        # Intensity controls blending smoothness
+        if seg.intensity > 0:
+            blend_amt = (wave * seg.intensity) // 255
+            color = color_blend(orange, purple, blend_amt)
+
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_noise(seg: Segment) -> int:
+    """Perlin-like noise pattern"""
+    if seg.call == 0:
+        seg.data = [random.randint(0, 255) for _ in range(seg.length)]
+
+    cycle_time = 20 + (255 - seg.speed) // 2
+    iteration = seg.now() // cycle_time
+
+    if iteration != seg.step:
+        # Smooth noise by averaging neighbors
+        new_data = seg.data.copy()
+        for i in range(1, seg.length - 1):
+            avg = (seg.data[i - 1] + seg.data[i] * 2 + seg.data[i + 1]) // 4
+            variation = random.randint(-20, 20)
+            new_data[i] = max(0, min(255, avg + variation))
+
+        # Occasionally inject new random values
+        if random.randint(0, 255) < seg.intensity:
+            pos = random.randint(0, seg.length - 1)
+            new_data[pos] = random.randint(0, 255)
+
+        seg.data = new_data
+        seg.step = iteration
+
+    # Map noise to colors
+    for i in range(seg.length):
+        hue = seg.data[i]
+        color = color_wheel(hue)
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
+def mode_funky_plank(seg: Segment) -> int:
+    """Multiple colored bars moving"""
+    if seg.call == 0:
+        seg.aux0 = 0
+
+    cycle_time = 10 + (255 - seg.speed)
+    iteration = seg.now() // cycle_time
+
+    if iteration != seg.step:
+        seg.aux0 = (seg.aux0 + 1) % seg.length
+        seg.step = iteration
+
+    num_planks = max(2, 1 + (seg.intensity >> 5))
+    plank_size = max(1, seg.length // num_planks)
+
+    for i in range(seg.length):
+        plank_idx = ((i + seg.aux0) // plank_size) % num_planks
+        hue = (plank_idx * 256 // num_planks) & 0xFF
+        color = color_wheel(hue)
+        seg.set_pixel_color(i, color)
+
+    return FRAMETIME
+
 # Effect registry
 # Effect registry
 EFFECTS = {
 EFFECTS = {
     0: ("Static", mode_static),
     0: ("Static", mode_static),
@@ -708,6 +1099,20 @@ EFFECTS = {
     28: ("Waves", mode_waves),
     28: ("Waves", mode_waves),
     29: ("BPM", mode_bpm),
     29: ("BPM", mode_bpm),
     30: ("Juggle", mode_juggle),
     30: ("Juggle", mode_juggle),
+    31: ("Meteor", mode_meteor),
+    32: ("Pride", mode_pride),
+    33: ("Pacifica", mode_pacifica),
+    34: ("Plasma", mode_plasma),
+    35: ("Dissolve", mode_dissolve),
+    36: ("Glitter", mode_glitter),
+    37: ("Confetti", mode_confetti),
+    38: ("Sinelon", mode_sinelon),
+    39: ("Candle", mode_candle),
+    40: ("Aurora", mode_aurora),
+    41: ("Rain", mode_rain),
+    42: ("Halloween", mode_halloween),
+    43: ("Noise", mode_noise),
+    44: ("Funky Plank", mode_funky_plank),
 }
 }
 
 
 def get_effect(effect_id: int):
 def get_effect(effect_id: int):