Back to Tasmota

Berry Animation Framework - Class Hierarchy and Parameters Reference

lib/libesp32/berry_animation/animation_docs/Animation_Class_Hierarchy.md

15.4.042.6 KB
Original Source

Berry Animation Framework - Class Hierarchy and Parameters Reference

This document provides a comprehensive reference for all classes in the Berry Animation Framework that extend parameterized_object, including their parameters and factory functions.

Table of Contents

  1. Class Hierarchy
  2. Base Classes
  3. Value Providers
  4. Color Providers
  5. Animation Classes
  6. Parameter Constraints

Class Hierarchy

parameterized_object (base class with parameter management and playable interface)
│
├── Animation (unified base class for all visual elements)
│   ├── engine_proxy (combines rendering and orchestration)
│   │   └── (user-defined template animations)
│   ├── solid (solid color fill)
│   ├── crenel (crenel/square wave pattern)
│   ├── breathe (breathing effect)
│   ├── beacon (pulse at specific position)
│   │   └── gradient (linear/radial color gradients)
│   ├── palette_gradient (gradient patterns with palette colors)
│   │   └── palette_meter (VU meter with gradient colors and peak hold)
│   ├── comet (moving comet with tail)
│   ├── twinkle (twinkling stars effect)
│   └── rich_palette (smooth palette transitions)
│
├── sequence_manager (orchestrates animation sequences)
│
└── Value Providers (VALUE_PROVIDER = true)
    │
    ├── static_value (wraps static values)
    ├── strip_length (provides LED strip length)
    ├── iteration_number (provides sequence iteration number)
    ├── oscillator_value (oscillating values with waveforms)
    ├── closure_value (computed values, internal use only)
    │
    └── Color Providers
        ├── color_provider (solid color, base for color providers)
        ├── breathe_color (breathing color effect with internal oscillator)
        ├── color_cycle (cycles through palette)
        └── rich_palette_color (smooth palette transitions)

Note: Supplementary animations (fire, wave, plasma, sparkle, etc.) are available in animations_future/ but not included in the standard build.

Note on Value Providers: Value providers inherit directly from parameterized_object and are identified by the static class variable VALUE_PROVIDER = true. Use animation.is_value_provider(obj) to check if an object is a value provider. This flat hierarchy reduces class overhead while maintaining clear semantic distinction.

Base Classes

parameterized_object

Base class for all parameterized objects in the framework. Provides parameter management with validation, storage, and retrieval, as well as the playable interface for lifecycle management (start/stop/update).

This unified base class enables:

  • Consistent parameter handling across all framework objects
  • Unified engine management (animations and sequences treated uniformly)
  • Hybrid objects that combine rendering and orchestration
  • Consistent lifecycle management (start/stop/update)
ParameterTypeDefaultConstraintsDescription
is_runningboolfalse-Whether the object is active

Key Methods:

  • start(time_ms) - Start the object at a specific time
  • stop() - Stop the object
  • update(time_ms) - Update object state based on current time (no return value)

Factory: N/A (base class)

Animation

Unified base class for all visual elements. Inherits from parameterized_object.

ParameterTypeDefaultConstraintsDescription
idstring"animation"-Optional name for the animation
is_runningboolfalse-Whether the animation is active
priorityint100-255Rendering priority (higher = on top)
durationint0min: 0Animation duration in ms (0 = infinite)
loopboolfalse-Whether to loop when duration is reached
opacityany255-Animation opacity (number, frame_buffer, or Animation)
colorint0xFFFFFFFF-Base color in ARGB format

Special Behavior: Setting is_running = true/false starts/stops the animation.

Timing Behavior: The start() method only resets the time origin if the animation was already started previously (i.e., self.start_time is not nil). The first actual rendering tick occurs in update() or render() methods, which initialize start_time on first call.

Factory: animation.animation(engine)

engine_proxy

A specialized animation class that combines rendering and orchestration capabilities. Extends Animation and can contain child animations and sequences. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
(inherits all Animation parameters)

Key Features:

  • Can render visual content like a regular animation
  • Can orchestrate sub-animations and sequences using add()
  • Enables complex composite effects
  • Used as base class for template animations

Child Management:

  • add(obj) - Adds a child animation or sequence
  • remove(obj) - Removes a child
  • Children are automatically started/stopped with parent
  • Children are rendered in priority order (higher priority on top)

Use Cases:

  • Composite effects combining multiple animations
  • Template animations with parameters
  • Complex patterns with timing control
  • Reusable animation components

Factory: animation.engine_proxy(engine)

Template Animations

Template animations are user-defined classes that extend engine_proxy, created using the DSL's template animation syntax. They provide reusable, parameterized animation patterns.

DSL Definition:

berry
template animation shutter_effect {
  param colors type palette nillable true
  param duration type time min 0 max 3600 default 5 nillable false
  
  # Animation definition with sequences, colors, etc.
  # Parameters accessed as self.colors, self.duration
}

Generated Class Structure:

berry
class shutter_effect_animation : animation.engine_proxy
  static var PARAMS = animation.enc_params({
    "colors": {"type": "palette", "nillable": true},
    "duration": {"type": "time", "min": 0, "max": 3600, "default": 5, "nillable": false}
  })
  
  def init(engine)
    super(self).init(engine)
    # Generated code with self.colors and self.duration references
    # Uses self.add() for sub-animations and sequences
  end
end

Parameter Constraints: Template animation parameters support all standard constraints:

  • type - Parameter type (palette, time, int, color, etc.)
  • min - Minimum value (for numeric types)
  • max - Maximum value (for numeric types)
  • default - Default value
  • nillable - Whether parameter can be nil (true/false)

Implicit Parameters: Template animations automatically inherit parameters from the engine_proxy class hierarchy without explicit declaration:

  • id (string, default: "animation") - Animation name
  • priority (int, default: 10) - Rendering priority
  • duration (int, default: 0) - Animation duration in milliseconds
  • loop (bool, default: false) - Whether animation loops
  • opacity (int, default: 255) - Animation opacity (0-255)
  • color (int, default: 0) - Base color value
  • is_running (bool, default: false) - Running state

These parameters can be used directly in template animation bodies without declaration:

berry
template animation fade_effect {
  param colors type palette
  
  # 'duration' is implicit - no need to declare
  set oscillator = sawtooth(min_value=0, max_value=255, duration=duration)
  
  color col = color_cycle(colors=colors, period=0)
  animation test = solid(color=col)
  test.opacity = oscillator  # 'opacity' is also implicit
  
  run test
}

Usage:

berry
# Create instance with parameters
palette rainbow = [red, orange, yellow, green, blue]
animation my_shutter = shutter_effect(colors=rainbow, duration=2s)
run my_shutter

Key Differences from Regular Animations:

  • Defined in DSL, not Berry code
  • Parameters accessed as self.<param> instead of direct variables
  • Uses self.add() for composition
  • Can be instantiated multiple times with different parameters
  • Automatically registered as animation constructors

Factory: User-defined (e.g., shutter_effect(engine))

Value Providers

Value providers generate dynamic values over time for use as animation parameters. They inherit directly from parameterized_object and are identified by the static class variable VALUE_PROVIDER = true.

Identifying Value Providers: Use animation.is_value_provider(obj) to check if an object is a value provider. This function checks for the VALUE_PROVIDER = true static variable.

Creating Custom Value Providers: To create a custom value provider, inherit from parameterized_object and set static var VALUE_PROVIDER = true:

berry
class my_custom_provider : animation.parameterized_object
  static var VALUE_PROVIDER = true
  
  def produce_value(name, time_ms)
    # Return computed value based on time
    return computed_value
  end
end

Common Value Provider Interface

All value providers share these characteristics from parameterized_object:

ParameterTypeDefaultConstraintsDescription
(none specific)---Value providers typically have no base parameters

Key Method:

  • produce_value(name, time_ms) - Returns a value for the given parameter name at the specified time

Timing Behavior: For value providers, start() is typically not called because instances can be embedded in closures. Value providers consider the first call to produce_value() as the start of their internal time reference. The start() method only resets the time origin if the provider was already started previously (i.e., self.start_time is not nil).

Update Method: The update(time_ms) method does not return any value. Subclasses should check self.is_running to determine if the object is still active.

static_value

Wraps static values to provide value_provider interface. Inherits from parameterized_object with VALUE_PROVIDER = true.

ParameterTypeDefaultConstraintsDescription
valueanynil-The static value to return

Factory: animation.static_value(engine)

strip_length

Provides access to the LED strip length as a dynamic value. Inherits from parameterized_object with VALUE_PROVIDER = true.

ParameterTypeDefaultConstraintsDescription
(none)---No parameters - strip length obtained from engine

Usage: Returns the 1D length of the LED strip in pixels. Useful for animations that need to know the strip dimensions for positioning, scaling, or boundary calculations.

Factory: animation.strip_length(engine)

oscillator_value

Generates oscillating values using various waveforms. Inherits from parameterized_object with VALUE_PROVIDER = true.

ParameterTypeDefaultConstraintsDescription
min_valueint0-Minimum oscillation value
max_valueint255-Maximum oscillation value
durationint1000min: 1Oscillation period in milliseconds
formint1enum: [1,2,3,4,5,6,7,8,9]Waveform type
phaseint00-255Phase shift in 0-255 range (mapped to duration)
duty_cycleint1270-255Duty cycle for square/triangle waves in 0-255 range

Waveform Constants:

  • 1 (SAWTOOTH) - Linear ramp from min to max
  • 2 (TRIANGLE) - Linear ramp from min to max and back
  • 3 (SQUARE) - Square wave alternating between min and max
  • 4 (COSINE) - Smooth cosine wave
  • 5 (SINE) - Pure sine wave
  • 6 (EASE_IN) - Quadratic acceleration
  • 7 (EASE_OUT) - Quadratic deceleration
  • 8 (ELASTIC) - Spring-like overshoot and oscillation
  • 9 (BOUNCE) - Ball-like bouncing with decreasing amplitude

Timing Behavior: The start_time is initialized on the first call to produce_value(). The start() method only resets the time origin if the oscillator was already started previously (i.e., self.start_time is not nil).

Factories: animation.ramp(engine), animation.sawtooth(engine), animation.linear(engine), animation.triangle(engine), animation.smooth(engine), animation.sine_osc(engine), animation.cosine_osc(engine), animation.square(engine), animation.ease_in(engine), animation.ease_out(engine), animation.elastic(engine), animation.bounce(engine), animation.oscillator_value(engine)

See Also: Oscillation Patterns - Visual examples and usage patterns for oscillation waveforms

closure_value

⚠️ INTERNAL USE ONLY - NOT FOR DIRECT USE

Wraps a closure/function as a value provider for internal transpiler use. This class is used internally by the DSL transpiler to handle computed values and should not be used directly by users. Inherits from parameterized_object with VALUE_PROVIDER = true.

ParameterTypeDefaultConstraintsDescription
closurefunctionnil-The closure function to call for value generation

Internal Usage: This provider is automatically created by the DSL transpiler when it encounters computed expressions or arithmetic operations involving value providers. The closure is called with (self, param_name, time_ms) parameters.

Mathematical Helper Methods

The closure_value includes built-in mathematical helper methods that can be used within closures for computed values:

MethodDescriptionParametersReturn TypeExample
min(a, b, ...)Minimum of two or more valuesa, b, *args: numbernumberanimation._math.min(5, 3, 8)3
max(a, b, ...)Maximum of two or more valuesa, b, *args: numbernumberanimation._math.max(5, 3, 8)8
abs(x)Absolute valuex: numbernumberanimation._math.abs(-5)5
round(x)Round to nearest integerx: numberintanimation._math.round(3.7)4
sqrt(x)Square root with integer handlingx: numbernumberanimation._math.sqrt(64)128 (for 0-255 range)
scale(v, from_min, from_max, to_min, to_max)Scale value between rangesv, from_min, from_max, to_min, to_max: numberintanimation._math.scale(50, 0, 100, 0, 255)127
sin(angle)Sine function (0-255 input range)angle: numberintanimation._math.sin(64)255 (90°)
cos(angle)Cosine function (0-255 input range)angle: numberintanimation._math.cos(0)-255 (matches oscillator behavior)

Mathematical Method Notes:

  • Integer Handling: sqrt() treats integers in 0-255 range as normalized values (255 = 1.0)
  • Angle Range: sin() and cos() use 0-255 input range (0-360 degrees)
  • Output Range: Trigonometric functions return -255 to 255 (mapped from -1.0 to 1.0)
  • Cosine Behavior: Matches oscillator COSINE waveform (starts at minimum, not maximum)
  • Scale Function: Uses tasmota.scale_int() for efficient integer scaling

Closure Signature

Closures used with closure_value must follow this signature:

berry
def closure_func(engine, param_name, time_ms)
  # engine: AnimationEngine reference
  # param_name: Name of the parameter being computed
  # time_ms: Current time in milliseconds
  return computed_value
end

Usage in Computed Values

These methods are automatically available in DSL computed expressions:

berry
# Example: Dynamic brightness based on strip position
set strip_len = strip_length()
animation pulse = breathe(
  color=red
  brightness=strip_len / 4 + 50    # Uses built-in arithmetic
)

# Complex mathematical expressions are automatically wrapped in closures
# that have access to all mathematical helper methods

Factory: animation.closure_value(engine) (internal use only)

Note: Users should not create closure_value instances directly. Instead, use the DSL's computed value syntax which automatically creates these providers as needed.

Color Providers

Color providers generate dynamic colors over time. They inherit from parameterized_object with VALUE_PROVIDER = true, providing color-specific functionality while maintaining the value provider interface.

color_provider

Base class for color providers that returns a solid color. Inherits from parameterized_object with VALUE_PROVIDER = true. Can be used directly for static colors or subclassed for dynamic color generation.

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-The color to return (32-bit ARGB value)
brightnessint2550-255Overall brightness scaling

Static Methods:

  • apply_brightness(color, brightness) - Applies brightness scaling to a color (ARGB format). Only performs scaling if brightness is not 255 (full brightness). This is a static utility method that can be called without an instance.

Factory: animation.color_provider(engine)

Usage Examples

berry
# Using predefined colors
color static_red = color_provider(color=red)
color static_blue = color_provider(color=blue)

# Using hex colors
color static_orange = color_provider(color=0xFF8C00)

# Using custom defined colors
color accent = 0xFF6B35
color static_accent = color_provider(color=accent)

color_cycle

Cycles through a palette of colors with brutal switching. Inherits from color_provider.

ParameterTypeDefaultConstraintsDescription
colorsbytesdefault palette-Palette bytes in AARRGGBB format
periodint5000min: 0Cycle time in ms (0 = manual only)
nextint0-Write 1 to move to next color manually, or any number to go forward or backwards by n colors
palette_sizeint3read-onlyNumber of colors in the palette (automatically updated when palette changes)
(inherits brightness from color_provider)

Note: The get_color_for_value() method accepts values in the 0-255 range for value-based color mapping.

Modes: Auto-cycle (period > 0) or Manual-only (period = 0)

Usage Examples

berry
# RGB cycle with brutal switching
color rgb_cycle = color_cycle(
  colors=bytes("FF0000FF" "FF00FF00" "FFFF0000"),
  period=4s
)

# Custom warm colors
color warm_cycle = color_cycle(
  colors=bytes("FF4500FF" "FF8C00FF" "FFFF00"),
  period=3s
)

# Mixed colors in AARRGGBB format
color mixed_cycle = color_cycle(
  colors=bytes("FFFF0000" "FF00FF00" "FF0000FF"),
  period=2s
)

rich_palette_color

Generates colors from predefined palettes with smooth transitions and professional color schemes. Inherits from color_provider.

ParameterTypeDefaultConstraintsDescription
colorsbytesrainbow palette-Palette bytes or predefined palette constant
periodint5000min: 0Cycle time in ms (0 = value-based only)
transition_typeintanimation.LINEARenum: [animation.LINEAR, animation.SINE]LINEAR=constant speed, SINE=smooth ease-in/ease-out
(inherits brightness from color_provider)

Available Predefined Palettes

PaletteDescriptionColors
PALETTE_RAINBOWStandard 7-color rainbowRed → Orange → Yellow → Green → Blue → Indigo → Violet
PALETTE_RGBSimple RGB cycleRed → Green → Blue
PALETTE_FIREWarm fire colorsBlack → Dark Red → Red → Orange → Yellow

Usage Examples

berry
# Rainbow palette with smooth ease-in/ease-out transitions
color rainbow_colors = rich_palette_color(
  colors=PALETTE_RAINBOW,
  period=5s,
  transition_type=SINE,
  brightness=255
)

# Fire effect with linear (constant speed) transitions
color fire_colors = rich_palette_color(
  colors=PALETTE_FIRE,
  period=3s,
  transition_type=LINEAR,
  brightness=200
)

breathe_color

Creates breathing/pulsing color effects by modulating the brightness of a base color over time. Inherits from color_provider and uses an internal oscillator_value for time-based brightness modulation.

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-The base color to modulate (32-bit ARGB value)
min_brightnessint00-255Minimum brightness level (breathing effect)
max_brightnessint2550-255Maximum brightness level (breathing effect)
periodint3000min: 1Time for one complete breathing cycle in ms
curve_factorint21-5Breathing curve shape (1=cosine wave, 2-5=curved breathing with pauses)
(inherits color, brightness from color_provider)

Curve Factor Effects:

  • 1: Pure cosine wave (smooth pulsing)
  • 2: Natural breathing with slight pauses at peaks (default)
  • 3: More pronounced breathing with longer pauses
  • 4: Deep breathing with extended pauses
  • 5: Most pronounced pauses at peaks (dramatic breathing effect)

Usage Examples

berry
# Natural breathing effect
color breathing_red = breathe_color(
  color=red,
  min_brightness=20,
  max_brightness=255,
  period=4s,
  curve_factor=3
)

# Fast pulsing effect
color pulse_blue = breathe_color(
  color=blue,
  min_brightness=50,
  max_brightness=200,
  period=1s,
  curve_factor=1
)

# Slow, deep breathing
color deep_breath = breathe_color(
  color=purple,
  min_brightness=5,
  max_brightness=255,
  period=6s,
  curve_factor=4
)

# Using dynamic base color
color rainbow_cycle = color_cycle(colors=bytes("FF0000FF" "FF00FF00" "FFFF0000"), period=5s)
color breathing_rainbow = breathe_color(
  color=rainbow_cycle,
  min_brightness=30,
  max_brightness=255,
  period=3s,
  curve_factor=2
)

Factories: animation.breathe_color(engine)

Animation Classes

All animation classes extend the base Animation class and inherit its parameters.

breathe

Creates a smooth breathing effect with natural breathing curves. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-The color to breathe
min_brightnessint00-255Minimum brightness level
max_brightnessint2550-255Maximum brightness level
periodint3000min: 100Breathing cycle time in ms
curve_factorint21-5Breathing curve shape (higher = sharper)
(inherits all Animation parameters)

Factory: animation.breathe(engine)

comet

Creates a comet effect with a bright head and fading tail. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-Color for the comet head
tail_lengthint51-50Length of the comet tail in pixels
speedint25601-25600Movement speed in 1/256th pixels per second
directionint1enum: [-1,1]Direction of movement (1=forward, -1=backward)
wrap_aroundint10-1Whether comet wraps around the strip
fade_factorint1790-255How quickly the tail fades
(inherits all Animation parameters)

Factory: animation.comet(engine)

gradient

Creates smooth two-color gradients. Subclass of beacon that uses beacon slew regions to create gradient effects.

ParameterTypeDefaultConstraintsDescription
color1int0xFFFF0000-First color (default red)
color2int0xFF0000FF-Second color (default blue)
directionint0enum: [0, 1]0=forward (color1→color2), 1=reverse (color2→color1)
gradient_typeint0enum: [0, 1]0=linear, 1=radial
(inherits all beacon parameters)

Gradient Types:

  • Linear (0): Creates a 2-color gradient from color1 to color2 (or reversed if direction=1). Implemented as the left slew of a large beacon positioned at the right edge.
  • Radial (1): Creates a symmetric gradient with color1 at center and color2 at edges (or reversed if direction=1). Implemented as a centered beacon with size=1 and slew regions extending to the edges.

Implementation Details:

  • Linear gradient uses a beacon with beacon_size=1000 (off-screen) and slew_size=strip_length
  • Radial gradient uses a centered beacon with beacon_size=1 and slew_size=strip_length/2

Factory: animation.gradient(engine)

palette_meter

VU meter style animation that displays a gradient-colored bar from the start of the strip up to a configurable level. Includes optional peak hold indicator. Inherits from palette_gradient.

ParameterTypeDefaultConstraintsDescription
levelint2550-255Current meter level (0=empty, 255=full)
peak_holdint1000min: 0Peak hold time in ms (0=disabled)
(inherits all palette_gradient parameters)

Visual Representation

level=128 (50%), peak at 200
[████████████████--------•-------]
^                        ^
|                        peak indicator (single pixel)
filled gradient area

Usage Examples

berry
# Simple meter with rainbow gradient
color rainbow = rich_palette_color()
animation meter = gradient_meter_animation()
meter.color_source = rainbow
meter.level = 128

# Meter with peak hold (1 second)
color fire_colors = rich_palette_color(colors=PALETTE_FIRE)
animation vu_meter = gradient_meter_animation(peak_hold=1000)
vu_meter.color_source = fire_colors

# Dynamic level from value provider
set audio_level = triangle(min_value=0, max_value=255, period=2s)
animation audio_meter = gradient_meter_animation(peak_hold=500)
audio_meter.color_source = rainbow
audio_meter.level = audio_level

Factory: animation.gradient_meter_animation(engine)

PulseAnimation

Creates a pulsing effect oscillating between min and max brightness. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-Pulse color
min_brightnessint00-255Minimum brightness level
max_brightnessint2550-255Maximum brightness level
periodint1000min: 100Pulse period in milliseconds
(inherits all Animation parameters)

Factory: animation.breathe(engine)

beacon

Creates a pulse effect at a specific position with optional fade regions. Inherits from Animation.

Visual Pattern

right_edge=0 (default, left edge):

         pos (1)
           |
           v
           _______
          /       \
  _______/         \____________
         | |     | |
         |2|  3  |2|

right_edge=1 (right edge):

                        pos (1)
                          |
                          v
           _______        |
          /       \       |
  _______/         \______|__
         | |     | |
         |2|  3  |2|

Where:

  1. pos - Position of the beacon edge (left edge for right_edge=0, right edge for right_edge=1)
  2. slew_size - Number of pixels to fade from back to fore color (can be 0)
  3. beacon_size - Number of pixels of the pulse

The pulse consists of:

  • Core pulse: Full brightness region of beacon_size pixels
  • Fade regions: Optional slew_size pixels on each side with gradual fade
  • Total width: beacon_size + (2 * slew_size) pixels

Parameters

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-Pulse color in ARGB format
back_colorint0xFF000000-Background color in ARGB format
posint0-Beacon edge position (left edge for right_edge=0, right edge for right_edge=1)
beacon_sizeint1min: 0Size of core pulse in pixels
slew_sizeint0min: 0Fade region size on each side in pixels
right_edgeint0enum: [0, 1]0=left edge (default), 1=right edge
(inherits all Animation parameters)

right_edge Behavior

  • right_edge=0 (default): pos specifies the left edge of the beacon. pos=0 places the beacon starting at the leftmost pixel.
  • right_edge=1: pos specifies the right edge of the beacon from the right side of the strip. pos=0 places the beacon's right edge at the rightmost pixel.

The effective left position is calculated as:

  • right_edge=0: effective_pos = pos
  • right_edge=1: effective_pos = strip_length - pos - beacon_size

Pattern Behavior

  • Sharp Pulse (slew_size = 0): Rectangular pulse with hard edges
  • Soft Pulse (slew_size > 0): Pulse with smooth fade-in/fade-out regions
  • Positioning: pos defines the beacon edge from the specified side
  • Fade Calculation: Linear fade from full brightness to background color
  • Boundary Handling: Fade regions are clipped to frame boundaries

Usage Examples

berry
# Sharp pulse at left edge (right_edge=0, default)
animation left_pulse = beacon(
  color=red,
  pos=0,
  beacon_size=3,
  slew_size=0,
  right_edge=0
)
# Shows 3 red pixels at positions 0, 1, 2

# Pulse from right edge
animation right_pulse = beacon(
  color=blue,
  pos=0,
  beacon_size=3,
  slew_size=0,
  right_edge=1
)
# With pos=0 and right_edge=1, shows 3 pixels at the right edge
# (positions strip_length-3, strip_length-2, strip_length-1)

# Soft pulse with fade regions
animation soft_pulse = beacon(
  color=green,
  pos=5,
  beacon_size=2,
  slew_size=3
)
# Total width: 2 + (2 * 3) = 8 pixels

# Spotlight effect
color dark_blue = 0xFF000040
animation spotlight = beacon(
  color=white,
  back_color=dark_blue,
  pos=15,
  beacon_size=1,
  slew_size=5
)

run spotlight

Common Use Cases

Spotlight Effects:

berry
# Moving spotlight with soft edges
animation moving_spotlight = beacon(
  color=white,
  back_color=0xFF000040,
  beacon_size=1,
  slew_size=5
)
moving_spotlight.pos = triangle(min_value=0, max_value=29, period=3s)

Position Markers:

berry
# Sharp position marker
animation position_marker = beacon(
  color=red,
  pos=15,
  beacon_size=1,
  slew_size=0
)

Breathing Spots:

berry
# Breathing effect at specific position
animation breathing_spot = beacon(
  color=blue,
  pos=10,
  beacon_size=3,
  slew_size=2
)
breathing_spot.opacity = smooth(min_value=50, max_value=255, period=2s)

Bidirectional Animations:

berry
# Two beacons moving from opposite edges toward center
set strip_len = strip_length()
set sweep = triangle(min_value=0, max_value=strip_len/2, period=2s)

animation left_beacon = beacon(
  color=red,
  beacon_size=2,
  right_edge=0
)
left_beacon.pos = sweep

animation right_beacon = beacon(
  color=blue,
  beacon_size=2,
  right_edge=1
)
right_beacon.pos = sweep

run left_beacon
run right_beacon

Factory: animation.beacon(engine)

crenel

Creates a crenel (square wave) pattern with repeating rectangular pulses. Inherits from Animation.

Visual Pattern

         pos (1)
           |
           v                 (*4)
            ______           ____
           |      |         |
  _________|      |_________|
 
           |   2  |    3     |

Where:

  1. pos - Starting position of the first pulse (in pixels)
  2. pulse_size - Width of each pulse (in pixels)
  3. low_size - Gap between pulses (in pixels)
  4. nb_pulse - Number of pulses (-1 for infinite)

The full period of the pattern is pulse_size + low_size pixels.

Parameters

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-Pulse color in ARGB format
back_colorint0xFF000000-Background color in ARGB format
posint0-Starting position of first pulse in pixels
pulse_sizeint1min: 0Width of each pulse in pixels
low_sizeint3min: 0Gap between pulses in pixels
nb_pulseint-1-Number of pulses (-1 = infinite)
(inherits all Animation parameters)

Pattern Behavior

  • Infinite Mode (nb_pulse = -1): Pattern repeats continuously across the strip
  • Finite Mode (nb_pulse > 0): Shows exactly the specified number of pulses
  • Period: Each pattern cycle spans pulse_size + low_size pixels
  • Boundary Handling: Pulses are clipped to frame boundaries
  • Zero Sizes: pulse_size = 0 produces no output; low_size = 0 creates continuous pulses

Pattern Calculations

  • Period and Positioning: The pattern repeats every pulse_size + low_size pixels
  • Optimization: For infinite pulses, the algorithm calculates optimal starting position for efficient rendering
  • Boundary Clipping: Pulses are automatically clipped to frame boundaries
  • Modulo Arithmetic: Negative positions are handled correctly with modulo arithmetic

Common Use Cases

Status Indicators:

berry
# Slow blinking pattern for status indication
animation status_indicator = crenel(
  color=green,
  pulse_size=1,
  low_size=9
)

Rhythmic Effects:

berry
# Fast rhythmic pattern
animation rhythm_pattern = crenel(
  color=red,
  pulse_size=2,
  low_size=2
)

Decorative Borders:

berry
# Decorative border pattern
color gold = 0xFFFFD700
animation border_pattern = crenel(
  color=gold,
  pulse_size=3,
  low_size=1,
  nb_pulse=10
)

Progress Indicators:

berry
# Progress bar with limited pulses
animation progress_bar = crenel(
  color=0xFF0080FF,
  pulse_size=2,
  low_size=1,
  nb_pulse=5
)

Integration Features

  • Parameter System: All parameters support dynamic updates with validation
  • Method Chaining: Fluent API for configuration (in Berry code)
  • Animation Lifecycle: Inherits standard animation lifecycle methods
  • Framework Integration: Seamless integration with animation engine
  • Testing: Comprehensive test suite covering edge cases and performance

Factory: animation.crenel(engine)

rich_palette

Creates smooth color transitions using rich palette data with direct parameter access. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
colorsbytesrainbow palette-Palette bytes or predefined palette
periodint5000min: 0Cycle time in ms (0 = value-based only)
transition_typeintanimation.LINEARenum: [animation.LINEAR, animation.SINE]LINEAR=constant speed, SINE=smooth ease-in/ease-out
brightnessint2550-255Overall brightness scaling
(inherits all Animation parameters)

Special Features:

  • Direct parameter access (set anim.colors instead of anim.color.colors)
  • Parameters are automatically forwarded to internal rich_palette_color
  • Access to specialized methods via anim.color_provider.method_name()

Factory: animation.rich_palette(engine)

twinkle

Creates a twinkling stars effect with random lights appearing and fading. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
colorint0xFFFFFFFF-Twinkle color
densityint1280-255Twinkle density/probability
twinkle_speedint61-5000Update frequency in Hz (or period in ms if ≥50)
fade_speedint1800-255How quickly twinkles fade
min_brightnessint320-255Minimum twinkle brightness
max_brightnessint2550-255Maximum twinkle brightness
(inherits all Animation parameters)

Factories: animation.twinkle(engine)

palette_gradient

Creates shifting gradient patterns with palette colors. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
color_sourceinstancenil-Color provider for pattern mapping
shift_periodint0min: 0Time for one complete shift cycle in ms (0 = static gradient)
spatial_periodint0min: 0Spatial period in pixels (0 = full strip length)
phase_shiftint00-255Phase shift in 0-255 range (mapped to spatial period)
(inherits all Animation parameters)

Implementation Details:

  • Uses bytes() buffer for efficient storage of per-pixel values
  • Color source receives values in 0-255 range via get_color_for_value(value, time_ms)
  • Buffer automatically resizes when strip length changes
  • Optimized LUT (Lookup Table) support for color providers

Pattern Generation:

  • Generates linear gradient values in 0-255 range across the specified spatial period
  • shift_period: Controls temporal movement - how long it takes for the gradient to shift one full spatial period
    • 0: Static gradient (no movement)
    • > 0: Moving gradient with specified period in milliseconds
  • spatial_period: Controls spatial repetition - how many pixels before the gradient pattern repeats
    • 0: Gradient spans the full strip length (single gradient across entire strip)
    • > 0: Gradient repeats every N pixels
  • phase_shift: Shifts the gradient pattern spatially by a percentage of the spatial period
  • Each pixel's value calculated using optimized fixed-point arithmetic

Factory: animation.palette_gradient(engine)

PaletteMeterAnimation

Creates meter/bar patterns based on a value function. Inherits from palette_gradient.

ParameterTypeDefaultConstraintsDescription
value_funcfunctionnil-Function that provides meter values (0-255 range)
(inherits all palette_gradient parameters)

Pattern Generation:

  • Value function signature: value_func(engine, time_ms, self) where:
    • engine: AnimationEngine reference
    • time_ms: Elapsed time since animation start
    • self: Reference to the animation instance
  • Value function returns value in 0-255 range representing meter level
  • Pixels within meter range get value 255, others get value 0
  • Meter position calculated as: position = tasmota.scale_uint(value, 0, 255, 0, strip_length)

Factory: animation.palette_meter(engine)

Motion Effects

Motion effects are transformation animations that apply movement, scaling, and distortion to existing animations. They accept any animation as a source and can be chained together for complex effects.

Combining Motion Effects

Motion effects can be chained to create sophisticated transformations:

berry
# Base animation
animation base_pulse = breathe(color=blue, period=3s)

# Simple animation composition
animation fire_effect = fire(
  color=fire_colors,
  intensity=180,
  flicker_speed=8
)

animation gradient_wave = gradient(
  color=rainbow_cycle,
  gradient_type=0,
  movement_speed=50
)

# Result: Multiple independent animations
run base_pulse
run fire_effect
run gradient_wave

Performance Considerations

  • Each animation uses approximately 4 bytes per pixel for color storage
  • Gradient animation requires color interpolation calculations
  • Consider strip length impact on transformation calculations

Parameter Constraints

Constraint Types

ConstraintTypeDescriptionExample
defaultanyDefault value used during initialization"default": 50
minintMinimum allowed value for integers"min": 0
maxintMaximum allowed value for integers"max": 100
enumlistList of valid values"enum": [1, 2, 3]
typestringExpected value type"type": "string"
nillableboolWhether nil values are allowed"nillable": true

Supported Types

TypeDescription
"int"Integer values (default if not specified)
"string"String values
"bool"Boolean values (true/false)
"instance"Object instances
"any"Any type (no type validation)

Factory Function Rules

  1. Engine-Only Parameters: All factory functions take ONLY the engine parameter
  2. No Redundant Factories: If a factory only calls the constructor, export the class directly
  3. Preset Factories: Factory functions should provide useful presets or complex configurations
  4. Parameter Assignment: Set parameters via virtual member assignment after creation

Supplementary Animations

These animations are available in src/animations_future/ but not included in the standard build. To use them, manually import and register them in your animation.be file.

fire

Creates a realistic fire effect with flickering flames. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
colorinstancenil-Color provider for fire palette (nil = default fire palette)
intensityint1800-255Overall fire intensity
flicker_speedint81-20Flicker update frequency in Hz
flicker_amountint1000-255Amount of random flicker
cooling_rateint550-255How quickly flames cool down
sparking_rateint1200-255Rate of new spark generation

Factory: animation.fire(engine)

wave

Creates mathematical waveforms that can move along the LED strip. Inherits from Animation.

ParameterTypeDefaultConstraintsDescription
colorint0xFFFF0000-Wave color
back_colorint0xFF000000-Background color shown in wave valleys
wave_typeint00-30=sine, 1=triangle, 2=square, 3=sawtooth
amplitudeint1280-255Wave height/intensity range
frequencyint320-255How many wave cycles fit on the strip
phaseint00-255Horizontal wave pattern shift
wave_speedint500-255Movement speed (0 = static wave)
center_levelint1280-255Baseline intensity around which wave oscillates

Wave Types: sine (0), triangle (1), square (2), sawtooth (3)

Factory: animation.wave(engine)

Other Supplementary Animations

Additional animations in animations_future/: bounce, jitter, plasma, scale, shift, sparkle.