Berry animation simplify DSL output Berry code (#23839)

This commit is contained in:
s-hadinger 2025-08-26 22:38:09 +02:00 committed by GitHub
parent 2540cf7e81
commit 5d9e62eebe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 18818 additions and 17514 deletions

View File

@ -1,48 +1,9 @@
# Generated Berry code from Animation DSL
# Source: aurora_borealis.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Aurora Borealis - Northern lights simulation
# # Flowing green and purple aurora colors
#
# #strip length 60
#
# # Define aurora color palette
# palette aurora_colors = [
# (0, 0x000022), # Dark night sky
# (64, 0x004400), # Dark green
# (128, 0x00AA44), # Aurora green
# (192, 0x44AA88), # Light green
# (255, 0x88FFAA) # Bright aurora
# ]
#
# # Secondary purple palette
# palette aurora_purple = [
# (0, 0x220022), # Dark purple
# (64, 0x440044), # Medium purple
# (128, 0x8800AA), # Bright purple
# (192, 0xAA44CC), # Light purple
# (255, 0xCCAAFF) # Pale purple
# ]
#
# # Base aurora animation with slow flowing colors
# animation aurora_base = rich_palette_animation(
# palette=aurora_colors # palette
# cycle_period=10s # cycle period
# transition_type=SINE # transition type (explicit for clarity)
# brightness=180 # brightness (dimmed for aurora effect)
# )
#
# sequence demo {
# play aurora_base # infinite duration (no 'for' clause)
# }
#
# run demo
import animation
# Aurora Borealis - Northern lights simulation
@ -70,3 +31,43 @@ var demo_ = (def (engine)
end)(engine)
engine.add_sequence_manager(demo_)
engine.start()
#- Original DSL source:
# Aurora Borealis - Northern lights simulation
# Flowing green and purple aurora colors
#strip length 60
# Define aurora color palette
palette aurora_colors = [
(0, 0x000022), # Dark night sky
(64, 0x004400), # Dark green
(128, 0x00AA44), # Aurora green
(192, 0x44AA88), # Light green
(255, 0x88FFAA) # Bright aurora
]
# Secondary purple palette
palette aurora_purple = [
(0, 0x220022), # Dark purple
(64, 0x440044), # Medium purple
(128, 0x8800AA), # Bright purple
(192, 0xAA44CC), # Light purple
(255, 0xCCAAFF) # Pale purple
]
# Base aurora animation with slow flowing colors
animation aurora_base = rich_palette_animation(
palette=aurora_colors # palette
cycle_period=10s # cycle period
transition_type=SINE # transition type (explicit for clarity)
brightness=180 # brightness (dimmed for aurora effect)
)
sequence demo {
play aurora_base # infinite duration (no 'for' clause)
}
run demo
-#

View File

@ -1,53 +1,9 @@
# Generated Berry code from Animation DSL
# Source: breathing_colors.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Breathing Colors - Slow color breathing effect
# # Gentle pulsing through different colors
#
# #strip length 60
#
# # Define breathing colors
# color breathe_red = 0xFF0000
# color breathe_green = 0x00FF00
# color breathe_blue = 0x0000FF
# color breathe_purple = 0x800080
# color breathe_orange = 0xFF8000
#
# # Create breathing animation that cycles through colors
# palette breathe_palette = [
# (0, 0xFF0000), # Red
# (51, 0xFF8000), # Orange
# (102, 0xFFFF00), # Yellow
# (153, 0x00FF00), # Green
# (204, 0x0000FF), # Blue
# (255, 0x800080) # Purple
# ]
#
# # Create a rich palette color provider
# color palette_pattern = rich_palette(
# palette=breathe_palette # palette
# cycle_period=15s # cycle period (defaults: smooth transition, 255 brightness)
# )
#
# # Create breathing animation using the palette
# animation breathing = breathe_animation(
# color=palette_pattern # base animation
# min_brightness=100 # min brightness
# max_brightness=255 # max brightness
# period=4s # breathing period (4 seconds)
# )
#
# # Add gentle opacity breathing
# breathing.opacity = smooth(min_value=100, max_value=255, duration=4s)
#
# # Start the animation
# run breathing
import animation
# Breathing Colors - Slow color breathing effect
@ -75,11 +31,58 @@ breathing_.min_brightness = 100 # min brightness
breathing_.max_brightness = 255 # max brightness
breathing_.period = 4000 # breathing period (4 seconds)
# Add gentle opacity breathing
var temp_smooth_152 = animation.smooth(engine)
temp_smooth_152.min_value = 100
temp_smooth_152.max_value = 255
temp_smooth_152.duration = 4000
breathing_.opacity = temp_smooth_152
breathing_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 100
provider.max_value = 255
provider.duration = 4000
return provider
end)(engine)
# Start the animation
engine.add_animation(breathing_)
engine.start()
#- Original DSL source:
# Breathing Colors - Slow color breathing effect
# Gentle pulsing through different colors
#strip length 60
# Define breathing colors
color breathe_red = 0xFF0000
color breathe_green = 0x00FF00
color breathe_blue = 0x0000FF
color breathe_purple = 0x800080
color breathe_orange = 0xFF8000
# Create breathing animation that cycles through colors
palette breathe_palette = [
(0, 0xFF0000), # Red
(51, 0xFF8000), # Orange
(102, 0xFFFF00), # Yellow
(153, 0x00FF00), # Green
(204, 0x0000FF), # Blue
(255, 0x800080) # Purple
]
# Create a rich palette color provider
color palette_pattern = rich_palette(
palette=breathe_palette # palette
cycle_period=15s # cycle period (defaults: smooth transition, 255 brightness)
)
# Create breathing animation using the palette
animation breathing = breathe_animation(
color=palette_pattern # base animation
min_brightness=100 # min brightness
max_brightness=255 # max brightness
period=4s # breathing period (4 seconds)
)
# Add gentle opacity breathing
breathing.opacity = smooth(min_value=100, max_value=255, duration=4s)
# Start the animation
run breathing
-#

View File

@ -1,58 +1,9 @@
# Generated Berry code from Animation DSL
# Source: candy_cane.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Candy Cane - Red and white stripes
# # Classic Christmas candy cane animation
#
# #strip length 60
#
# # Define stripe colors
# color candy_red = 0xFF0000
# color candy_white = 0xFFFFFF
#
# # Create alternating red and white animation
# # Using multiple pulse positions to create stripes
# animation stripe1 = beacon_animation(color=candy_red, pos=3, beacon_size=4, slew_size=1)
# animation stripe2 = beacon_animation(color=candy_white, pos=9, beacon_size=4, slew_size=1)
# animation stripe3 = beacon_animation(color=candy_red, pos=15, beacon_size=4, slew_size=1)
# animation stripe4 = beacon_animation(color=candy_white, pos=21, beacon_size=4, slew_size=1)
# animation stripe5 = beacon_animation(color=candy_red, pos=27, beacon_size=4, slew_size=1)
# animation stripe6 = beacon_animation(color=candy_white, pos=33, beacon_size=4, slew_size=1)
# animation stripe7 = beacon_animation(color=candy_red, pos=39, beacon_size=4, slew_size=1)
# animation stripe8 = beacon_animation(color=candy_white, pos=45, beacon_size=4, slew_size=1)
# animation stripe9 = beacon_animation(color=candy_red, pos=51, beacon_size=4, slew_size=1)
# animation stripe10 = beacon_animation(color=candy_white, pos=57, beacon_size=4, slew_size=1)
#
# # Add gentle movement to make it more dynamic
# set move_speed = 8s
# stripe1.pos = sawtooth(min_value=3, max_value=63, duration=move_speed)
# stripe2.pos = sawtooth(min_value=9, max_value=69, duration=move_speed)
# stripe3.pos = sawtooth(min_value=15, max_value=75, duration=move_speed)
# stripe4.pos = sawtooth(min_value=21, max_value=81, duration=move_speed)
# stripe5.pos = sawtooth(min_value=27, max_value=87, duration=move_speed)
# stripe6.pos = sawtooth(min_value=33, max_value=93, duration=move_speed)
# stripe7.pos = sawtooth(min_value=39, max_value=99, duration=move_speed)
# stripe8.pos = sawtooth(min_value=45, max_value=105, duration=move_speed)
# stripe9.pos = sawtooth(min_value=51, max_value=111, duration=move_speed)
# stripe10.pos = sawtooth(min_value=57, max_value=117, duration=move_speed)
#
# # Start all stripes
# run stripe1
# run stripe2
# run stripe3
# run stripe4
# run stripe5
# run stripe6
# run stripe7
# run stripe8
# run stripe9
# run stripe10
import animation
# Candy Cane - Red and white stripes
@ -118,56 +69,76 @@ stripe10_.beacon_size = 4
stripe10_.slew_size = 1
# Add gentle movement to make it more dynamic
var move_speed_ = 8000
var temp_sawtooth_258 = animation.sawtooth(engine)
temp_sawtooth_258.min_value = 3
temp_sawtooth_258.max_value = 63
temp_sawtooth_258.duration = move_speed_
stripe1_.pos = temp_sawtooth_258
var temp_sawtooth_277 = animation.sawtooth(engine)
temp_sawtooth_277.min_value = 9
temp_sawtooth_277.max_value = 69
temp_sawtooth_277.duration = move_speed_
stripe2_.pos = temp_sawtooth_277
var temp_sawtooth_296 = animation.sawtooth(engine)
temp_sawtooth_296.min_value = 15
temp_sawtooth_296.max_value = 75
temp_sawtooth_296.duration = move_speed_
stripe3_.pos = temp_sawtooth_296
var temp_sawtooth_315 = animation.sawtooth(engine)
temp_sawtooth_315.min_value = 21
temp_sawtooth_315.max_value = 81
temp_sawtooth_315.duration = move_speed_
stripe4_.pos = temp_sawtooth_315
var temp_sawtooth_334 = animation.sawtooth(engine)
temp_sawtooth_334.min_value = 27
temp_sawtooth_334.max_value = 87
temp_sawtooth_334.duration = move_speed_
stripe5_.pos = temp_sawtooth_334
var temp_sawtooth_353 = animation.sawtooth(engine)
temp_sawtooth_353.min_value = 33
temp_sawtooth_353.max_value = 93
temp_sawtooth_353.duration = move_speed_
stripe6_.pos = temp_sawtooth_353
var temp_sawtooth_372 = animation.sawtooth(engine)
temp_sawtooth_372.min_value = 39
temp_sawtooth_372.max_value = 99
temp_sawtooth_372.duration = move_speed_
stripe7_.pos = temp_sawtooth_372
var temp_sawtooth_391 = animation.sawtooth(engine)
temp_sawtooth_391.min_value = 45
temp_sawtooth_391.max_value = 105
temp_sawtooth_391.duration = move_speed_
stripe8_.pos = temp_sawtooth_391
var temp_sawtooth_410 = animation.sawtooth(engine)
temp_sawtooth_410.min_value = 51
temp_sawtooth_410.max_value = 111
temp_sawtooth_410.duration = move_speed_
stripe9_.pos = temp_sawtooth_410
var temp_sawtooth_429 = animation.sawtooth(engine)
temp_sawtooth_429.min_value = 57
temp_sawtooth_429.max_value = 117
temp_sawtooth_429.duration = move_speed_
stripe10_.pos = temp_sawtooth_429
stripe1_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 3
provider.max_value = 63
provider.duration = move_speed_
return provider
end)(engine)
stripe2_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 9
provider.max_value = 69
provider.duration = move_speed_
return provider
end)(engine)
stripe3_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 15
provider.max_value = 75
provider.duration = move_speed_
return provider
end)(engine)
stripe4_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 21
provider.max_value = 81
provider.duration = move_speed_
return provider
end)(engine)
stripe5_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 27
provider.max_value = 87
provider.duration = move_speed_
return provider
end)(engine)
stripe6_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 33
provider.max_value = 93
provider.duration = move_speed_
return provider
end)(engine)
stripe7_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 39
provider.max_value = 99
provider.duration = move_speed_
return provider
end)(engine)
stripe8_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 45
provider.max_value = 105
provider.duration = move_speed_
return provider
end)(engine)
stripe9_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 51
provider.max_value = 111
provider.duration = move_speed_
return provider
end)(engine)
stripe10_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 57
provider.max_value = 117
provider.duration = move_speed_
return provider
end)(engine)
# Start all stripes
engine.add_animation(stripe1_)
engine.add_animation(stripe2_)
@ -180,3 +151,53 @@ engine.add_animation(stripe8_)
engine.add_animation(stripe9_)
engine.add_animation(stripe10_)
engine.start()
#- Original DSL source:
# Candy Cane - Red and white stripes
# Classic Christmas candy cane animation
#strip length 60
# Define stripe colors
color candy_red = 0xFF0000
color candy_white = 0xFFFFFF
# Create alternating red and white animation
# Using multiple pulse positions to create stripes
animation stripe1 = beacon_animation(color=candy_red, pos=3, beacon_size=4, slew_size=1)
animation stripe2 = beacon_animation(color=candy_white, pos=9, beacon_size=4, slew_size=1)
animation stripe3 = beacon_animation(color=candy_red, pos=15, beacon_size=4, slew_size=1)
animation stripe4 = beacon_animation(color=candy_white, pos=21, beacon_size=4, slew_size=1)
animation stripe5 = beacon_animation(color=candy_red, pos=27, beacon_size=4, slew_size=1)
animation stripe6 = beacon_animation(color=candy_white, pos=33, beacon_size=4, slew_size=1)
animation stripe7 = beacon_animation(color=candy_red, pos=39, beacon_size=4, slew_size=1)
animation stripe8 = beacon_animation(color=candy_white, pos=45, beacon_size=4, slew_size=1)
animation stripe9 = beacon_animation(color=candy_red, pos=51, beacon_size=4, slew_size=1)
animation stripe10 = beacon_animation(color=candy_white, pos=57, beacon_size=4, slew_size=1)
# Add gentle movement to make it more dynamic
set move_speed = 8s
stripe1.pos = sawtooth(min_value=3, max_value=63, duration=move_speed)
stripe2.pos = sawtooth(min_value=9, max_value=69, duration=move_speed)
stripe3.pos = sawtooth(min_value=15, max_value=75, duration=move_speed)
stripe4.pos = sawtooth(min_value=21, max_value=81, duration=move_speed)
stripe5.pos = sawtooth(min_value=27, max_value=87, duration=move_speed)
stripe6.pos = sawtooth(min_value=33, max_value=93, duration=move_speed)
stripe7.pos = sawtooth(min_value=39, max_value=99, duration=move_speed)
stripe8.pos = sawtooth(min_value=45, max_value=105, duration=move_speed)
stripe9.pos = sawtooth(min_value=51, max_value=111, duration=move_speed)
stripe10.pos = sawtooth(min_value=57, max_value=117, duration=move_speed)
# Start all stripes
run stripe1
run stripe2
run stripe3
run stripe4
run stripe5
run stripe6
run stripe7
run stripe8
run stripe9
run stripe10
-#

View File

@ -1,72 +1,9 @@
# Generated Berry code from Animation DSL
# Source: christmas_tree.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Christmas Tree - Festive holiday colors
# # Green base with colorful ornaments and twinkling
#
# #strip length 60
#
# # Green tree base
# color tree_green = 0x006600
# animation tree_base = solid(color=tree_green)
#
# # Define ornament colors
# palette ornament_colors = [
# (0, 0xFF0000), # Red
# (64, 0xFFD700), # Gold
# (128, 0x0000FF), # Blue
# (192, 0xFFFFFF), # White
# (255, 0xFF00FF) # Magenta
# ]
#
# # Colorful ornaments as twinkling lights
# color ornament_pattern = rich_palette(palette=ornament_colors, cycle_period=3s, transition_type=LINEAR, brightness=255)
# animation ornaments = twinkle_animation(
# color=ornament_pattern # color source
# density=15 # density (many ornaments)
# twinkle_speed=800ms # twinkle speed (slow twinkle)
# )
# ornaments.priority = 10
#
# # Star on top (bright yellow pulse)
# animation tree_star = beacon_animation(
# color=0xFFFF00 # Bright yellow
# pos=58 # position (near the top)
# beacon_size=3 # star size
# slew_size=1 # sharp edges
# )
# tree_star.priority = 20
# tree_star.opacity = smooth(min_value=200, max_value=255, duration=2s) # Gentle pulsing
#
# # Add some white sparkles for snow/magic
# animation snow_sparkles = twinkle_animation(
# color=0xFFFFFF # White snow
# density=8 # density (sparkle count)
# twinkle_speed=400ms # twinkle speed (quick sparkles)
# )
# snow_sparkles.priority = 15
#
# # Garland effect - moving colored lights
# color garland_pattern = rich_palette(palette=ornament_colors, cycle_period=2s, transition_type=LINEAR, brightness=200)
# animation garland = comet_animation(
# color=garland_pattern # color source
# tail_length=6 # garland length (tail length)
# speed=4s # slow movement (speed)
# )
# garland.priority = 5
#
# # Start all animations
# run tree_base
# run ornaments
# run tree_star
# run snow_sparkles
# run garland
import animation
# Christmas Tree - Festive holiday colors
@ -99,11 +36,13 @@ tree_star_.pos = 58 # position (near the top)
tree_star_.beacon_size = 3 # star size
tree_star_.slew_size = 1 # sharp edges
tree_star_.priority = 20
var temp_smooth_170 = animation.smooth(engine)
temp_smooth_170.min_value = 200
temp_smooth_170.max_value = 255
temp_smooth_170.duration = 2000
tree_star_.opacity = temp_smooth_170 # Gentle pulsing
tree_star_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 200
provider.max_value = 255
provider.duration = 2000
return provider
end)(engine) # Gentle pulsing
# Add some white sparkles for snow/magic
var snow_sparkles_ = animation.twinkle_animation(engine)
snow_sparkles_.color = 0xFFFFFFFF # White snow
@ -128,3 +67,67 @@ engine.add_animation(tree_star_)
engine.add_animation(snow_sparkles_)
engine.add_animation(garland_)
engine.start()
#- Original DSL source:
# Christmas Tree - Festive holiday colors
# Green base with colorful ornaments and twinkling
#strip length 60
# Green tree base
color tree_green = 0x006600
animation tree_base = solid(color=tree_green)
# Define ornament colors
palette ornament_colors = [
(0, 0xFF0000), # Red
(64, 0xFFD700), # Gold
(128, 0x0000FF), # Blue
(192, 0xFFFFFF), # White
(255, 0xFF00FF) # Magenta
]
# Colorful ornaments as twinkling lights
color ornament_pattern = rich_palette(palette=ornament_colors, cycle_period=3s, transition_type=LINEAR, brightness=255)
animation ornaments = twinkle_animation(
color=ornament_pattern # color source
density=15 # density (many ornaments)
twinkle_speed=800ms # twinkle speed (slow twinkle)
)
ornaments.priority = 10
# Star on top (bright yellow pulse)
animation tree_star = beacon_animation(
color=0xFFFF00 # Bright yellow
pos=58 # position (near the top)
beacon_size=3 # star size
slew_size=1 # sharp edges
)
tree_star.priority = 20
tree_star.opacity = smooth(min_value=200, max_value=255, duration=2s) # Gentle pulsing
# Add some white sparkles for snow/magic
animation snow_sparkles = twinkle_animation(
color=0xFFFFFF # White snow
density=8 # density (sparkle count)
twinkle_speed=400ms # twinkle speed (quick sparkles)
)
snow_sparkles.priority = 15
# Garland effect - moving colored lights
color garland_pattern = rich_palette(palette=ornament_colors, cycle_period=2s, transition_type=LINEAR, brightness=200)
animation garland = comet_animation(
color=garland_pattern # color source
tail_length=6 # garland length (tail length)
speed=4s # slow movement (speed)
)
garland.priority = 5
# Start all animations
run tree_base
run ornaments
run tree_star
run snow_sparkles
run garland
-#

View File

@ -1,51 +1,9 @@
# Generated Berry code from Animation DSL
# Source: comet_chase.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Comet Chase - Moving comet with trailing tail
# # Bright head with fading tail
#
# #strip length 60
#
# # Dark blue background
# color space_blue = 0x000066 # Note: opaque 0xFF alpha channel is implicitly added
# animation background = solid(color=space_blue)
#
# # Main comet with bright white head
# animation comet_main = comet_animation(
# color=0xFFFFFF # White head
# tail_length=10 # tail length
# speed=2s # speed
# priority = 7
# )
#
# # Secondary comet in different color, opposite direction
# animation comet_secondary = comet_animation(
# color=0xFF4500 # Orange head
# tail_length=8 # shorter tail
# speed=3s # slower speed
# direction=-1 # other direction
# priority = 5
# )
#
# # Add sparkle trail behind comets but on top of blue background
# animation comet_sparkles = twinkle_animation(
# color=0xAAAAFF # Light blue sparkles
# density=8 # density (moderate sparkles)
# twinkle_speed=400ms # twinkle speed (quick sparkle)
# priority = 8
# )
#
# # Start all animations
# run background
# run comet_main
# run comet_secondary
# run comet_sparkles
import animation
# Comet Chase - Moving comet with trailing tail
@ -83,3 +41,46 @@ engine.add_animation(comet_main_)
engine.add_animation(comet_secondary_)
engine.add_animation(comet_sparkles_)
engine.start()
#- Original DSL source:
# Comet Chase - Moving comet with trailing tail
# Bright head with fading tail
#strip length 60
# Dark blue background
color space_blue = 0x000066 # Note: opaque 0xFF alpha channel is implicitly added
animation background = solid(color=space_blue)
# Main comet with bright white head
animation comet_main = comet_animation(
color=0xFFFFFF # White head
tail_length=10 # tail length
speed=2s # speed
priority = 7
)
# Secondary comet in different color, opposite direction
animation comet_secondary = comet_animation(
color=0xFF4500 # Orange head
tail_length=8 # shorter tail
speed=3s # slower speed
direction=-1 # other direction
priority = 5
)
# Add sparkle trail behind comets but on top of blue background
animation comet_sparkles = twinkle_animation(
color=0xAAAAFF # Light blue sparkles
density=8 # density (moderate sparkles)
twinkle_speed=400ms # twinkle speed (quick sparkle)
priority = 8
)
# Start all animations
run background
run comet_main
run comet_secondary
run comet_sparkles
-#

View File

@ -1,43 +1,9 @@
# Generated Berry code from Animation DSL
# Source: computed_values_demo.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Computed Values Demo - Example from the original request
# # Shows how to use computed values from value providers
#
# # Get the current strip length
# set strip_len = strip_length()
#
# # Create animation with computed values
# animation stream1 = comet_animation(
# color=red
# tail_length=abs(strip_len / 4) # computed value
# speed=1.5
# priority=10
# )
#
# # More complex computed values
# set base_speed = 2.0
# animation stream2 = comet_animation(
# color=blue
# tail_length=strip_len / 8 + (2 * strip_len) -10 # computed with addition
# speed=base_speed * 1.5 # computed with multiplication
# direction=-1
# priority=5
# )
#
# # Property assignment with computed values
# stream1.tail_length = strip_len / 5
# stream2.opacity = strip_len * 4
#
# # Run both animations
# run stream1
# run stream2
import animation
# Computed Values Demo - Example from the original request
@ -46,8 +12,7 @@ import animation
# Auto-generated strip initialization (using Tasmota configuration)
var engine = animation.init_strip()
var temp_strip_length_11 = animation.strip_length(engine)
var strip_len_ = temp_strip_length_11
var strip_len_ = animation.strip_length(engine)
# Create animation with computed values
var stream1_ = animation.comet_animation(engine)
stream1_.color = 0xFFFF0000
@ -69,3 +34,38 @@ stream2_.opacity = animation.create_closure_value(engine, def (self, param_name,
engine.add_animation(stream1_)
engine.add_animation(stream2_)
engine.start()
#- Original DSL source:
# Computed Values Demo - Example from the original request
# Shows how to use computed values from value providers
# Get the current strip length
set strip_len = strip_length()
# Create animation with computed values
animation stream1 = comet_animation(
color=red
tail_length=abs(strip_len / 4) # computed value
speed=1.5
priority=10
)
# More complex computed values
set base_speed = 2.0
animation stream2 = comet_animation(
color=blue
tail_length=strip_len / 8 + (2 * strip_len) -10 # computed with addition
speed=base_speed * 1.5 # computed with multiplication
direction=-1
priority=5
)
# Property assignment with computed values
stream1.tail_length = strip_len / 5
stream2.opacity = strip_len * 4
# Run both animations
run stream1
run stream2
-#

View File

@ -0,0 +1,47 @@
# Generated Berry code from Animation DSL
# Source: cylon_red_eye.anim
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
import animation
# Cylon Red Eye
# Automatically adapts to the length of the strip
# Auto-generated strip initialization (using Tasmota configuration)
var engine = animation.init_strip()
var strip_len_ = animation.strip_length(engine)
# Base aurora animation with slow flowing colors
var red_eye_ = animation.beacon_animation(engine)
red_eye_.color = 0xFFFF0000
red_eye_.pos = (def (engine)
var provider = animation.cosine_osc(engine)
provider.min_value = 0
provider.max_value = animation.create_closure_value(engine, def (self, param_name, time_ms) return (self.resolve(strip_len_, param_name, time_ms) - 2) end)
provider.duration = 5000
return provider
end)(engine)
red_eye_.beacon_size = 3 # small 3 pixels eye
red_eye_.slew_size = 2 # with 2 pixel shading around
engine.add_animation(red_eye_)
engine.start()
#- Original DSL source:
# Cylon Red Eye
# Automatically adapts to the length of the strip
set strip_len = strip_length()
# Base aurora animation with slow flowing colors
animation red_eye = beacon_animation(
color = red
pos = cosine_osc(min_value = 0, max_value = strip_len - 2, duration = 5s)
beacon_size = 3 # small 3 pixels eye
slew_size = 2 # with 2 pixel shading around
)
run red_eye
-#

View File

@ -1,64 +1,9 @@
# Generated Berry code from Animation DSL
# Source: disco_strobe.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Disco Strobe - Fast colorful strobing
# # Rapid color changes with strobe effects
#
# #strip length 60
#
# # Define disco color palette
# palette disco_colors = [
# (0, 0xFF0000), # Red
# (42, 0xFF8000), # Orange
# (85, 0xFFFF00), # Yellow
# (128, 0x00FF00), # Green
# (170, 0x0000FF), # Blue
# (213, 0x8000FF), # Purple
# (255, 0xFF00FF) # Magenta
# ]
#
# # Fast color cycling base
# animation disco_base = rich_palette_animation(palette=disco_colors, cycle_period=1s, transition_type=LINEAR, brightness=255)
#
# # Add strobe effect
# disco_base.opacity = square(min_value=0, max_value=255, duration=100ms, duty_cycle=30) # Fast strobe
#
# # Add white flash overlay
# animation white_flash = solid(color=0xFFFFFF)
# white_flash.opacity = square(min_value=0, max_value=255, duration=50ms, duty_cycle=10) # Quick white flashes
# white_flash.priority = 20
#
# # Add colored sparkles
# color sparkle_pattern = rich_palette(palette=disco_colors, cycle_period=500ms, transition_type=LINEAR, brightness=255)
# animation disco_sparkles = twinkle_animation(
# color=sparkle_pattern # color source
# density=12 # density (many sparkles)
# twinkle_speed=80ms # twinkle speed (very quick)
# )
# disco_sparkles.priority = 15
#
# # Add moving pulse for extra effect
# color pulse_pattern = rich_palette(palette=disco_colors, cycle_period=800ms, transition_type=LINEAR, brightness=255)
# animation disco_pulse = beacon_animation(
# color=pulse_pattern # color source
# pos=4 # initial position
# beacon_size=8 # pulse width
# slew_size=2 # sharp edges (slew size)
# )
# disco_pulse.priority = 10
# disco_pulse.pos = sawtooth(min_value=4, max_value=56, duration=2s) # Fast movement
#
# # Start all animations
# run disco_base
# run white_flash
# run disco_sparkles
# run disco_pulse
import animation
# Disco Strobe - Fast colorful strobing
@ -76,21 +21,25 @@ disco_base_.cycle_period = 1000
disco_base_.transition_type = animation.LINEAR
disco_base_.brightness = 255
# Add strobe effect
var temp_square_105 = animation.square(engine)
temp_square_105.min_value = 0
temp_square_105.max_value = 255
temp_square_105.duration = 100
temp_square_105.duty_cycle = 30
disco_base_.opacity = temp_square_105 # Fast strobe
disco_base_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 100
provider.duty_cycle = 30
return provider
end)(engine) # Fast strobe
# Add white flash overlay
var white_flash_ = animation.solid(engine)
white_flash_.color = 0xFFFFFFFF
var temp_square_142 = animation.square(engine)
temp_square_142.min_value = 0
temp_square_142.max_value = 255
temp_square_142.duration = 50
temp_square_142.duty_cycle = 10
white_flash_.opacity = temp_square_142 # Quick white flashes
white_flash_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 50
provider.duty_cycle = 10
return provider
end)(engine) # Quick white flashes
white_flash_.priority = 20
# Add colored sparkles
var sparkle_pattern_ = animation.rich_palette(engine)
@ -115,14 +64,72 @@ disco_pulse_.pos = 4 # initial position
disco_pulse_.beacon_size = 8 # pulse width
disco_pulse_.slew_size = 2 # sharp edges (slew size)
disco_pulse_.priority = 10
var temp_sawtooth_285 = animation.sawtooth(engine)
temp_sawtooth_285.min_value = 4
temp_sawtooth_285.max_value = 56
temp_sawtooth_285.duration = 2000
disco_pulse_.pos = temp_sawtooth_285 # Fast movement
disco_pulse_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 4
provider.max_value = 56
provider.duration = 2000
return provider
end)(engine) # Fast movement
# Start all animations
engine.add_animation(disco_base_)
engine.add_animation(white_flash_)
engine.add_animation(disco_sparkles_)
engine.add_animation(disco_pulse_)
engine.start()
#- Original DSL source:
# Disco Strobe - Fast colorful strobing
# Rapid color changes with strobe effects
#strip length 60
# Define disco color palette
palette disco_colors = [
(0, 0xFF0000), # Red
(42, 0xFF8000), # Orange
(85, 0xFFFF00), # Yellow
(128, 0x00FF00), # Green
(170, 0x0000FF), # Blue
(213, 0x8000FF), # Purple
(255, 0xFF00FF) # Magenta
]
# Fast color cycling base
animation disco_base = rich_palette_animation(palette=disco_colors, cycle_period=1s, transition_type=LINEAR, brightness=255)
# Add strobe effect
disco_base.opacity = square(min_value=0, max_value=255, duration=100ms, duty_cycle=30) # Fast strobe
# Add white flash overlay
animation white_flash = solid(color=0xFFFFFF)
white_flash.opacity = square(min_value=0, max_value=255, duration=50ms, duty_cycle=10) # Quick white flashes
white_flash.priority = 20
# Add colored sparkles
color sparkle_pattern = rich_palette(palette=disco_colors, cycle_period=500ms, transition_type=LINEAR, brightness=255)
animation disco_sparkles = twinkle_animation(
color=sparkle_pattern # color source
density=12 # density (many sparkles)
twinkle_speed=80ms # twinkle speed (very quick)
)
disco_sparkles.priority = 15
# Add moving pulse for extra effect
color pulse_pattern = rich_palette(palette=disco_colors, cycle_period=800ms, transition_type=LINEAR, brightness=255)
animation disco_pulse = beacon_animation(
color=pulse_pattern # color source
pos=4 # initial position
beacon_size=8 # pulse width
slew_size=2 # sharp edges (slew size)
)
disco_pulse.priority = 10
disco_pulse.pos = sawtooth(min_value=4, max_value=56, duration=2s) # Fast movement
# Start all animations
run disco_base
run white_flash
run disco_sparkles
run disco_pulse
-#

View File

@ -1,44 +1,9 @@
# Generated Berry code from Animation DSL
# Source: fire_flicker.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Fire Flicker - Realistic fire simulation
# # Warm colors with random flickering intensity
#
# #strip length 60
#
# # Define fire palette from black to yellow
# palette fire_colors = [
# (0, 0x000000), # Black
# (64, 0x800000), # Dark red
# (128, 0xFF0000), # Red
# (192, 0xFF4500), # Orange red
# (255, 0xFFFF00) # Yellow
# ]
#
# # Create base fire animation with palette
# animation fire_base = rich_palette_animation(palette=fire_colors, cycle_period=3s, transition_type=LINEAR, brightness=255)
#
# # Add flickering effect with random intensity changes
# fire_base.opacity = smooth(min_value=180, max_value=255, duration=800ms)
#
# # Add subtle position variation for more realism
# color flicker_pattern = rich_palette(palette=fire_colors, cycle_period=2s, transition_type=LINEAR, brightness=255)
# animation fire_flicker = twinkle_animation(
# color=flicker_pattern # color source
# density=12 # density (number of flickers)
# twinkle_speed=200ms # twinkle speed (flicker duration)
# )
# fire_flicker.priority = 10
#
# # Start both animations
# run fire_base
# run fire_flicker
import animation
# Fire Flicker - Realistic fire simulation
@ -56,11 +21,13 @@ fire_base_.cycle_period = 3000
fire_base_.transition_type = animation.LINEAR
fire_base_.brightness = 255
# Add flickering effect with random intensity changes
var temp_smooth_89 = animation.smooth(engine)
temp_smooth_89.min_value = 180
temp_smooth_89.max_value = 255
temp_smooth_89.duration = 800
fire_base_.opacity = temp_smooth_89
fire_base_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 180
provider.max_value = 255
provider.duration = 800
return provider
end)(engine)
# Add subtle position variation for more realism
var flicker_pattern_ = animation.rich_palette(engine)
flicker_pattern_.palette = fire_colors_
@ -76,3 +43,39 @@ fire_flicker_.priority = 10
engine.add_animation(fire_base_)
engine.add_animation(fire_flicker_)
engine.start()
#- Original DSL source:
# Fire Flicker - Realistic fire simulation
# Warm colors with random flickering intensity
#strip length 60
# Define fire palette from black to yellow
palette fire_colors = [
(0, 0x000000), # Black
(64, 0x800000), # Dark red
(128, 0xFF0000), # Red
(192, 0xFF4500), # Orange red
(255, 0xFFFF00) # Yellow
]
# Create base fire animation with palette
animation fire_base = rich_palette_animation(palette=fire_colors, cycle_period=3s, transition_type=LINEAR, brightness=255)
# Add flickering effect with random intensity changes
fire_base.opacity = smooth(min_value=180, max_value=255, duration=800ms)
# Add subtle position variation for more realism
color flicker_pattern = rich_palette(palette=fire_colors, cycle_period=2s, transition_type=LINEAR, brightness=255)
animation fire_flicker = twinkle_animation(
color=flicker_pattern # color source
density=12 # density (number of flickers)
twinkle_speed=200ms # twinkle speed (flicker duration)
)
fire_flicker.priority = 10
# Start both animations
run fire_base
run fire_flicker
-#

View File

@ -1,54 +1,9 @@
# Generated Berry code from Animation DSL
# Source: heartbeat_pulse.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Heartbeat Pulse - Rhythmic double pulse
# # Red pulsing like a heartbeat
#
# #strip length 60
#
# # Dark background
# color heart_bg = 0x110000
# animation background = solid(color=heart_bg)
#
# # Define heartbeat timing - double pulse animation
# # First pulse (stronger)
# animation heartbeat1 = solid(color=0xFF0000) # Bright red
# heartbeat1.opacity = square(min_value=0, max_value=255, duration=150ms, duty_cycle=20) # Quick strong pulse
# heartbeat1.priority = 10
#
# # Second pulse (weaker, slightly delayed)
# animation heartbeat2 = solid(color=0xCC0000) # Slightly dimmer red
# # Delay the second pulse by adjusting the square wave phase
# heartbeat2.opacity = square(min_value=0, max_value=180, duration=150ms, duty_cycle=15) # Weaker pulse
# heartbeat2.priority = 8
#
# # Add subtle glow effect
# animation heart_glow = solid(color=0x660000) # Dim red glow
# heart_glow.opacity = smooth(min_value=30, max_value=100, duration=1s) # Gentle breathing glow
# heart_glow.priority = 5
#
# # Add center pulse for emphasis
# animation center_pulse = beacon_animation(
# color=0xFFFFFF # White center
# pos=30 # center of strip
# beacon_size=4 # small center
# slew_size=2 # soft edges
# )
# center_pulse.priority = 20
# center_pulse.opacity = square(min_value=0, max_value=200, duration=100ms, duty_cycle=10) # Quick white flash
#
# # Start all animations
# run background
# run heart_glow
# run heartbeat1
# run heartbeat2
# run center_pulse
import animation
# Heartbeat Pulse - Rhythmic double pulse
@ -66,34 +21,40 @@ background_.color = heart_bg_
var heartbeat1_ = animation.solid(engine)
heartbeat1_.color = 0xFFFF0000
# Bright red
var temp_square_46 = animation.square(engine)
temp_square_46.min_value = 0
temp_square_46.max_value = 255
temp_square_46.duration = 150
temp_square_46.duty_cycle = 20
heartbeat1_.opacity = temp_square_46 # Quick strong pulse
heartbeat1_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 150
provider.duty_cycle = 20
return provider
end)(engine) # Quick strong pulse
heartbeat1_.priority = 10
# Second pulse (weaker, slightly delayed)
var heartbeat2_ = animation.solid(engine)
heartbeat2_.color = 0xFFCC0000
# Slightly dimmer red
# Delay the second pulse by adjusting the square wave phase
var temp_square_92 = animation.square(engine)
temp_square_92.min_value = 0
temp_square_92.max_value = 180
temp_square_92.duration = 150
temp_square_92.duty_cycle = 15
heartbeat2_.opacity = temp_square_92 # Weaker pulse
heartbeat2_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 180
provider.duration = 150
provider.duty_cycle = 15
return provider
end)(engine) # Weaker pulse
heartbeat2_.priority = 8
# Add subtle glow effect
var heart_glow_ = animation.solid(engine)
heart_glow_.color = 0xFF660000
# Dim red glow
var temp_smooth_136 = animation.smooth(engine)
temp_smooth_136.min_value = 30
temp_smooth_136.max_value = 100
temp_smooth_136.duration = 1000
heart_glow_.opacity = temp_smooth_136 # Gentle breathing glow
heart_glow_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 30
provider.max_value = 100
provider.duration = 1000
return provider
end)(engine) # Gentle breathing glow
heart_glow_.priority = 5
# Add center pulse for emphasis
var center_pulse_ = animation.beacon_animation(engine)
@ -102,12 +63,14 @@ center_pulse_.pos = 30 # center of strip
center_pulse_.beacon_size = 4 # small center
center_pulse_.slew_size = 2 # soft edges
center_pulse_.priority = 20
var temp_square_199 = animation.square(engine)
temp_square_199.min_value = 0
temp_square_199.max_value = 200
temp_square_199.duration = 100
temp_square_199.duty_cycle = 10
center_pulse_.opacity = temp_square_199 # Quick white flash
center_pulse_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 200
provider.duration = 100
provider.duty_cycle = 10
return provider
end)(engine) # Quick white flash
# Start all animations
engine.add_animation(background_)
engine.add_animation(heart_glow_)
@ -115,3 +78,49 @@ engine.add_animation(heartbeat1_)
engine.add_animation(heartbeat2_)
engine.add_animation(center_pulse_)
engine.start()
#- Original DSL source:
# Heartbeat Pulse - Rhythmic double pulse
# Red pulsing like a heartbeat
#strip length 60
# Dark background
color heart_bg = 0x110000
animation background = solid(color=heart_bg)
# Define heartbeat timing - double pulse animation
# First pulse (stronger)
animation heartbeat1 = solid(color=0xFF0000) # Bright red
heartbeat1.opacity = square(min_value=0, max_value=255, duration=150ms, duty_cycle=20) # Quick strong pulse
heartbeat1.priority = 10
# Second pulse (weaker, slightly delayed)
animation heartbeat2 = solid(color=0xCC0000) # Slightly dimmer red
# Delay the second pulse by adjusting the square wave phase
heartbeat2.opacity = square(min_value=0, max_value=180, duration=150ms, duty_cycle=15) # Weaker pulse
heartbeat2.priority = 8
# Add subtle glow effect
animation heart_glow = solid(color=0x660000) # Dim red glow
heart_glow.opacity = smooth(min_value=30, max_value=100, duration=1s) # Gentle breathing glow
heart_glow.priority = 5
# Add center pulse for emphasis
animation center_pulse = beacon_animation(
color=0xFFFFFF # White center
pos=30 # center of strip
beacon_size=4 # small center
slew_size=2 # soft edges
)
center_pulse.priority = 20
center_pulse.opacity = square(min_value=0, max_value=200, duration=100ms, duty_cycle=10) # Quick white flash
# Start all animations
run background
run heart_glow
run heartbeat1
run heartbeat2
run center_pulse
-#

View File

@ -1,75 +1,9 @@
# Generated Berry code from Animation DSL
# Source: lava_lamp.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Lava Lamp - Slow flowing warm colors
# # Organic movement like a lava lamp
#
# #strip length 60
#
# # Define lava colors (warm oranges and reds)
# palette lava_colors = [
# (0, 0x330000), # Dark red
# (64, 0x660000), # Medium red
# (128, 0xCC3300), # Bright red
# (192, 0xFF6600), # Orange
# (255, 0xFFAA00) # Yellow-orange
# ]
#
# # Base lava animation - very slow color changes
# animation lava_base = rich_palette_animation(palette=lava_colors, cycle_period=15s, transition_type=SINE, brightness=180)
#
# # Add slow-moving lava blobs
# color blob1_pattern = rich_palette(palette=lava_colors, cycle_period=12s, transition_type=SINE, brightness=255)
# animation lava_blob1 = beacon_animation(
# color=blob1_pattern # color source
# pos=9 # initial position
# beacon_size=18 # large blob
# slew_size=12 # very soft edges
# )
# lava_blob1.priority = 10
# lava_blob1.pos = smooth(min_value=9, max_value=51, duration=20s) # Very slow movement
#
# color blob2_pattern = rich_palette(palette=lava_colors, cycle_period=10s, transition_type=SINE, brightness=220)
# animation lava_blob2 = beacon_animation(
# color=blob2_pattern # color source
# pos=46 # initial position
# beacon_size=14 # medium blob
# slew_size=10 # soft edges
# )
# lava_blob2.priority = 8
# lava_blob2.pos = smooth(min_value=46, max_value=14, duration=25s) # Opposite direction, slower
#
# color blob3_pattern = rich_palette(palette=lava_colors, cycle_period=8s, transition_type=SINE, brightness=200)
# animation lava_blob3 = beacon_animation(
# color=blob3_pattern # color source
# pos=25 # initial position
# beacon_size=10 # smaller blob
# slew_size=8 # soft edges
# )
# lava_blob3.priority = 6
# lava_blob3.pos = smooth(min_value=25, max_value=35, duration=18s) # Small movement range
#
# # Add subtle heat shimmer effect
# color shimmer_pattern = rich_palette(palette=lava_colors, cycle_period=6s, transition_type=SINE, brightness=255)
# animation heat_shimmer = twinkle_animation(
# color=shimmer_pattern # color source
# density=6 # density (shimmer points)
# twinkle_speed=1.5s # twinkle speed (slow shimmer)
# )
# heat_shimmer.priority = 15
#
# # Start all animations
# run lava_base
# run lava_blob1
# run lava_blob2
# run lava_blob3
# run heat_shimmer
import animation
# Lava Lamp - Slow flowing warm colors
@ -98,11 +32,13 @@ lava_blob1_.pos = 9 # initial position
lava_blob1_.beacon_size = 18 # large blob
lava_blob1_.slew_size = 12 # very soft edges
lava_blob1_.priority = 10
var temp_smooth_145 = animation.smooth(engine)
temp_smooth_145.min_value = 9
temp_smooth_145.max_value = 51
temp_smooth_145.duration = 20000
lava_blob1_.pos = temp_smooth_145 # Very slow movement
lava_blob1_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 9
provider.max_value = 51
provider.duration = 20000
return provider
end)(engine) # Very slow movement
var blob2_pattern_ = animation.rich_palette(engine)
blob2_pattern_.palette = lava_colors_
blob2_pattern_.cycle_period = 10000
@ -114,11 +50,13 @@ lava_blob2_.pos = 46 # initial position
lava_blob2_.beacon_size = 14 # medium blob
lava_blob2_.slew_size = 10 # soft edges
lava_blob2_.priority = 8
var temp_smooth_222 = animation.smooth(engine)
temp_smooth_222.min_value = 46
temp_smooth_222.max_value = 14
temp_smooth_222.duration = 25000
lava_blob2_.pos = temp_smooth_222 # Opposite direction, slower
lava_blob2_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 46
provider.max_value = 14
provider.duration = 25000
return provider
end)(engine) # Opposite direction, slower
var blob3_pattern_ = animation.rich_palette(engine)
blob3_pattern_.palette = lava_colors_
blob3_pattern_.cycle_period = 8000
@ -130,11 +68,13 @@ lava_blob3_.pos = 25 # initial position
lava_blob3_.beacon_size = 10 # smaller blob
lava_blob3_.slew_size = 8 # soft edges
lava_blob3_.priority = 6
var temp_smooth_299 = animation.smooth(engine)
temp_smooth_299.min_value = 25
temp_smooth_299.max_value = 35
temp_smooth_299.duration = 18000
lava_blob3_.pos = temp_smooth_299 # Small movement range
lava_blob3_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 25
provider.max_value = 35
provider.duration = 18000
return provider
end)(engine) # Small movement range
# Add subtle heat shimmer effect
var shimmer_pattern_ = animation.rich_palette(engine)
shimmer_pattern_.palette = lava_colors_
@ -153,3 +93,70 @@ engine.add_animation(lava_blob2_)
engine.add_animation(lava_blob3_)
engine.add_animation(heat_shimmer_)
engine.start()
#- Original DSL source:
# Lava Lamp - Slow flowing warm colors
# Organic movement like a lava lamp
#strip length 60
# Define lava colors (warm oranges and reds)
palette lava_colors = [
(0, 0x330000), # Dark red
(64, 0x660000), # Medium red
(128, 0xCC3300), # Bright red
(192, 0xFF6600), # Orange
(255, 0xFFAA00) # Yellow-orange
]
# Base lava animation - very slow color changes
animation lava_base = rich_palette_animation(palette=lava_colors, cycle_period=15s, transition_type=SINE, brightness=180)
# Add slow-moving lava blobs
color blob1_pattern = rich_palette(palette=lava_colors, cycle_period=12s, transition_type=SINE, brightness=255)
animation lava_blob1 = beacon_animation(
color=blob1_pattern # color source
pos=9 # initial position
beacon_size=18 # large blob
slew_size=12 # very soft edges
)
lava_blob1.priority = 10
lava_blob1.pos = smooth(min_value=9, max_value=51, duration=20s) # Very slow movement
color blob2_pattern = rich_palette(palette=lava_colors, cycle_period=10s, transition_type=SINE, brightness=220)
animation lava_blob2 = beacon_animation(
color=blob2_pattern # color source
pos=46 # initial position
beacon_size=14 # medium blob
slew_size=10 # soft edges
)
lava_blob2.priority = 8
lava_blob2.pos = smooth(min_value=46, max_value=14, duration=25s) # Opposite direction, slower
color blob3_pattern = rich_palette(palette=lava_colors, cycle_period=8s, transition_type=SINE, brightness=200)
animation lava_blob3 = beacon_animation(
color=blob3_pattern # color source
pos=25 # initial position
beacon_size=10 # smaller blob
slew_size=8 # soft edges
)
lava_blob3.priority = 6
lava_blob3.pos = smooth(min_value=25, max_value=35, duration=18s) # Small movement range
# Add subtle heat shimmer effect
color shimmer_pattern = rich_palette(palette=lava_colors, cycle_period=6s, transition_type=SINE, brightness=255)
animation heat_shimmer = twinkle_animation(
color=shimmer_pattern # color source
density=6 # density (shimmer points)
twinkle_speed=1.5s # twinkle speed (slow shimmer)
)
heat_shimmer.priority = 15
# Start all animations
run lava_base
run lava_blob1
run lava_blob2
run lava_blob3
run heat_shimmer
-#

View File

@ -1,60 +1,9 @@
# Generated Berry code from Animation DSL
# Source: lightning_storm.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Lightning Storm - Random lightning flashes
# # Dark stormy background with bright lightning
#
# #strip length 60
#
# # Dark stormy background with subtle purple/blue
# palette storm_colors = [
# (0, 0x000011), # Very dark blue
# (128, 0x110022), # Dark purple
# (255, 0x220033) # Slightly lighter purple
# ]
#
# animation storm_bg = rich_palette_animation(palette=storm_colors, cycle_period=12s, transition_type=SINE, brightness=100)
#
# # Random lightning flashes - full strip
# animation lightning_main = solid(color=0xFFFFFF) # Bright white
# lightning_main.opacity = square(min_value=0, max_value=255, duration=80ms, duty_cycle=3) # Quick bright flashes
# lightning_main.priority = 20
#
# # Secondary lightning - partial strip
# animation lightning_partial = beacon_animation(
# color=0xFFFFAA # Slightly yellow white
# pos=30 # center position
# beacon_size=20 # covers part of strip
# slew_size=5 # soft edges
# )
# lightning_partial.priority = 15
# lightning_partial.opacity = square(min_value=0, max_value=200, duration=120ms, duty_cycle=4) # Different timing
#
# # Add blue afterglow
# animation afterglow = solid(color=0x4444FF) # Blue glow
# afterglow.opacity = square(min_value=0, max_value=80, duration=200ms, duty_cycle=8) # Longer, dimmer glow
# afterglow.priority = 10
#
# # Distant thunder (dim flashes)
# animation distant_flash = twinkle_animation(
# color=0x666699 # Dim blue-white
# density=4 # density (few flashes)
# twinkle_speed=300ms # twinkle speed (medium duration)
# )
# distant_flash.priority = 5
#
# # Start all animations
# run storm_bg
# run lightning_main
# run lightning_partial
# run afterglow
# run distant_flash
import animation
# Lightning Storm - Random lightning flashes
@ -74,12 +23,14 @@ storm_bg_.brightness = 100
var lightning_main_ = animation.solid(engine)
lightning_main_.color = 0xFFFFFFFF
# Bright white
var temp_square_82 = animation.square(engine)
temp_square_82.min_value = 0
temp_square_82.max_value = 255
temp_square_82.duration = 80
temp_square_82.duty_cycle = 3
lightning_main_.opacity = temp_square_82 # Quick bright flashes
lightning_main_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 80
provider.duty_cycle = 3
return provider
end)(engine) # Quick bright flashes
lightning_main_.priority = 20
# Secondary lightning - partial strip
var lightning_partial_ = animation.beacon_animation(engine)
@ -88,22 +39,26 @@ lightning_partial_.pos = 30 # center position
lightning_partial_.beacon_size = 20 # covers part of strip
lightning_partial_.slew_size = 5 # soft edges
lightning_partial_.priority = 15
var temp_square_149 = animation.square(engine)
temp_square_149.min_value = 0
temp_square_149.max_value = 200
temp_square_149.duration = 120
temp_square_149.duty_cycle = 4
lightning_partial_.opacity = temp_square_149 # Different timing
lightning_partial_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 200
provider.duration = 120
provider.duty_cycle = 4
return provider
end)(engine) # Different timing
# Add blue afterglow
var afterglow_ = animation.solid(engine)
afterglow_.color = 0xFF4444FF
# Blue glow
var temp_square_187 = animation.square(engine)
temp_square_187.min_value = 0
temp_square_187.max_value = 80
temp_square_187.duration = 200
temp_square_187.duty_cycle = 8
afterglow_.opacity = temp_square_187 # Longer, dimmer glow
afterglow_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 80
provider.duration = 200
provider.duty_cycle = 8
return provider
end)(engine) # Longer, dimmer glow
afterglow_.priority = 10
# Distant thunder (dim flashes)
var distant_flash_ = animation.twinkle_animation(engine)
@ -118,3 +73,55 @@ engine.add_animation(lightning_partial_)
engine.add_animation(afterglow_)
engine.add_animation(distant_flash_)
engine.start()
#- Original DSL source:
# Lightning Storm - Random lightning flashes
# Dark stormy background with bright lightning
#strip length 60
# Dark stormy background with subtle purple/blue
palette storm_colors = [
(0, 0x000011), # Very dark blue
(128, 0x110022), # Dark purple
(255, 0x220033) # Slightly lighter purple
]
animation storm_bg = rich_palette_animation(palette=storm_colors, cycle_period=12s, transition_type=SINE, brightness=100)
# Random lightning flashes - full strip
animation lightning_main = solid(color=0xFFFFFF) # Bright white
lightning_main.opacity = square(min_value=0, max_value=255, duration=80ms, duty_cycle=3) # Quick bright flashes
lightning_main.priority = 20
# Secondary lightning - partial strip
animation lightning_partial = beacon_animation(
color=0xFFFFAA # Slightly yellow white
pos=30 # center position
beacon_size=20 # covers part of strip
slew_size=5 # soft edges
)
lightning_partial.priority = 15
lightning_partial.opacity = square(min_value=0, max_value=200, duration=120ms, duty_cycle=4) # Different timing
# Add blue afterglow
animation afterglow = solid(color=0x4444FF) # Blue glow
afterglow.opacity = square(min_value=0, max_value=80, duration=200ms, duty_cycle=8) # Longer, dimmer glow
afterglow.priority = 10
# Distant thunder (dim flashes)
animation distant_flash = twinkle_animation(
color=0x666699 # Dim blue-white
density=4 # density (few flashes)
twinkle_speed=300ms # twinkle speed (medium duration)
)
distant_flash.priority = 5
# Start all animations
run storm_bg
run lightning_main
run lightning_partial
run afterglow
run distant_flash
-#

View File

@ -1,70 +1,9 @@
# Generated Berry code from Animation DSL
# Source: matrix_rain.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Matrix Rain - Digital rain effect
# # Green cascading code like The Matrix
#
# #strip length 60
#
# # Dark background
# color matrix_bg = 0x000000
# animation background = solid(color=matrix_bg, priority=50)
#
# # Define matrix green palette
# palette matrix_greens = [
# (0, 0x000000), # Black
# (64, 0x003300), # Dark green
# (128, 0x006600), # Medium green
# (192, 0x00AA00), # Bright green
# (255, 0x00FF00) # Neon green
# ]
#
# # Create multiple cascading streams
# color stream1_pattern = rich_palette(palette=matrix_greens, cycle_period=2s, transition_type=LINEAR, brightness=255)
# animation stream1 = comet_animation(
# color=stream1_pattern # color source
# tail_length=15 # long tail
# speed=1.5s # speed
# priority = 10
# )
#
#
# color stream2_pattern = rich_palette(palette=matrix_greens, cycle_period=1.8s, transition_type=LINEAR, brightness=200)
# animation stream2 = comet_animation(
# color=stream2_pattern # color source
# tail_length=12 # medium tail
# speed=2.2s # different speed
# priority = 8
# )
#
# color stream3_pattern = rich_palette(palette=matrix_greens, cycle_period=2.5s, transition_type=LINEAR, brightness=180)
# animation stream3 = comet_animation(
# color=stream3_pattern # color source
# tail_length=10 # shorter tail
# speed=1.8s # another speed
# priority = 6
# )
#
# # Add random bright flashes (like code highlights)
# animation code_flash = twinkle_animation(
# color=0x00FFAA # Bright cyan-green
# density=3 # density (few flashes)
# twinkle_speed=150ms # twinkle speed (quick flash)
# priority = 20
# )
#
# # Start all animations
# run background
# run stream1
# run stream2
# run stream3
# run code_flash
import animation
# Matrix Rain - Digital rain effect
@ -124,3 +63,65 @@ engine.add_animation(stream2_)
engine.add_animation(stream3_)
engine.add_animation(code_flash_)
engine.start()
#- Original DSL source:
# Matrix Rain - Digital rain effect
# Green cascading code like The Matrix
#strip length 60
# Dark background
color matrix_bg = 0x000000
animation background = solid(color=matrix_bg, priority=50)
# Define matrix green palette
palette matrix_greens = [
(0, 0x000000), # Black
(64, 0x003300), # Dark green
(128, 0x006600), # Medium green
(192, 0x00AA00), # Bright green
(255, 0x00FF00) # Neon green
]
# Create multiple cascading streams
color stream1_pattern = rich_palette(palette=matrix_greens, cycle_period=2s, transition_type=LINEAR, brightness=255)
animation stream1 = comet_animation(
color=stream1_pattern # color source
tail_length=15 # long tail
speed=1.5s # speed
priority = 10
)
color stream2_pattern = rich_palette(palette=matrix_greens, cycle_period=1.8s, transition_type=LINEAR, brightness=200)
animation stream2 = comet_animation(
color=stream2_pattern # color source
tail_length=12 # medium tail
speed=2.2s # different speed
priority = 8
)
color stream3_pattern = rich_palette(palette=matrix_greens, cycle_period=2.5s, transition_type=LINEAR, brightness=180)
animation stream3 = comet_animation(
color=stream3_pattern # color source
tail_length=10 # shorter tail
speed=1.8s # another speed
priority = 6
)
# Add random bright flashes (like code highlights)
animation code_flash = twinkle_animation(
color=0x00FFAA # Bright cyan-green
density=3 # density (few flashes)
twinkle_speed=150ms # twinkle speed (quick flash)
priority = 20
)
# Start all animations
run background
run stream1
run stream2
run stream3
run code_flash
-#

View File

@ -1,74 +1,9 @@
# Generated Berry code from Animation DSL
# Source: meteor_shower.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Meteor Shower - Multiple meteors with trails
# # Fast moving bright objects with fading trails
#
# #strip length 60
#
# # Dark space background
# color space_bg = 0x000011
# animation background = solid(color=space_bg)
#
# # Multiple meteors with different speeds and colors
# animation meteor1 = comet_animation(
# color=0xFFFFFF # Bright white
# tail_length=12 # long trail
# speed=1.5s # fast speed
# )
# meteor1.priority = 15
#
# animation meteor2 = comet_animation(
# color=0xFFAA00 # Orange
# tail_length=10 # medium trail
# speed=2s # medium speed
# )
# meteor2.priority = 12
#
# animation meteor3 = comet_animation(
# color=0xAAAAFF # Blue-white
# tail_length=8 # shorter trail
# speed=1.8s # fast speed
# )
# meteor3.priority = 10
#
# animation meteor4 = comet_animation(
# color=0xFFAAAA # Pink-white
# tail_length=14 # long trail
# speed=2.5s # slower speed
# )
# meteor4.priority = 8
#
# # Add distant stars
# animation stars = twinkle_animation(
# color=0xCCCCCC # Dim white
# density=12 # density (many stars)
# twinkle_speed=2s # twinkle speed (slow twinkle)
# )
# stars.priority = 5
#
# # Add occasional bright flash (meteor explosion)
# animation meteor_flash = twinkle_animation(
# color=0xFFFFFF # Bright white
# density=1 # density (single flash)
# twinkle_speed=100ms # twinkle speed (very quick)
# )
# meteor_flash.priority = 25
#
# # Start all animations
# run background
# run stars
# run meteor1
# run meteor2
# run meteor3
# run meteor4
# run meteor_flash
import animation
# Meteor Shower - Multiple meteors with trails
@ -123,3 +58,69 @@ engine.add_animation(meteor3_)
engine.add_animation(meteor4_)
engine.add_animation(meteor_flash_)
engine.start()
#- Original DSL source:
# Meteor Shower - Multiple meteors with trails
# Fast moving bright objects with fading trails
#strip length 60
# Dark space background
color space_bg = 0x000011
animation background = solid(color=space_bg)
# Multiple meteors with different speeds and colors
animation meteor1 = comet_animation(
color=0xFFFFFF # Bright white
tail_length=12 # long trail
speed=1.5s # fast speed
)
meteor1.priority = 15
animation meteor2 = comet_animation(
color=0xFFAA00 # Orange
tail_length=10 # medium trail
speed=2s # medium speed
)
meteor2.priority = 12
animation meteor3 = comet_animation(
color=0xAAAAFF # Blue-white
tail_length=8 # shorter trail
speed=1.8s # fast speed
)
meteor3.priority = 10
animation meteor4 = comet_animation(
color=0xFFAAAA # Pink-white
tail_length=14 # long trail
speed=2.5s # slower speed
)
meteor4.priority = 8
# Add distant stars
animation stars = twinkle_animation(
color=0xCCCCCC # Dim white
density=12 # density (many stars)
twinkle_speed=2s # twinkle speed (slow twinkle)
)
stars.priority = 5
# Add occasional bright flash (meteor explosion)
animation meteor_flash = twinkle_animation(
color=0xFFFFFF # Bright white
density=1 # density (single flash)
twinkle_speed=100ms # twinkle speed (very quick)
)
meteor_flash.priority = 25
# Start all animations
run background
run stars
run meteor1
run meteor2
run meteor3
run meteor4
run meteor_flash
-#

View File

@ -1,77 +1,9 @@
# Generated Berry code from Animation DSL
# Source: neon_glow.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Neon Glow - Electric neon tube effect
# # Bright saturated colors with flickering
#
# #strip length 60
#
# # Define neon colors
# palette neon_colors = [
# (0, 0xFF0080), # Hot pink
# (85, 0x00FF80), # Neon green
# (170, 0x8000FF), # Electric purple
# (255, 0xFF8000) # Neon orange
# ]
#
# # Main neon glow with color cycling
# animation neon_main = rich_palette_animation(palette=neon_colors, cycle_period=4s, transition_type=LINEAR, brightness=255)
#
# # Add electrical flickering
# neon_main.opacity = smooth(min_value=220, max_value=255, duration=200ms)
#
# # Add occasional electrical surge
# animation neon_surge = solid(color=0xFFFFFF) # White surge
# neon_surge.opacity = square(min_value=0, max_value=255, duration=50ms, duty_cycle=2) # Quick bright surges
# neon_surge.priority = 20
#
# # Add neon tube segments with gaps
# color segment_pattern = rich_palette(palette=neon_colors, cycle_period=4s, transition_type=LINEAR, brightness=255)
# animation segment1 = beacon_animation(
# color=segment_pattern # color source
# pos=6 # position
# beacon_size=12 # segment length
# slew_size=1 # sharp edges
# )
# segment1.priority = 10
#
# animation segment2 = beacon_animation(
# color=segment_pattern # color source
# pos=24 # position
# beacon_size=12 # segment length
# slew_size=1 # sharp edges
# )
# segment2.priority = 10
#
# animation segment3 = beacon_animation(
# color=segment_pattern # color source
# pos=42 # position
# beacon_size=12 # segment length
# slew_size=1 # sharp edges
# )
# segment3.priority = 10
#
# # Add electrical arcing between segments
# animation arc_sparkles = twinkle_animation(
# color=0xAAAAFF # Electric blue
# density=4 # density (few arcs)
# twinkle_speed=100ms # twinkle speed (quick arcs)
# )
# arc_sparkles.priority = 15
#
# # Start all animations
# run neon_main
# run neon_surge
# run segment1
# run segment2
# run segment3
# run arc_sparkles
import animation
# Neon Glow - Electric neon tube effect
@ -89,21 +21,25 @@ neon_main_.cycle_period = 4000
neon_main_.transition_type = animation.LINEAR
neon_main_.brightness = 255
# Add electrical flickering
var temp_smooth_81 = animation.smooth(engine)
temp_smooth_81.min_value = 220
temp_smooth_81.max_value = 255
temp_smooth_81.duration = 200
neon_main_.opacity = temp_smooth_81
neon_main_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 220
provider.max_value = 255
provider.duration = 200
return provider
end)(engine)
# Add occasional electrical surge
var neon_surge_ = animation.solid(engine)
neon_surge_.color = 0xFFFFFFFF
# White surge
var temp_square_114 = animation.square(engine)
temp_square_114.min_value = 0
temp_square_114.max_value = 255
temp_square_114.duration = 50
temp_square_114.duty_cycle = 2
neon_surge_.opacity = temp_square_114 # Quick bright surges
neon_surge_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 50
provider.duty_cycle = 2
return provider
end)(engine) # Quick bright surges
neon_surge_.priority = 20
# Add neon tube segments with gaps
var segment_pattern_ = animation.rich_palette(engine)
@ -143,3 +79,72 @@ engine.add_animation(segment2_)
engine.add_animation(segment3_)
engine.add_animation(arc_sparkles_)
engine.start()
#- Original DSL source:
# Neon Glow - Electric neon tube effect
# Bright saturated colors with flickering
#strip length 60
# Define neon colors
palette neon_colors = [
(0, 0xFF0080), # Hot pink
(85, 0x00FF80), # Neon green
(170, 0x8000FF), # Electric purple
(255, 0xFF8000) # Neon orange
]
# Main neon glow with color cycling
animation neon_main = rich_palette_animation(palette=neon_colors, cycle_period=4s, transition_type=LINEAR, brightness=255)
# Add electrical flickering
neon_main.opacity = smooth(min_value=220, max_value=255, duration=200ms)
# Add occasional electrical surge
animation neon_surge = solid(color=0xFFFFFF) # White surge
neon_surge.opacity = square(min_value=0, max_value=255, duration=50ms, duty_cycle=2) # Quick bright surges
neon_surge.priority = 20
# Add neon tube segments with gaps
color segment_pattern = rich_palette(palette=neon_colors, cycle_period=4s, transition_type=LINEAR, brightness=255)
animation segment1 = beacon_animation(
color=segment_pattern # color source
pos=6 # position
beacon_size=12 # segment length
slew_size=1 # sharp edges
)
segment1.priority = 10
animation segment2 = beacon_animation(
color=segment_pattern # color source
pos=24 # position
beacon_size=12 # segment length
slew_size=1 # sharp edges
)
segment2.priority = 10
animation segment3 = beacon_animation(
color=segment_pattern # color source
pos=42 # position
beacon_size=12 # segment length
slew_size=1 # sharp edges
)
segment3.priority = 10
# Add electrical arcing between segments
animation arc_sparkles = twinkle_animation(
color=0xAAAAFF # Electric blue
density=4 # density (few arcs)
twinkle_speed=100ms # twinkle speed (quick arcs)
)
arc_sparkles.priority = 15
# Start all animations
run neon_main
run neon_surge
run segment1
run segment2
run segment3
run arc_sparkles
-#

View File

@ -1,63 +1,9 @@
# Generated Berry code from Animation DSL
# Source: ocean_waves.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Ocean Waves - Blue-green wave simulation
# # Flowing water colors with wave motion
#
# #strip length 60
#
# # Define ocean color palette
# palette ocean_colors = [
# (0, 0x000080), # Deep blue
# (64, 0x0040C0), # Ocean blue
# (128, 0x0080FF), # Light blue
# (192, 0x40C0FF), # Cyan
# (255, 0x80FFFF) # Light cyan
# ]
#
# # Base ocean animation with slow color cycling
# animation ocean_base = rich_palette_animation(palette=ocean_colors, cycle_period=8s, transition_type=SINE, brightness=200)
#
# # Add wave motion with moving pulses
# color wave1_pattern = rich_palette(palette=ocean_colors, cycle_period=6s, transition_type=SINE, brightness=255)
# animation wave1 = beacon_animation(
# color=wave1_pattern # color source
# pos=0 # initial position
# beacon_size=12 # wave width
# slew_size=6 # soft edges
# )
# wave1.priority = 10
# wave1.pos = sawtooth(min_value=0, max_value=48, duration=5s) # 60-12 = 48
#
# color wave2_pattern = rich_palette(palette=ocean_colors, cycle_period=4s, transition_type=SINE, brightness=180)
# animation wave2 = beacon_animation(
# color=wave2_pattern # color source
# pos=52 # initial position
# beacon_size=8 # smaller wave
# slew_size=4 # soft edges
# )
# wave2.priority = 8
# wave2.pos = sawtooth(min_value=52, max_value=8, duration=7s) # Opposite direction
#
# # Add foam sparkles
# animation foam = twinkle_animation(
# color=0xFFFFFF # White foam
# density=6 # density (sparkle count)
# twinkle_speed=300ms # twinkle speed (quick sparkles)
# )
# foam.priority = 15
#
# # Start all animations
# run ocean_base
# run wave1
# run wave2
# run foam
import animation
# Ocean Waves - Blue-green wave simulation
@ -86,11 +32,13 @@ wave1_.pos = 0 # initial position
wave1_.beacon_size = 12 # wave width
wave1_.slew_size = 6 # soft edges
wave1_.priority = 10
var temp_sawtooth_145 = animation.sawtooth(engine)
temp_sawtooth_145.min_value = 0
temp_sawtooth_145.max_value = 48
temp_sawtooth_145.duration = 5000
wave1_.pos = temp_sawtooth_145 # 60-12 = 48
wave1_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 0
provider.max_value = 48
provider.duration = 5000
return provider
end)(engine) # 60-12 = 48
var wave2_pattern_ = animation.rich_palette(engine)
wave2_pattern_.palette = ocean_colors_
wave2_pattern_.cycle_period = 4000
@ -102,11 +50,13 @@ wave2_.pos = 52 # initial position
wave2_.beacon_size = 8 # smaller wave
wave2_.slew_size = 4 # soft edges
wave2_.priority = 8
var temp_sawtooth_222 = animation.sawtooth(engine)
temp_sawtooth_222.min_value = 52
temp_sawtooth_222.max_value = 8
temp_sawtooth_222.duration = 7000
wave2_.pos = temp_sawtooth_222 # Opposite direction
wave2_.pos = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 52
provider.max_value = 8
provider.duration = 7000
return provider
end)(engine) # Opposite direction
# Add foam sparkles
var foam_ = animation.twinkle_animation(engine)
foam_.color = 0xFFFFFFFF # White foam
@ -119,3 +69,58 @@ engine.add_animation(wave1_)
engine.add_animation(wave2_)
engine.add_animation(foam_)
engine.start()
#- Original DSL source:
# Ocean Waves - Blue-green wave simulation
# Flowing water colors with wave motion
#strip length 60
# Define ocean color palette
palette ocean_colors = [
(0, 0x000080), # Deep blue
(64, 0x0040C0), # Ocean blue
(128, 0x0080FF), # Light blue
(192, 0x40C0FF), # Cyan
(255, 0x80FFFF) # Light cyan
]
# Base ocean animation with slow color cycling
animation ocean_base = rich_palette_animation(palette=ocean_colors, cycle_period=8s, transition_type=SINE, brightness=200)
# Add wave motion with moving pulses
color wave1_pattern = rich_palette(palette=ocean_colors, cycle_period=6s, transition_type=SINE, brightness=255)
animation wave1 = beacon_animation(
color=wave1_pattern # color source
pos=0 # initial position
beacon_size=12 # wave width
slew_size=6 # soft edges
)
wave1.priority = 10
wave1.pos = sawtooth(min_value=0, max_value=48, duration=5s) # 60-12 = 48
color wave2_pattern = rich_palette(palette=ocean_colors, cycle_period=4s, transition_type=SINE, brightness=180)
animation wave2 = beacon_animation(
color=wave2_pattern # color source
pos=52 # initial position
beacon_size=8 # smaller wave
slew_size=4 # soft edges
)
wave2.priority = 8
wave2.pos = sawtooth(min_value=52, max_value=8, duration=7s) # Opposite direction
# Add foam sparkles
animation foam = twinkle_animation(
color=0xFFFFFF # White foam
density=6 # density (sparkle count)
twinkle_speed=300ms # twinkle speed (quick sparkles)
)
foam.priority = 15
# Start all animations
run ocean_base
run wave1
run wave2
run foam
-#

View File

@ -1,52 +1,9 @@
# Generated Berry code from Animation DSL
# Source: palette_demo.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Palette Demo - Shows how to use custom palettes in DSL
# # This demonstrates the new palette syntax
#
# #strip length 30
#
# # Define a fire palette
# palette fire_colors = [
# (0, 0x000000), # Black
# (64, 0x800000), # Dark red
# (128, 0xFF0000), # Red
# (192, 0xFF8000), # Orange
# (255, 0xFFFF00) # Yellow
# ]
#
# # Define an ocean palette
# palette ocean_colors = [
# (0, 0x000080), # Navy blue
# (64, 0x0000FF), # Blue
# (128, 0x00FFFF), # Cyan
# (192, 0x00FF80), # Spring green
# (255, 0x008000) # Green
# ]
#
# # Create animations using the palettes
# animation fire_anim = rich_palette_animation(palette=fire_colors, cycle_period=5s)
#
# animation ocean_anim = rich_palette_animation(palette=ocean_colors, cycle_period=8s)
#
# # Sequence to show both palettes
# sequence palette_demo {
# play fire_anim for 10s
# wait 1s
# play ocean_anim for 10s
# wait 1s
# repeat 2 times:
# play fire_anim for 3s
# play ocean_anim for 3s
# }
#
# run palette_demo
import animation
# Palette Demo - Shows how to use custom palettes in DSL
@ -83,3 +40,47 @@ var palette_demo_ = (def (engine)
end)(engine)
engine.add_sequence_manager(palette_demo_)
engine.start()
#- Original DSL source:
# Palette Demo - Shows how to use custom palettes in DSL
# This demonstrates the new palette syntax
#strip length 30
# Define a fire palette
palette fire_colors = [
(0, 0x000000), # Black
(64, 0x800000), # Dark red
(128, 0xFF0000), # Red
(192, 0xFF8000), # Orange
(255, 0xFFFF00) # Yellow
]
# Define an ocean palette
palette ocean_colors = [
(0, 0x000080), # Navy blue
(64, 0x0000FF), # Blue
(128, 0x00FFFF), # Cyan
(192, 0x00FF80), # Spring green
(255, 0x008000) # Green
]
# Create animations using the palettes
animation fire_anim = rich_palette_animation(palette=fire_colors, cycle_period=5s)
animation ocean_anim = rich_palette_animation(palette=ocean_colors, cycle_period=8s)
# Sequence to show both palettes
sequence palette_demo {
play fire_anim for 10s
wait 1s
play ocean_anim for 10s
wait 1s
repeat 2 times:
play fire_anim for 3s
play ocean_anim for 3s
}
run palette_demo
-#

View File

@ -1,93 +1,9 @@
# Generated Berry code from Animation DSL
# Source: palette_showcase.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Palette Showcase - Demonstrates all palette features
# # This example shows the full range of palette capabilities
#
# #strip length 60
#
# # Example 1: Fire palette with hex colors
# palette fire_gradient = [
# (0, 0x000000), # Black (no fire)
# (32, 0x330000), # Very dark red
# (64, 0x660000), # Dark red
# (96, 0xCC0000), # Red
# (128, 0xFF3300), # Red-orange
# (160, 0xFF6600), # Orange
# (192, 0xFF9900), # Light orange
# (224, 0xFFCC00), # Yellow-orange
# (255, 0xFFFF00) # Bright yellow
# ]
#
# # Example 2: Ocean palette with named colors
# palette ocean_depths = [
# (0, black), # Deep ocean
# (64, navy), # Deep blue
# (128, blue), # Ocean blue
# (192, cyan), # Shallow water
# (255, white) # Foam/waves
# ]
#
# # Example 3: Aurora palette (from the original example)
# palette aurora_borealis = [
# (0, 0x000022), # Dark night sky
# (64, 0x004400), # Dark green
# (128, 0x00AA44), # Aurora green
# (192, 0x44AA88), # Light green
# (255, 0x88FFAA) # Bright aurora
# ]
#
# # Example 4: Sunset palette mixing hex and named colors
# palette sunset_sky = [
# (0, 0x191970), # Midnight blue
# (64, purple), # Purple twilight
# (128, 0xFF69B4), # Hot pink
# (192, orange), # Sunset orange
# (255, yellow) # Sun
# ]
#
# # Create animations using each palette
# animation fire_effect = rich_palette_animation(palette=fire_gradient, cycle_period=3s)
#
# animation ocean_waves = rich_palette_animation(palette=ocean_depths, cycle_period=8s, transition_type=SINE, brightness=200)
#
# animation aurora_lights = rich_palette_animation(palette=aurora_borealis, cycle_period=12s, transition_type=SINE, brightness=180)
#
# animation sunset_glow = rich_palette_animation(palette=sunset_sky, cycle_period=6s, transition_type=SINE, brightness=220)
#
# # Sequence to showcase all palettes
# sequence palette_showcase {
# # Fire effect
# play fire_effect for 8s
# wait 1s
#
# # Ocean waves
# play ocean_waves for 8s
# wait 1s
#
# # Aurora borealis
# play aurora_lights for 8s
# wait 1s
#
# # Sunset
# play sunset_glow for 8s
# wait 1s
#
# # Quick cycle through all
# repeat 3 times:
# play fire_effect for 2s
# play ocean_waves for 2s
# play aurora_lights for 2s
# play sunset_glow for 2s
# }
#
# run palette_showcase
import animation
# Palette Showcase - Demonstrates all palette features
@ -151,3 +67,88 @@ var palette_showcase_ = (def (engine)
end)(engine)
engine.add_sequence_manager(palette_showcase_)
engine.start()
#- Original DSL source:
# Palette Showcase - Demonstrates all palette features
# This example shows the full range of palette capabilities
#strip length 60
# Example 1: Fire palette with hex colors
palette fire_gradient = [
(0, 0x000000), # Black (no fire)
(32, 0x330000), # Very dark red
(64, 0x660000), # Dark red
(96, 0xCC0000), # Red
(128, 0xFF3300), # Red-orange
(160, 0xFF6600), # Orange
(192, 0xFF9900), # Light orange
(224, 0xFFCC00), # Yellow-orange
(255, 0xFFFF00) # Bright yellow
]
# Example 2: Ocean palette with named colors
palette ocean_depths = [
(0, black), # Deep ocean
(64, navy), # Deep blue
(128, blue), # Ocean blue
(192, cyan), # Shallow water
(255, white) # Foam/waves
]
# Example 3: Aurora palette (from the original example)
palette aurora_borealis = [
(0, 0x000022), # Dark night sky
(64, 0x004400), # Dark green
(128, 0x00AA44), # Aurora green
(192, 0x44AA88), # Light green
(255, 0x88FFAA) # Bright aurora
]
# Example 4: Sunset palette mixing hex and named colors
palette sunset_sky = [
(0, 0x191970), # Midnight blue
(64, purple), # Purple twilight
(128, 0xFF69B4), # Hot pink
(192, orange), # Sunset orange
(255, yellow) # Sun
]
# Create animations using each palette
animation fire_effect = rich_palette_animation(palette=fire_gradient, cycle_period=3s)
animation ocean_waves = rich_palette_animation(palette=ocean_depths, cycle_period=8s, transition_type=SINE, brightness=200)
animation aurora_lights = rich_palette_animation(palette=aurora_borealis, cycle_period=12s, transition_type=SINE, brightness=180)
animation sunset_glow = rich_palette_animation(palette=sunset_sky, cycle_period=6s, transition_type=SINE, brightness=220)
# Sequence to showcase all palettes
sequence palette_showcase {
# Fire effect
play fire_effect for 8s
wait 1s
# Ocean waves
play ocean_waves for 8s
wait 1s
# Aurora borealis
play aurora_lights for 8s
wait 1s
# Sunset
play sunset_glow for 8s
wait 1s
# Quick cycle through all
repeat 3 times:
play fire_effect for 2s
play ocean_waves for 2s
play aurora_lights for 2s
play sunset_glow for 2s
}
run palette_showcase
-#

View File

@ -1,69 +1,9 @@
# Generated Berry code from Animation DSL
# Source: plasma_wave.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Plasma Wave - Smooth flowing plasma colors
# # Continuous color waves like plasma display
#
# #strip length 60
#
# # Define plasma color palette with smooth transitions
# palette plasma_colors = [
# (0, 0xFF0080), # Magenta
# (51, 0xFF8000), # Orange
# (102, 0xFFFF00), # Yellow
# (153, 0x80FF00), # Yellow-green
# (204, 0x00FF80), # Cyan-green
# (255, 0x0080FF) # Blue
# ]
#
# # Base plasma animation with medium speed
# animation plasma_base = rich_palette_animation(palette=plasma_colors, cycle_period=6s, transition_type=SINE, brightness=200)
#
# # Add multiple wave layers for complexity
# color wave1_pattern = rich_palette(palette=plasma_colors, cycle_period=4s, transition_type=SINE, brightness=255)
# animation plasma_wave1 = beacon_animation(
# color=wave1_pattern # color source
# pos=0 # initial position
# beacon_size=20 # wide wave
# slew_size=10 # very smooth
# )
# plasma_wave1.priority = 10
# plasma_wave1.pos = smooth(min_value=0, max_value=40, duration=8s)
#
# color wave2_pattern = rich_palette(palette=plasma_colors, cycle_period=5s, transition_type=SINE, brightness=180)
# animation plasma_wave2 = beacon_animation(
# color=wave2_pattern # color source
# pos=45 # initial position
# beacon_size=15 # medium wave
# slew_size=8 # smooth
# )
# plasma_wave2.priority = 8
# plasma_wave2.pos = smooth(min_value=45, max_value=15, duration=10s) # Opposite direction
#
# color wave3_pattern = rich_palette(palette=plasma_colors, cycle_period=3s, transition_type=SINE, brightness=220)
# animation plasma_wave3 = beacon_animation(
# color=wave3_pattern # color source
# pos=20 # initial position
# beacon_size=12 # smaller wave
# slew_size=6 # smooth
# )
# plasma_wave3.priority = 12
# plasma_wave3.pos = smooth(min_value=20, max_value=50, duration=6s) # Different speed
#
# # Add subtle intensity variation
# plasma_base.opacity = smooth(min_value=150, max_value=255, duration=12s)
#
# # Start all animations
# run plasma_base
# run plasma_wave1
# run plasma_wave2
# run plasma_wave3
import animation
# Plasma Wave - Smooth flowing plasma colors
@ -92,11 +32,13 @@ plasma_wave1_.pos = 0 # initial position
plasma_wave1_.beacon_size = 20 # wide wave
plasma_wave1_.slew_size = 10 # very smooth
plasma_wave1_.priority = 10
var temp_smooth_153 = animation.smooth(engine)
temp_smooth_153.min_value = 0
temp_smooth_153.max_value = 40
temp_smooth_153.duration = 8000
plasma_wave1_.pos = temp_smooth_153
plasma_wave1_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 0
provider.max_value = 40
provider.duration = 8000
return provider
end)(engine)
var wave2_pattern_ = animation.rich_palette(engine)
wave2_pattern_.palette = plasma_colors_
wave2_pattern_.cycle_period = 5000
@ -108,11 +50,13 @@ plasma_wave2_.pos = 45 # initial position
plasma_wave2_.beacon_size = 15 # medium wave
plasma_wave2_.slew_size = 8 # smooth
plasma_wave2_.priority = 8
var temp_smooth_229 = animation.smooth(engine)
temp_smooth_229.min_value = 45
temp_smooth_229.max_value = 15
temp_smooth_229.duration = 10000
plasma_wave2_.pos = temp_smooth_229 # Opposite direction
plasma_wave2_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 45
provider.max_value = 15
provider.duration = 10000
return provider
end)(engine) # Opposite direction
var wave3_pattern_ = animation.rich_palette(engine)
wave3_pattern_.palette = plasma_colors_
wave3_pattern_.cycle_period = 3000
@ -124,20 +68,85 @@ plasma_wave3_.pos = 20 # initial position
plasma_wave3_.beacon_size = 12 # smaller wave
plasma_wave3_.slew_size = 6 # smooth
plasma_wave3_.priority = 12
var temp_smooth_306 = animation.smooth(engine)
temp_smooth_306.min_value = 20
temp_smooth_306.max_value = 50
temp_smooth_306.duration = 6000
plasma_wave3_.pos = temp_smooth_306 # Different speed
plasma_wave3_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 20
provider.max_value = 50
provider.duration = 6000
return provider
end)(engine) # Different speed
# Add subtle intensity variation
var temp_smooth_329 = animation.smooth(engine)
temp_smooth_329.min_value = 150
temp_smooth_329.max_value = 255
temp_smooth_329.duration = 12000
plasma_base_.opacity = temp_smooth_329
plasma_base_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 150
provider.max_value = 255
provider.duration = 12000
return provider
end)(engine)
# Start all animations
engine.add_animation(plasma_base_)
engine.add_animation(plasma_wave1_)
engine.add_animation(plasma_wave2_)
engine.add_animation(plasma_wave3_)
engine.start()
#- Original DSL source:
# Plasma Wave - Smooth flowing plasma colors
# Continuous color waves like plasma display
#strip length 60
# Define plasma color palette with smooth transitions
palette plasma_colors = [
(0, 0xFF0080), # Magenta
(51, 0xFF8000), # Orange
(102, 0xFFFF00), # Yellow
(153, 0x80FF00), # Yellow-green
(204, 0x00FF80), # Cyan-green
(255, 0x0080FF) # Blue
]
# Base plasma animation with medium speed
animation plasma_base = rich_palette_animation(palette=plasma_colors, cycle_period=6s, transition_type=SINE, brightness=200)
# Add multiple wave layers for complexity
color wave1_pattern = rich_palette(palette=plasma_colors, cycle_period=4s, transition_type=SINE, brightness=255)
animation plasma_wave1 = beacon_animation(
color=wave1_pattern # color source
pos=0 # initial position
beacon_size=20 # wide wave
slew_size=10 # very smooth
)
plasma_wave1.priority = 10
plasma_wave1.pos = smooth(min_value=0, max_value=40, duration=8s)
color wave2_pattern = rich_palette(palette=plasma_colors, cycle_period=5s, transition_type=SINE, brightness=180)
animation plasma_wave2 = beacon_animation(
color=wave2_pattern # color source
pos=45 # initial position
beacon_size=15 # medium wave
slew_size=8 # smooth
)
plasma_wave2.priority = 8
plasma_wave2.pos = smooth(min_value=45, max_value=15, duration=10s) # Opposite direction
color wave3_pattern = rich_palette(palette=plasma_colors, cycle_period=3s, transition_type=SINE, brightness=220)
animation plasma_wave3 = beacon_animation(
color=wave3_pattern # color source
pos=20 # initial position
beacon_size=12 # smaller wave
slew_size=6 # smooth
)
plasma_wave3.priority = 12
plasma_wave3.pos = smooth(min_value=20, max_value=50, duration=6s) # Different speed
# Add subtle intensity variation
plasma_base.opacity = smooth(min_value=150, max_value=255, duration=12s)
# Start all animations
run plasma_base
run plasma_wave1
run plasma_wave2
run plasma_wave3
-#

View File

@ -1,49 +1,9 @@
# Generated Berry code from Animation DSL
# Source: police_lights.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Police Lights - Red and blue alternating flashes
# # Emergency vehicle style lighting
#
# #strip length 60
#
# # Define zones for left and right halves
# set half_length = 30
#
# # Left side red flashing
# animation left_red = beacon_animation(
# color=0xFF0000 # Bright red
# pos=15 # center of left half
# beacon_size=15 # half the strip
# slew_size=2 # sharp edges
# )
# left_red.priority = 10
# left_red.opacity = square(min_value=0, max_value=255, duration=400ms, duty_cycle=50) # 50% duty cycle
#
# # Right side blue flashing (opposite phase)
# animation right_blue = beacon_animation(
# color=0x0000FF # Bright blue
# pos=45 # center of right half
# beacon_size=15 # half the strip
# slew_size=2 # sharp edges
# )
# right_blue.priority = 10
# right_blue.opacity = square(min_value=255, max_value=0, duration=400ms, duty_cycle=50) # Opposite phase
#
# # Add white strobe overlay occasionally
# animation white_strobe = solid(color=0xFFFFFF)
# white_strobe.opacity = square(min_value=0, max_value=255, duration=100ms, duty_cycle=5) # Quick bright flashes
# white_strobe.priority = 20
#
# # Start all animations
# run left_red
# run right_blue
# run white_strobe
import animation
# Police Lights - Red and blue alternating flashes
@ -61,12 +21,14 @@ left_red_.pos = 15 # center of left half
left_red_.beacon_size = 15 # half the strip
left_red_.slew_size = 2 # sharp edges
left_red_.priority = 10
var temp_square_57 = animation.square(engine)
temp_square_57.min_value = 0
temp_square_57.max_value = 255
temp_square_57.duration = 400
temp_square_57.duty_cycle = 50
left_red_.opacity = temp_square_57 # 50% duty cycle
left_red_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 400
provider.duty_cycle = 50
return provider
end)(engine) # 50% duty cycle
# Right side blue flashing (opposite phase)
var right_blue_ = animation.beacon_animation(engine)
right_blue_.color = 0xFF0000FF # Bright blue
@ -74,24 +36,69 @@ right_blue_.pos = 45 # center of right half
right_blue_.beacon_size = 15 # half the strip
right_blue_.slew_size = 2 # sharp edges
right_blue_.priority = 10
var temp_square_118 = animation.square(engine)
temp_square_118.min_value = 255
temp_square_118.max_value = 0
temp_square_118.duration = 400
temp_square_118.duty_cycle = 50
right_blue_.opacity = temp_square_118 # Opposite phase
right_blue_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 255
provider.max_value = 0
provider.duration = 400
provider.duty_cycle = 50
return provider
end)(engine) # Opposite phase
# Add white strobe overlay occasionally
var white_strobe_ = animation.solid(engine)
white_strobe_.color = 0xFFFFFFFF
var temp_square_155 = animation.square(engine)
temp_square_155.min_value = 0
temp_square_155.max_value = 255
temp_square_155.duration = 100
temp_square_155.duty_cycle = 5
white_strobe_.opacity = temp_square_155 # Quick bright flashes
white_strobe_.opacity = (def (engine)
var provider = animation.square(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 100
provider.duty_cycle = 5
return provider
end)(engine) # Quick bright flashes
white_strobe_.priority = 20
# Start all animations
engine.add_animation(left_red_)
engine.add_animation(right_blue_)
engine.add_animation(white_strobe_)
engine.start()
#- Original DSL source:
# Police Lights - Red and blue alternating flashes
# Emergency vehicle style lighting
#strip length 60
# Define zones for left and right halves
set half_length = 30
# Left side red flashing
animation left_red = beacon_animation(
color=0xFF0000 # Bright red
pos=15 # center of left half
beacon_size=15 # half the strip
slew_size=2 # sharp edges
)
left_red.priority = 10
left_red.opacity = square(min_value=0, max_value=255, duration=400ms, duty_cycle=50) # 50% duty cycle
# Right side blue flashing (opposite phase)
animation right_blue = beacon_animation(
color=0x0000FF # Bright blue
pos=45 # center of right half
beacon_size=15 # half the strip
slew_size=2 # sharp edges
)
right_blue.priority = 10
right_blue.opacity = square(min_value=255, max_value=0, duration=400ms, duty_cycle=50) # Opposite phase
# Add white strobe overlay occasionally
animation white_strobe = solid(color=0xFFFFFF)
white_strobe.opacity = square(min_value=0, max_value=255, duration=100ms, duty_cycle=5) # Quick bright flashes
white_strobe.priority = 20
# Start all animations
run left_red
run right_blue
run white_strobe
-#

View File

@ -1,55 +1,9 @@
# Generated Berry code from Animation DSL
# Source: property_assignment_demo.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Property Assignment Demo
# # Shows how to set animation properties after creation
#
# #strip length 60
#
# # Define colors
# color red_custom = 0xFF0000
# color blue_custom = 0x0000FF
# color green_custom = 0x00FF00
#
# # Create animations
# animation left_pulse = beacon_animation(color=red_custom, pos=15, beacon_size=15, slew_size=3)
# animation center_pulse = beacon_animation(color=blue_custom, pos=30, beacon_size=15, slew_size=3)
# animation right_pulse = beacon_animation(color=green_custom, pos=45, beacon_size=15, slew_size=3)
#
# # Set different opacities
# left_pulse.opacity = 255 # Full slew_size
# center_pulse.opacity = 200 # Slightly dimmed
# right_pulse.opacity = 150 # More dimmed
#
# # Set priorities (higher numbers have priority)
# left_pulse.priority = 10
# center_pulse.priority = 15 # Center has highest priority
# right_pulse.priority = 5
#
# # Create a sequence that shows all three
# sequence demo {
# play left_pulse for 3s
# wait 500ms
# play center_pulse for 3s
# wait 500ms
# play right_pulse for 3s
# wait 500ms
#
# # Play all together for final effect
# repeat 3 times:
# play left_pulse for 2s
# play center_pulse for 2s
# play right_pulse for 2s
# wait 1s
# }
#
# run demo
import animation
# Property Assignment Demo
@ -108,3 +62,50 @@ var demo_ = (def (engine)
end)(engine)
engine.add_sequence_manager(demo_)
engine.start()
#- Original DSL source:
# Property Assignment Demo
# Shows how to set animation properties after creation
#strip length 60
# Define colors
color red_custom = 0xFF0000
color blue_custom = 0x0000FF
color green_custom = 0x00FF00
# Create animations
animation left_pulse = beacon_animation(color=red_custom, pos=15, beacon_size=15, slew_size=3)
animation center_pulse = beacon_animation(color=blue_custom, pos=30, beacon_size=15, slew_size=3)
animation right_pulse = beacon_animation(color=green_custom, pos=45, beacon_size=15, slew_size=3)
# Set different opacities
left_pulse.opacity = 255 # Full slew_size
center_pulse.opacity = 200 # Slightly dimmed
right_pulse.opacity = 150 # More dimmed
# Set priorities (higher numbers have priority)
left_pulse.priority = 10
center_pulse.priority = 15 # Center has highest priority
right_pulse.priority = 5
# Create a sequence that shows all three
sequence demo {
play left_pulse for 3s
wait 500ms
play center_pulse for 3s
wait 500ms
play right_pulse for 3s
wait 500ms
# Play all together for final effect
repeat 3 times:
play left_pulse for 2s
play center_pulse for 2s
play right_pulse for 2s
wait 1s
}
run demo
-#

View File

@ -1,26 +1,9 @@
# Generated Berry code from Animation DSL
# Source: rainbow_cycle.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Rainbow Cycle - Classic WLED effect
# # Smooth rainbow colors cycling across the strip
#
# #strip length 60
#
# # Create smooth rainbow cycle animation
# color rainbow_cycle = color_cycle(
# palette=[0xFF0000, 0xFF8000, 0xFFFF00, 0x00FF00, 0x0000FF, 0x8000FF, 0xFF00FF] # rainbow colors
# cycle_period=5s # cycle period
# )
# animation rainbow_animation = solid(color=rainbow_cycle)
#
# # Start the animation
# run rainbow_animation
import animation
# Rainbow Cycle - Classic WLED effect
@ -38,3 +21,21 @@ rainbow_animation_.color = rainbow_cycle_
# Start the animation
engine.add_animation(rainbow_animation_)
engine.start()
#- Original DSL source:
# Rainbow Cycle - Classic WLED effect
# Smooth rainbow colors cycling across the strip
#strip length 60
# Create smooth rainbow cycle animation
color rainbow_cycle = color_cycle(
palette=[0xFF0000, 0xFF8000, 0xFFFF00, 0x00FF00, 0x0000FF, 0x8000FF, 0xFF00FF] # rainbow colors
cycle_period=5s # cycle period
)
animation rainbow_animation = solid(color=rainbow_cycle)
# Start the animation
run rainbow_animation
-#

View File

@ -1,49 +1,9 @@
# Generated Berry code from Animation DSL
# Source: scanner_larson.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Scanner (Larson) - Knight Rider style scanner
# # Red dot bouncing back and forth
#
# #strip length 60
#
# # Dark background
# color scanner_bg = 0x110000
# animation background = solid(color=scanner_bg)
#
# # Main scanner pulse that bounces
# animation scanner = beacon_animation(
# color=0xFF0000 # Bright red
# pos=2 # initial position
# beacon_size=3 # pulse width
# slew_size=2 # fade region
# )
# scanner.priority = 10
#
# # Bouncing position from left to right and back
# scanner.pos = triangle(min_value=2, max_value=57, duration=2s)
#
# # Add trailing glow effect
# animation scanner_trail = beacon_animation(
# color=0x660000 # Dim red trail
# pos=2 # initial position
# beacon_size=6 # wider trail
# slew_size=4 # more fade
# )
# scanner_trail.priority = 5
# set pos_test = triangle(min_value=2, max_value=57, duration=2s)
# scanner_trail.pos = pos_test
# scanner_trail.opacity = 128 # Half brightness
#
# # Start all animations
# run background
# run scanner_trail
# run scanner
import animation
# Scanner (Larson) - Knight Rider style scanner
@ -64,11 +24,13 @@ scanner_.beacon_size = 3 # pulse width
scanner_.slew_size = 2 # fade region
scanner_.priority = 10
# Bouncing position from left to right and back
var temp_triangle_70 = animation.triangle(engine)
temp_triangle_70.min_value = 2
temp_triangle_70.max_value = 57
temp_triangle_70.duration = 2000
scanner_.pos = temp_triangle_70
scanner_.pos = (def (engine)
var provider = animation.triangle(engine)
provider.min_value = 2
provider.max_value = 57
provider.duration = 2000
return provider
end)(engine)
# Add trailing glow effect
var scanner_trail_ = animation.beacon_animation(engine)
scanner_trail_.color = 0xFF660000 # Dim red trail
@ -76,11 +38,13 @@ scanner_trail_.pos = 2 # initial position
scanner_trail_.beacon_size = 6 # wider trail
scanner_trail_.slew_size = 4 # more fade
scanner_trail_.priority = 5
var temp_triangle_125 = animation.triangle(engine)
temp_triangle_125.min_value = 2
temp_triangle_125.max_value = 57
temp_triangle_125.duration = 2000
var pos_test_ = temp_triangle_125
var pos_test_ = (def (engine)
var provider = animation.triangle(engine)
provider.min_value = 2
provider.max_value = 57
provider.duration = 2000
return provider
end)(engine)
scanner_trail_.pos = pos_test_
scanner_trail_.opacity = 128 # Half brightness
# Start all animations
@ -88,3 +52,44 @@ engine.add_animation(background_)
engine.add_animation(scanner_trail_)
engine.add_animation(scanner_)
engine.start()
#- Original DSL source:
# Scanner (Larson) - Knight Rider style scanner
# Red dot bouncing back and forth
#strip length 60
# Dark background
color scanner_bg = 0x110000
animation background = solid(color=scanner_bg)
# Main scanner pulse that bounces
animation scanner = beacon_animation(
color=0xFF0000 # Bright red
pos=2 # initial position
beacon_size=3 # pulse width
slew_size=2 # fade region
)
scanner.priority = 10
# Bouncing position from left to right and back
scanner.pos = triangle(min_value=2, max_value=57, duration=2s)
# Add trailing glow effect
animation scanner_trail = beacon_animation(
color=0x660000 # Dim red trail
pos=2 # initial position
beacon_size=6 # wider trail
slew_size=4 # more fade
)
scanner_trail.priority = 5
set pos_test = triangle(min_value=2, max_value=57, duration=2s)
scanner_trail.pos = pos_test
scanner_trail.opacity = 128 # Half brightness
# Start all animations
run background
run scanner_trail
run scanner
-#

View File

@ -1,35 +1,9 @@
# Generated Berry code from Animation DSL
# Source: simple_palette.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Simple Palette Example
# # Demonstrates basic palette usage in the DSL
#
# #strip length 20
#
# # Define a simple rainbow palette
# palette rainbow = [
# (0, red),
# (64, orange),
# (128, yellow),
# (192, green),
# (255, blue)
# ]
#
# # Create an animation using the palette
# animation rainbow_cycle = rich_palette_animation(palette=rainbow, cycle_period=3s)
#
# # Simple sequence
# sequence demo {
# play rainbow_cycle for 15s
# }
#
# run demo
import animation
# Simple Palette Example
@ -54,3 +28,30 @@ var demo_ = (def (engine)
end)(engine)
engine.add_sequence_manager(demo_)
engine.start()
#- Original DSL source:
# Simple Palette Example
# Demonstrates basic palette usage in the DSL
#strip length 20
# Define a simple rainbow palette
palette rainbow = [
(0, red),
(64, orange),
(128, yellow),
(192, green),
(255, blue)
]
# Create an animation using the palette
animation rainbow_cycle = rich_palette_animation(palette=rainbow, cycle_period=3s)
# Simple sequence
sequence demo {
play rainbow_cycle for 15s
}
run demo
-#

View File

@ -1,69 +1,9 @@
# Generated Berry code from Animation DSL
# Source: sunrise_sunset.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Sunrise Sunset - Warm color transition
# # Gradual transition from night to day colors
#
# #strip length 60
#
# # Define time-of-day color palette
# palette daylight_colors = [
# (0, 0x000011), # Night - dark blue
# (32, 0x001133), # Pre-dawn
# (64, 0xFF4400), # Sunrise orange
# (96, 0xFFAA00), # Morning yellow
# (128, 0xFFFF88), # Midday bright
# (160, 0xFFAA44), # Afternoon
# (192, 0xFF6600), # Sunset orange
# (224, 0xAA2200), # Dusk red
# (255, 0x220011) # Night - dark red
# ]
#
# # Main daylight cycle - very slow transition
# animation daylight_cycle = rich_palette_animation(palette=daylight_colors, cycle_period=60s)
#
# # Add sun position effect - bright spot that moves
# animation sun_position = beacon_animation(
# color=0xFFFFAA # Bright yellow sun
# pos=5 # initial position
# beacon_size=8 # sun size
# slew_size=4 # soft glow
# )
# sun_position.priority = 10
# sun_position.pos = smooth(min_value=5, max_value=55, duration=30s) # Sun arc across sky
# sun_position.opacity = smooth(min_value=0, max_value=255, duration=30s) # Fade in and out
#
# # Add atmospheric glow around sun
# animation sun_glow = beacon_animation(
# color=0xFFCC88 # Warm glow
# pos=5 # initial position
# beacon_size=16 # larger glow
# slew_size=8 # very soft
# )
# sun_glow.priority = 5
# sun_glow.pos = smooth(min_value=5, max_value=55, duration=30s) # Follow sun
# sun_glow.opacity = smooth(min_value=0, max_value=150, duration=30s) # Dimmer glow
#
# # Add twinkling stars during night phases
# animation stars = twinkle_animation(
# color=0xFFFFFF # White stars
# density=6 # density (star count)
# twinkle_speed=1s # twinkle speed (slow twinkle)
# )
# stars.priority = 15
# stars.opacity = smooth(min_value=255, max_value=0, duration=30s) # Fade out during day
#
# # Start all animations
# run daylight_cycle
# run sun_position
# run sun_glow
# run stars
import animation
# Sunrise Sunset - Warm color transition
@ -85,16 +25,20 @@ sun_position_.pos = 5 # initial position
sun_position_.beacon_size = 8 # sun size
sun_position_.slew_size = 4 # soft glow
sun_position_.priority = 10
var temp_smooth_147 = animation.smooth(engine)
temp_smooth_147.min_value = 5
temp_smooth_147.max_value = 55
temp_smooth_147.duration = 30000
sun_position_.pos = temp_smooth_147 # Sun arc across sky
var temp_smooth_167 = animation.smooth(engine)
temp_smooth_167.min_value = 0
temp_smooth_167.max_value = 255
temp_smooth_167.duration = 30000
sun_position_.opacity = temp_smooth_167 # Fade in and out
sun_position_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 5
provider.max_value = 55
provider.duration = 30000
return provider
end)(engine) # Sun arc across sky
sun_position_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 0
provider.max_value = 255
provider.duration = 30000
return provider
end)(engine) # Fade in and out
# Add atmospheric glow around sun
var sun_glow_ = animation.beacon_animation(engine)
sun_glow_.color = 0xFFFFCC88 # Warm glow
@ -102,30 +46,97 @@ sun_glow_.pos = 5 # initial position
sun_glow_.beacon_size = 16 # larger glow
sun_glow_.slew_size = 8 # very soft
sun_glow_.priority = 5
var temp_smooth_224 = animation.smooth(engine)
temp_smooth_224.min_value = 5
temp_smooth_224.max_value = 55
temp_smooth_224.duration = 30000
sun_glow_.pos = temp_smooth_224 # Follow sun
var temp_smooth_244 = animation.smooth(engine)
temp_smooth_244.min_value = 0
temp_smooth_244.max_value = 150
temp_smooth_244.duration = 30000
sun_glow_.opacity = temp_smooth_244 # Dimmer glow
sun_glow_.pos = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 5
provider.max_value = 55
provider.duration = 30000
return provider
end)(engine) # Follow sun
sun_glow_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 0
provider.max_value = 150
provider.duration = 30000
return provider
end)(engine) # Dimmer glow
# Add twinkling stars during night phases
var stars_ = animation.twinkle_animation(engine)
stars_.color = 0xFFFFFFFF # White stars
stars_.density = 6 # density (star count)
stars_.twinkle_speed = 1000 # twinkle speed (slow twinkle)
stars_.priority = 15
var temp_smooth_296 = animation.smooth(engine)
temp_smooth_296.min_value = 255
temp_smooth_296.max_value = 0
temp_smooth_296.duration = 30000
stars_.opacity = temp_smooth_296 # Fade out during day
stars_.opacity = (def (engine)
var provider = animation.smooth(engine)
provider.min_value = 255
provider.max_value = 0
provider.duration = 30000
return provider
end)(engine) # Fade out during day
# Start all animations
engine.add_animation(daylight_cycle_)
engine.add_animation(sun_position_)
engine.add_animation(sun_glow_)
engine.add_animation(stars_)
engine.start()
#- Original DSL source:
# Sunrise Sunset - Warm color transition
# Gradual transition from night to day colors
#strip length 60
# Define time-of-day color palette
palette daylight_colors = [
(0, 0x000011), # Night - dark blue
(32, 0x001133), # Pre-dawn
(64, 0xFF4400), # Sunrise orange
(96, 0xFFAA00), # Morning yellow
(128, 0xFFFF88), # Midday bright
(160, 0xFFAA44), # Afternoon
(192, 0xFF6600), # Sunset orange
(224, 0xAA2200), # Dusk red
(255, 0x220011) # Night - dark red
]
# Main daylight cycle - very slow transition
animation daylight_cycle = rich_palette_animation(palette=daylight_colors, cycle_period=60s)
# Add sun position effect - bright spot that moves
animation sun_position = beacon_animation(
color=0xFFFFAA # Bright yellow sun
pos=5 # initial position
beacon_size=8 # sun size
slew_size=4 # soft glow
)
sun_position.priority = 10
sun_position.pos = smooth(min_value=5, max_value=55, duration=30s) # Sun arc across sky
sun_position.opacity = smooth(min_value=0, max_value=255, duration=30s) # Fade in and out
# Add atmospheric glow around sun
animation sun_glow = beacon_animation(
color=0xFFCC88 # Warm glow
pos=5 # initial position
beacon_size=16 # larger glow
slew_size=8 # very soft
)
sun_glow.priority = 5
sun_glow.pos = smooth(min_value=5, max_value=55, duration=30s) # Follow sun
sun_glow.opacity = smooth(min_value=0, max_value=150, duration=30s) # Dimmer glow
# Add twinkling stars during night phases
animation stars = twinkle_animation(
color=0xFFFFFF # White stars
density=6 # density (star count)
twinkle_speed=1s # twinkle speed (slow twinkle)
)
stars.priority = 15
stars.opacity = smooth(min_value=255, max_value=0, duration=30s) # Fade out during day
# Start all animations
run daylight_cycle
run sun_position
run sun_glow
run stars
-#

View File

@ -1,41 +1,9 @@
# Generated Berry code from Animation DSL
# Source: twinkle_stars.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # Twinkle Stars - Random sparkling white stars
# # White sparkles on dark blue background
#
# #strip length 60
#
# # Dark blue background
# color night_sky = 0x000033
# animation background = solid(color=night_sky)
#
# # White twinkling stars
# animation stars = twinkle_animation(
# color=0xFFFFFF # White stars
# density=8 # density (number of stars)
# twinkle_speed=500ms # twinkle speed (twinkle duration)
# )
# stars.priority = 10
#
# # Add occasional bright flash
# animation bright_flash = twinkle_animation(
# color=0xFFFFAA # Bright yellow-white
# density=2 # density (fewer bright flashes)
# twinkle_speed=300ms # twinkle speed (quick flash)
# )
# bright_flash.priority = 15
#
# # Start all animations
# run background
# run stars
# run bright_flash
import animation
# Twinkle Stars - Random sparkling white stars
@ -65,3 +33,36 @@ engine.add_animation(background_)
engine.add_animation(stars_)
engine.add_animation(bright_flash_)
engine.start()
#- Original DSL source:
# Twinkle Stars - Random sparkling white stars
# White sparkles on dark blue background
#strip length 60
# Dark blue background
color night_sky = 0x000033
animation background = solid(color=night_sky)
# White twinkling stars
animation stars = twinkle_animation(
color=0xFFFFFF # White stars
density=8 # density (number of stars)
twinkle_speed=500ms # twinkle speed (twinkle duration)
)
stars.priority = 10
# Add occasional bright flash
animation bright_flash = twinkle_animation(
color=0xFFFFAA # Bright yellow-white
density=2 # density (fewer bright flashes)
twinkle_speed=300ms # twinkle speed (quick flash)
)
bright_flash.priority = 15
# Start all animations
run background
run stars
run bright_flash
-#

View File

@ -1,64 +1,9 @@
# Generated Berry code from Animation DSL
# Source: user_functions_demo.anim
# Generated automatically
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
# Original DSL source:
# # User Functions Demo - Advanced Computed Parameters
# # Shows how to use user functions in computed parameters via property assignments
#
# # Get the current strip length for calculations
# set strip_len = strip_length()
#
# # Example 1: Simple user function in computed parameter
# animation random_base = solid(
# color=blue
# priority=10
# )
# # Use user function in property assignment
# random_base.opacity = rand_demo()
#
# # Example 2: User function with mathematical operations
# animation random_bounded = solid(
# color=orange
# priority=8
# )
# # User function with bounds using math functions
# random_bounded.opacity = max(50, min(255, rand_demo() + 100))
#
# # Example 3: User function in arithmetic expressions
# animation random_variation = solid(
# color=purple
# priority=15
# )
# # Mix user function with arithmetic operations
# random_variation.opacity = abs(rand_demo() - 128) + 64
#
# # Example 4: User function affecting different properties
# animation random_multi = solid(
# color=cyan
# priority=12
# )
# # Use user function for multiple properties
# random_multi.opacity = max(100, rand_demo())
#
# # Example 5: Complex expression with user function
# animation random_complex = solid(
# color=white
# priority=20
# )
# # Complex expression with user function and math operations
# random_complex.opacity = round((rand_demo() + 128) / 2 + abs(rand_demo() - 100))
#
# # Run all animations to demonstrate the effects
# run random_base
# run random_bounded
# run random_variation
# run random_multi
# run random_complex
import animation
# User Functions Demo - Advanced Computed Parameters
@ -67,8 +12,7 @@ import animation
# Auto-generated strip initialization (using Tasmota configuration)
var engine = animation.init_strip()
var temp_strip_length_11 = animation.strip_length(engine)
var strip_len_ = temp_strip_length_11
var strip_len_ = animation.strip_length(engine)
# Example 1: Simple user function in computed parameter
var random_base_ = animation.solid(engine)
random_base_.color = 0xFF0000FF
@ -106,3 +50,59 @@ engine.add_animation(random_variation_)
engine.add_animation(random_multi_)
engine.add_animation(random_complex_)
engine.start()
#- Original DSL source:
# User Functions Demo - Advanced Computed Parameters
# Shows how to use user functions in computed parameters via property assignments
# Get the current strip length for calculations
set strip_len = strip_length()
# Example 1: Simple user function in computed parameter
animation random_base = solid(
color=blue
priority=10
)
# Use user function in property assignment
random_base.opacity = rand_demo()
# Example 2: User function with mathematical operations
animation random_bounded = solid(
color=orange
priority=8
)
# User function with bounds using math functions
random_bounded.opacity = max(50, min(255, rand_demo() + 100))
# Example 3: User function in arithmetic expressions
animation random_variation = solid(
color=purple
priority=15
)
# Mix user function with arithmetic operations
random_variation.opacity = abs(rand_demo() - 128) + 64
# Example 4: User function affecting different properties
animation random_multi = solid(
color=cyan
priority=12
)
# Use user function for multiple properties
random_multi.opacity = max(100, rand_demo())
# Example 5: Complex expression with user function
animation random_complex = solid(
color=white
priority=20
)
# Complex expression with user function and math operations
random_complex.opacity = round((rand_demo() + 128) / 2 + abs(rand_demo() - 100))
# Run all animations to demonstrate the effects
run random_base
run random_bounded
run random_variation
run random_multi
run random_complex
-#

View File

@ -0,0 +1,14 @@
# Cylon Red Eye
# Automatically adapts to the length of the strip
set strip_len = strip_length()
# Base aurora animation with slow flowing colors
animation red_eye = beacon_animation(
color = red
pos = cosine_osc(min_value = 0, max_value = strip_len - 2, duration = 5s)
beacon_size = 3 # small 3 pixels eye
slew_size = 2 # with 2 pixel shading around
)
run red_eye

View File

@ -26,7 +26,7 @@ ParameterizedObject
│ ├── NoiseAnimation
│ ├── PlasmaAnimation
│ ├── PulseAnimation
│ ├── PulsePositionAnimation
│ ├── BeaconAnimation
│ ├── CrenelPositionAnimation
│ ├── RichPaletteAnimation
│ ├── TwinkleAnimation
@ -141,7 +141,7 @@ Generates oscillating values using various waveforms. Inherits from `ValueProvid
- `8` (ELASTIC) - Spring-like overshoot and oscillation
- `9` (BOUNCE) - Ball-like bouncing with decreasing amplitude
**Factories**: `animation.ramp(engine)`, `animation.sawtooth(engine)`, `animation.linear(engine)`, `animation.triangle(engine)`, `animation.smooth(engine)`, `animation.sine(engine)`, `animation.square(engine)`, `animation.ease_in(engine)`, `animation.ease_out(engine)`, `animation.elastic(engine)`, `animation.bounce(engine)`, `animation.oscillator_value(engine)`
**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](OSCILLATION_PATTERNS.md) - Visual examples and usage patterns for oscillation waveforms
@ -169,13 +169,13 @@ The ClosureValueProvider includes built-in mathematical helper methods that can
| `round(x)` | Round to nearest integer | `x: number` | `int` | `self.round(3.7)``4` |
| `sqrt(x)` | Square root with integer handling | `x: number` | `number` | `self.sqrt(64)``128` (for 0-255 range) |
| `scale(v, from_min, from_max, to_min, to_max)` | Scale value between ranges | `v, from_min, from_max, to_min, to_max: number` | `int` | `self.scale(50, 0, 100, 0, 255)``127` |
| `sine(angle)` | Sine function (0-255 input range) | `angle: number` | `int` | `self.sine(64)` → `255` (90°) |
| `cosine(angle)` | Cosine function (0-255 input range) | `angle: number` | `int` | `self.cosine(0)` → `-255` (matches oscillator behavior) |
| `sin(angle)` | Sine function (0-255 input range) | `angle: number` | `int` | `self.sin(64)` → `255` (90°) |
| `cos(angle)` | Cosine function (0-255 input range) | `angle: number` | `int` | `self.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**: `sine()` and `cosine()` use 0-255 input range (0-360 degrees)
- **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
@ -787,7 +787,7 @@ Creates a pulsing effect oscillating between min and max brightness. Inherits fr
**Factory**: `animation.pulsating_animation(engine)`
### PulsePositionAnimation
### BeaconAnimation
Creates a pulse effect at a specific position with optional fade regions. Inherits from `Animation`.
@ -812,7 +812,7 @@ Where:
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_sizee + (2 * slew_size)` pixels
- **Total width**: `beacon_size + (2 * slew_size)` pixels
#### Parameters
@ -840,7 +840,7 @@ The pulse consists of:
animation sharp_pulse = beacon_animation(
color=red,
pos=10,
beacon_sizee=3,
beacon_size=3,
slew_size=0
)

View File

@ -331,12 +331,12 @@ for i: 0..(frame.width-1)
end
```
## Complete Example: PulsePositionAnimation
## Complete Example: BeaconAnimation
Here's a complete example showing all concepts:
```berry
#@ solidify:PulsePositionAnimation,weak
#@ solidify:BeaconAnimation,weak
class BeaconAnimation : animation.animation
# NO instance variables for parameters - they are handled by the virtual parameter system
@ -466,12 +466,12 @@ class BeaconAnimation : animation.animation
# String representation of the animation
def tostring()
return f"PulsePositionAnimation(color=0x{self.color :08x}, pos={self.pos}, beacon_size={self.beacon_size}, slew_size={self.slew_size})"
return f"BeaconAnimation(color=0x{self.color :08x}, pos={self.pos}, beacon_size={self.beacon_size}, slew_size={self.slew_size})"
end
end
# Export class directly - no redundant factory function needed
return {'beacon_animation': PulsePositionAnimation}
return {'beacon_animation': BeaconAnimation}
```
## Testing Your Animation

View File

@ -399,8 +399,8 @@ The following mathematical functions are available in computed parameters and ar
| `round(x)` | Rounds to nearest integer | One number | Rounded integer |
| `sqrt(x)` | Returns the square root | One number | Square root (scaled for integers) |
| `scale(v, from_min, from_max, to_min, to_max)` | Scales value from one range to another | Value and range parameters | Scaled integer |
| `sine(angle)` | Returns sine of angle | Angle in 0-255 range (0-360°) | Sine value in -255 to 255 range |
| `cosine(angle)` | Returns cosine of angle | Angle in 0-255 range (0-360°) | Cosine value in -255 to 255 range |
| `sin(angle)` | Returns sine of angle | Angle in 0-255 range (0-360°) | Sine value in -255 to 255 range |
| `cos(angle)` | Returns cosine of angle | Angle in 0-255 range (0-360°) | Cosine value in -255 to 255 range |
**Mathematical Function Examples:**
```berry
@ -425,17 +425,17 @@ test.opacity = scale(strip_len, 10, 60, 50, 255) # Scale strip length to opacit
# Trigonometric functions for wave patterns
set angle = 128 # 180 degrees in 0-255 range
test.opacity = sine(angle) + 128 # Sine wave shifted to positive range
test.brightness = cosine(angle) + 128 # Cosine wave shifted to positive range
test.opacity = sin(angle) + 128 # Mathematical sine function (not oscillator)
test.brightness = cos(angle) + 128 # Mathematical cosine function (not oscillator)
# Complex expressions combining multiple functions
test.position = max(0, round(abs(sine(strip_len * 2)) * (strip_len - 1) / 255))
test.position = max(0, round(abs(sin(strip_len * 2)) * (strip_len - 1) / 255))
test.opacity = min(255, max(50, scale(sqrt(strip_len), 0, 16, 100, 255)))
```
**Special Notes:**
- **Integer Optimization**: `sqrt()` function automatically handles integer scaling for 0-255 range values
- **Trigonometric Range**: `sine()` and `cosine()` use 0-255 input range (mapped to 0-360°) and return -255 to 255 output range
- **Trigonometric Range**: `sin()` and `cos()` use 0-255 input range (mapped to 0-360°) and return -255 to 255 output range
- **Automatic Detection**: Mathematical functions are automatically detected at transpile time using dynamic introspection
- **Closure Context**: In computed parameters, mathematical functions are called as `self.<function>()` in the generated closure context
@ -672,7 +672,8 @@ Value providers create dynamic values that change over time:
|----------|-------------|
| `triangle` | Triangle wave oscillation (alias for oscillator with triangle waveform) |
| `smooth` | Smooth cosine wave (alias for oscillator with smooth waveform) |
| `sine` | Pure sine wave oscillation (alias for oscillator with sine waveform) |
| `cosine_osc` | Cosine wave oscillation (alias for smooth - cosine waveform) |
| `sine_osc` | Pure sine wave oscillation (alias for oscillator with sine waveform) |
| `linear` | Linear progression (alias for oscillator with linear waveform) |
| `ramp` | Sawtooth wave (alias for oscillator with ramp waveform) |
| `sawtooth` | Sawtooth wave (alias for ramp) |
@ -686,7 +687,8 @@ Value providers create dynamic values that change over time:
# Direct oscillator usage
triangle(min_value=0, max_value=255, period=2s) # Triangle wave
smooth(min_value=50, max_value=200, period=3s) # Smooth cosine
sine(min_value=0, max_value=255, period=2s) # Pure sine wave
cosine_osc(min_value=3, max_value=1, period=5s) # Cosine wave (alias for smooth)
sine_osc(min_value=0, max_value=255, period=2s) # Pure sine wave
linear(min_value=0, max_value=100, period=1s) # Linear progression
ramp(min_value=0, max_value=255, period=2s) # Sawtooth wave
square(min_value=0, max_value=255, period=1s) # Square wave
@ -699,6 +701,8 @@ bounce(min_value=0, max_value=255, period=2s) # Bouncing ball effect
set brightness_oscillator = smooth(min_value=50, max_value=255, period=3s)
set position_sweep = triangle(min_value=0, max_value=29, period=5s)
set elastic_movement = elastic(min_value=0, max_value=30, period=4s)
set sine_wave = sine_osc(min_value=0, max_value=255, period=2s)
set cosine_wave = cosine_osc(min_value=50, max_value=200, period=3s)
set strip_len = strip_length() # Get the current strip length
```

View File

@ -355,12 +355,12 @@ run nonexistent_animation
2. **Use programmatic API for performance-critical code**:
```berry
# DSL for high-level structure
animation_dsl.execute('''
sequence main {
play performance_critical_anim for 10s
}
run main
''')
animation_dsl.execute(
"sequence main {\n"
"play performance_critical_anim for 10s\n"
"}\n"
"run main"
)
# Programmatic for performance-critical animations
var performance_critical_anim = animation.create_optimized_animation()

View File

@ -32,7 +32,8 @@ set bouncing = oscillator_value(min_value=10, max_value=240, duration=4000, form
```berry
# These are equivalent to oscillator_value with specific forms
set smooth_fade = smooth(min_value=50, max_value=255, duration=3000) # form=COSINE
set sine_wave = sine(min_value=50, max_value=255, duration=3000) # form=SINE
set sine_wave = sine_osc(min_value=50, max_value=255, duration=3000) # form=SINE
set cosine_wave = cosine_osc(min_value=50, max_value=255, duration=3000) # form=COSINE (alias for smooth)
set linear_sweep = linear(min_value=0, max_value=255, duration=2000) # form=SAWTOOTH
set triangle_wave = triangle(min_value=10, max_value=240, duration=4000) # form=TRIANGLE
```
@ -100,7 +101,7 @@ Value
```
```berry
set wave_motion = sine(min_value=0, max_value=255, duration=2000)
set wave_motion = sine_osc(min_value=0, max_value=255, duration=2000)
```
### TRIANGLE

View File

@ -379,17 +379,16 @@ import animation
load("user_animations.be")
# Now they're available in DSL
var dsl_code = '''
animation my_fire = fire(200, 1500ms)
animation my_sparkles = sparkle(white, 8, 400ms)
sequence show {
play my_fire for 10s
play my_sparkles for 5s
}
run show
'''
var dsl_code =
"animation my_fire = fire(200, 1500ms)\n"
"animation my_sparkles = sparkle(white, 8, 400ms)\n"
"\n"
"sequence show {\n"
" play my_fire for 10s\n"
" play my_sparkles for 5s\n"
"}\n"
"\n
"run show"
animation_dsl.execute(dsl_code)
```
@ -398,17 +397,16 @@ animation_dsl.execute(dsl_code)
```berry
# Save DSL with custom functions
var my_show = '''
animation campfire = fire(180, 2s)
animation stars = sparkle(#FFFFFF, 6, 600ms)
sequence night_scene {
play campfire for 30s
play stars for 10s
}
run night_scene
'''
var my_show =
"animation campfire = fire(180, 2s)\n"
"animation stars = sparkle(#FFFFFF, 6, 600ms)\n"
"\n"
"sequence night_scene {\n"
" play campfire for 30s\n"
" play stars for 10s\n"
"}\n"
"\n"
"run night_scene"
# Save to file
var f = open("night_scene.anim", "w")

View File

@ -92,18 +92,9 @@ class BeaconAnimation : animation.animation
i = left_slew_min
while i < left_slew_max
# Calculate blend factor (255 = background, 0 = beacon color)
var blend_factor
if slew_size == 1
# For single pixel slew, use 50% blend
blend_factor = 128
else
blend_factor = tasmota.scale_uint(i, pos - slew_size, pos - 1, 255, 0)
end
# Create color with appropriate alpha for blending
var alpha = 255 - blend_factor # Invert so 0 = transparent, 255 = opaque
var blend_color = (alpha << 24) | (color & 0x00FFFFFF)
var blended_color = frame.blend(back_color, blend_color)
# Calculate blend factor - blend from 255 (back) to 0 (fore) like original
var blend_factor = tasmota.scale_int(i, pos - slew_size - 1, pos, 255, 0)
var blended_color = frame.blend_linear(back_color, color, blend_factor)
frame.set_pixel_color(i, blended_color)
i += 1
end
@ -121,18 +112,9 @@ class BeaconAnimation : animation.animation
i = right_slew_min
while i < right_slew_max
# Calculate blend factor (0 = beacon color, 255 = background)
var blend_factor
if slew_size == 1
# For single pixel slew, use 50% blend
blend_factor = 128
else
blend_factor = tasmota.scale_uint(i, pos + beacon_size, pos + beacon_size + slew_size - 1, 0, 255)
end
# Create color with appropriate alpha for blending
var alpha = 255 - blend_factor # Start opaque, fade to transparent
var blend_color = (alpha << 24) | (color & 0x00FFFFFF)
var blended_color = frame.blend(back_color, blend_color)
# Calculate blend factor - blend from 0 (fore) to 255 (back) like original
var blend_factor = tasmota.scale_int(i, pos + beacon_size - 1, pos + beacon_size + slew_size, 0, 255)
var blended_color = frame.blend_linear(back_color, color, blend_factor)
frame.set_pixel_color(i, blended_color)
i += 1
end

View File

@ -168,6 +168,9 @@ class AnimationEngine
current_time = tasmota.millis()
end
# Check if strip length changed since last time
self.check_strip_length()
# Update engine time
self.time_ms = current_time
@ -356,6 +359,7 @@ class AnimationEngine
end
def get_strip_length()
self.check_strip_length()
return self.width
end
@ -371,6 +375,34 @@ class AnimationEngine
return self.animations
end
# Check if the length of the strip changes
#
# @return bool - True if strip lengtj was changed, false otherwise
def check_strip_length()
var current_length = self.strip.length()
if current_length != self.width
self._handle_strip_length_change(current_length)
return true # Length changed
end
return false # No change
end
# Handle strip length changes by resizing buffers
def _handle_strip_length_change(new_length)
if new_length <= 0
return # Invalid length, ignore
end
self.width = new_length
# Resize existing frame buffers instead of creating new ones
self.frame_buffer.resize(new_length)
self.temp_buffer.resize(new_length)
# Force a render to clear any stale pixels
self.render_needed = true
end
# Cleanup method for proper resource management
def cleanup()
self.stop()

View File

@ -73,6 +73,24 @@ class FrameBuffer
self.pixels.resize(self.width * 4) # resize to full size filled with transparent black (all zeroes)
end
# Resize the frame buffer to a new width
# This is more efficient than creating a new frame buffer object
def resize(new_width)
if new_width <= 0
raise "value_error", "width must be positive"
end
if new_width == self.width
return # No change needed
end
self.width = new_width
# Resize the underlying bytes buffer
self.pixels.resize(self.width * 4)
# Clear to ensure all new pixels are transparent black
self.clear()
end
# Convert separate a, r, g, b components to a 32-bit color value
# r: red component (0-255)
# g: green component (0-255)
@ -158,6 +176,46 @@ class FrameBuffer
return (int(a) << 24) | (int(r) << 16) | (int(g) << 8) | int(b)
end
# Linear interpolation between two colors using explicit blend factor
# Returns the blended color as a 32-bit integer (ARGB format - 0xAARRGGBB)
#
# This function matches the original berry_animate frame.blend(color1, color2, blend_factor) behavior
# Used for creating smooth gradients like beacon slew regions
#
# color1: destination/background color (ARGB format - 0xAARRGGBB)
# color2: source/foreground color (ARGB format - 0xAARRGGBB)
# blend_factor: blend factor (0-255 integer)
# - 0 = full color2 (foreground)
# - 255 = full color1 (background)
def blend_linear(color1, color2, blend_factor)
# Extract components from color1 (background/destination)
var back_a = (color1 >> 24) & 0xFF
var back_r = (color1 >> 16) & 0xFF
var back_g = (color1 >> 8) & 0xFF
var back_b = color1 & 0xFF
# Extract components from color2 (foreground/source)
var fore_a = (color2 >> 24) & 0xFF
var fore_r = (color2 >> 16) & 0xFF
var fore_g = (color2 >> 8) & 0xFF
var fore_b = color2 & 0xFF
# Linear interpolation: result = fore + (back - fore) * blend_factor / 255
var result_a = fore_a + (back_a - fore_a) * blend_factor / 255
var result_r = fore_r + (back_r - fore_r) * blend_factor / 255
var result_g = fore_g + (back_g - fore_g) * blend_factor / 255
var result_b = fore_b + (back_b - fore_b) * blend_factor / 255
# Ensure values are in valid range
result_a = result_a < 0 ? 0 : (result_a > 255 ? 255 : result_a)
result_r = result_r < 0 ? 0 : (result_r > 255 ? 255 : result_r)
result_g = result_g < 0 ? 0 : (result_g > 255 ? 255 : result_g)
result_b = result_b < 0 ? 0 : (result_b > 255 ? 255 : result_b)
# Combine components into a 32-bit value (ARGB format)
return (int(result_a) << 24) | (int(result_r) << 16) | (int(result_g) << 8) | int(result_b)
end
# Blend this frame buffer with another frame buffer using per-pixel alpha
# other_buffer: the other frame buffer to blend with
# mode: blending mode (default: BLEND_MODE_NORMAL)

View File

@ -585,8 +585,8 @@ class SimpleDSLTranspiler
end
end
# Only create closures at the top level
if is_top_level && self.is_computed_expression_string(left)
# Only create closures at the top level, but not for anonymous functions
if is_top_level && self.is_computed_expression_string(left) && !self.is_anonymous_function(left)
return self.create_computation_closure_from_string(left)
else
return left
@ -656,8 +656,12 @@ class SimpleDSLTranspiler
if (tok.type == animation_dsl.Token.KEYWORD || tok.type == animation_dsl.Token.IDENTIFIER) &&
self.peek() != nil && self.peek().type == animation_dsl.Token.LEFT_PAREN
# Check if this is a simple function call first
var func_name = tok.value
if self._is_simple_function_call(func_name)
return self.process_function_call(context)
# Check if this is a nested function call or a variable assignment with named parameters
if context == "argument" || context == "property" || context == "variable"
elif context == "argument" || context == "property" || context == "variable"
return self.process_nested_function_call()
else
return self.process_function_call(context)
@ -745,6 +749,13 @@ class SimpleDSLTranspiler
return "nil"
end
# Check if an expression is already an anonymous function
def is_anonymous_function(expr_str)
import string
# Check if the expression starts with "(def " and ends with ")(engine)"
return string.find(expr_str, "(def ") == 0 && string.find(expr_str, ")(engine)") >= 0
end
# Check if an expression string contains computed values that need a closure
def is_computed_expression_string(expr_str)
import string
@ -758,16 +769,27 @@ class SimpleDSLTranspiler
)
# Check for function calls (parentheses with identifiers before them)
# This excludes simple parenthesized literals like (-1)
# This excludes simple parenthesized literals like (-1) and simple function calls
var has_function_calls = false
var paren_pos = string.find(expr_str, "(")
if paren_pos > 0
# Check if there's an identifier before the parenthesis (indicating a function call)
var char_before = expr_str[paren_pos-1]
if self.is_identifier_char(char_before)
# Extract the function name to check if it's a simple function
var func_start = paren_pos - 1
while func_start >= 0 && self.is_identifier_char(expr_str[func_start])
func_start -= 1
end
func_start += 1
var func_name = expr_str[func_start..paren_pos-1]
# Only mark as needing closure if it's NOT a simple function
if !self._is_simple_function_call(func_name)
has_function_calls = true
end
end
end
# Only create closures for expressions that actually involve computation
return has_operators || has_function_calls
@ -1032,9 +1054,12 @@ class SimpleDSLTranspiler
var full_args = args != "" ? f"engine, {args}" : "engine"
return f"animation.get_user_function('{func_name}')({full_args})"
else
# All functions are resolved from the animation module
# No context-specific mapping needed with unified architecture
return f"animation.{func_name}({args})"
# All functions are resolved from the animation module and need engine as first parameter
if args != ""
return f"animation.{func_name}(engine, {args})"
else
return f"animation.{func_name}(engine)"
end
end
end
@ -1415,6 +1440,16 @@ class SimpleDSLTranspiler
var args = self.process_function_arguments_for_expression()
var full_args = args != "" ? f"self.engine, {args}" : "self.engine"
return f"animation.get_user_function('{func_name}')({full_args})"
else
# Check if this is a simple function call without named parameters
if self._is_simple_function_call(func_name)
# For simple functions like strip_length(), do direct assignment
var args = self.process_function_arguments()
if args != ""
return f"animation.{func_name}(engine, {args})"
else
return f"animation.{func_name}(engine)"
end
else
# Built-in functions use the new engine-first + named parameters pattern
# Validate that the factory function exists at transpilation time
@ -1424,17 +1459,9 @@ class SimpleDSLTranspiler
return "nil"
end
# Generate unique temporary variable name using position
var temp_var = f"temp_{func_name}_{self.pos}"
# Generate the base function call
self.add(f"var {temp_var} = animation.{func_name}(engine)")
# Process named arguments for the temporary variable with validation
self._process_named_arguments_for_animation(temp_var, func_name)
# Return the temporary variable name
return temp_var
# Generate anonymous function that creates and configures the provider
return self._generate_anonymous_function_call(func_name)
end
end
end
@ -2169,6 +2196,98 @@ class SimpleDSLTranspiler
self._process_named_arguments_generic(var_name, func_name)
end
# Check if this is a simple function call that doesn't need anonymous function treatment
def _is_simple_function_call(func_name)
# Functions that return simple values and don't use named parameters
var simple_functions = [
"strip_length",
"static_value"
]
for simple_func : simple_functions
if func_name == simple_func
return true
end
end
return false
end
# Generate anonymous function call that creates and configures a provider without temporary variables
def _generate_anonymous_function_call(func_name)
# Start building the anonymous function
var lines = []
lines.push("(def (engine)")
lines.push(f" var provider = animation.{func_name}(engine)")
# Process named arguments and collect them
self.expect_left_paren()
# Create animation instance once for parameter validation
var animation_instance = self._create_animation_instance_for_validation(func_name)
while !self.at_end() && !self.check_right_paren()
self.skip_whitespace_including_newlines()
if self.check_right_paren()
break
end
# Parse named argument: param_name=value
var param_name = self.expect_identifier()
# Validate parameter immediately as it's parsed
if animation_instance != nil
self._validate_single_parameter(func_name, param_name, animation_instance)
end
self.expect_assign()
var param_value = self.process_value("argument")
var inline_comment = self.collect_inline_comment()
# Add parameter assignment to the anonymous function
lines.push(f" provider.{param_name} = {param_value}{inline_comment}")
# Skip whitespace but preserve newlines for separator detection
while !self.at_end()
var tok = self.current()
if tok != nil && tok.type == animation_dsl.Token.COMMENT
self.next()
else
break
end
end
# Check for parameter separator: comma OR newline OR end of parameters
if self.current() != nil && self.current().type == animation_dsl.Token.COMMA
self.next() # skip comma
self.skip_whitespace_including_newlines()
elif self.current() != nil && self.current().type == animation_dsl.Token.NEWLINE
# Newline acts as parameter separator - skip it and continue
self.next() # skip newline
self.skip_whitespace_including_newlines()
elif !self.check_right_paren()
self.error("Expected ',' or ')' in function arguments")
break
end
end
self.expect_right_paren()
# Complete the anonymous function
lines.push(" return provider")
lines.push("end)(engine)")
# Join all lines into a single expression
var result = ""
for i : 0..size(lines)-1
if i > 0
result += "\n"
end
result += lines[i]
end
return result
end
end
# DSL compilation function

View File

@ -142,7 +142,7 @@ class ClosureValueProvider : animation.value_provider
#
# @param angle: number - Angle in 0-255 range (0-360 degrees)
# @return int - Sine value in -255 to 255 range
def sine(angle)
def sin(angle)
# Map angle from 0-255 to 0-32767 (tasmota.sine_int input range)
var tasmota_angle = tasmota.scale_int(angle, 0, 255, 0, 32767)
@ -160,7 +160,7 @@ class ClosureValueProvider : animation.value_provider
#
# @param angle: number - Angle in 0-255 range (0-360 degrees)
# @return int - Cosine value in -255 to 255 range
def cosine(angle)
def cos(angle)
# Map angle from 0-255 to 0-32767 (tasmota.sine_int input range)
var tasmota_angle = tasmota.scale_int(angle, 0, 255, 0, 32767)

View File

@ -108,12 +108,12 @@ class OscillatorValueProvider : animation.value_provider
# Calculate value based on waveform
if form == animation.SAWTOOTH
self.value = tasmota.scale_uint(past_with_phase, 0, duration - 1, min_value, max_value)
self.value = tasmota.scale_int(past_with_phase, 0, duration - 1, min_value, max_value)
elif form == animation.TRIANGLE
if past_with_phase < duration_ms_mid
self.value = tasmota.scale_uint(past_with_phase, 0, duration_ms_mid - 1, min_value, max_value)
self.value = tasmota.scale_int(past_with_phase, 0, duration_ms_mid - 1, min_value, max_value)
else
self.value = tasmota.scale_uint(past_with_phase, duration_ms_mid, duration - 1, max_value, min_value)
self.value = tasmota.scale_int(past_with_phase, duration_ms_mid, duration - 1, max_value, min_value)
end
elif form == animation.SQUARE
if past_with_phase < duration_ms_mid
@ -125,22 +125,22 @@ class OscillatorValueProvider : animation.value_provider
# Map timing to 0..32767 for sine calculation
var angle = tasmota.scale_uint(past_with_phase, 0, duration - 1, 0, 32767)
var x = tasmota.sine_int(angle - 8192) # -4096 .. 4096, dephase from cosine to sine
self.value = tasmota.scale_uint(x, -4096, 4096, min_value, max_value)
self.value = tasmota.scale_int(x, -4096, 4096, min_value, max_value)
elif form == animation.SINE
# Map timing to 0..32767 for sine calculation
var angle = tasmota.scale_uint(past_with_phase, 0, duration - 1, 0, 32767)
var x = tasmota.sine_int(angle) # -4096 .. 4096, pure sine wave
self.value = tasmota.scale_uint(x, -4096, 4096, min_value, max_value)
self.value = tasmota.scale_int(x, -4096, 4096, min_value, max_value)
elif form == animation.EASE_IN
# Quadratic ease-in: starts slow, accelerates
var t = tasmota.scale_uint(past_with_phase, 0, duration - 1, 0, 255) # 0..255
var eased = (t * t) / 255 # t^2 scaled back to 0..255
self.value = tasmota.scale_uint(eased, 0, 255, min_value, max_value)
self.value = tasmota.scale_int(eased, 0, 255, min_value, max_value)
elif form == animation.EASE_OUT
# Quadratic ease-out: starts fast, decelerates
var t = tasmota.scale_uint(past_with_phase, 0, duration - 1, 0, 255) # 0..255
var eased = 255 - ((255 - t) * (255 - t)) / 255 # 1 - (1-t)^2 scaled to 0..255
self.value = tasmota.scale_uint(eased, 0, 255, min_value, max_value)
self.value = tasmota.scale_int(eased, 0, 255, min_value, max_value)
elif form == animation.ELASTIC
# Elastic easing: overshoots and oscillates like a spring
var t = tasmota.scale_uint(past_with_phase, 0, duration - 1, 0, 255) # 0..255
@ -155,7 +155,7 @@ class OscillatorValueProvider : animation.value_provider
var freq_angle = tasmota.scale_uint(t, 0, 255, 0, 32767 * 6) # High frequency oscillation
var oscillation = tasmota.sine_int(freq_angle % 32767) # -4096 to 4096
var elastic_offset = (oscillation * decay) / 4096 # Scale oscillation by decay
var base_progress = tasmota.scale_uint(t, 0, 255, 0, max_value - min_value)
var base_progress = tasmota.scale_int(t, 0, 255, 0, max_value - min_value)
self.value = min_value + base_progress + elastic_offset
# Clamp to reasonable bounds to prevent extreme overshoots
var value_range = max_value - min_value
@ -182,7 +182,7 @@ class OscillatorValueProvider : animation.value_provider
bounced_t = 255 - ((255 - bounce_val) * 64) / 255 # Settle towards full value
end
self.value = tasmota.scale_uint(bounced_t, 0, 255, min_value, max_value)
self.value = tasmota.scale_int(bounced_t, 0, 255, min_value, max_value)
end
return self.value
@ -232,11 +232,21 @@ def smooth(engine)
return osc
end
# Create a cosine oscillator (alias for smooth - cosine wave)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New cosine oscillator instance
def cosine_osc(engine)
var osc = animation.oscillator_value(engine)
osc.form = animation.COSINE
return osc
end
# Create a sine wave oscillator
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New sine wave instance
def sine(engine)
def sine_osc(engine)
var osc = animation.oscillator_value(engine)
osc.form = animation.SINE
return osc
@ -317,7 +327,8 @@ return {'ramp': ramp,
'linear': linear,
'triangle': triangle,
'smooth': smooth,
'sine': sine,
'cosine_osc': cosine_osc,
'sine_osc': sine_osc,
'square': square,
'ease_in': ease_in,
'ease_out': ease_out,

File diff suppressed because it is too large Load Diff

View File

@ -171,6 +171,201 @@ var engine3 = animation.animation_engine(strip)
assert_not_nil(engine3, "Direct engine creation should work")
assert_equals(engine3.width, strip.length(), "Direct engine width should match strip")
# Test 10: Dynamic Strip Length Detection
print("\n--- Test 10: Dynamic Strip Length Detection ---")
# Create a mock strip that can change length at runtime
class MockDynamicStrip
var _length
var pixels
var show_calls
def init(initial_length)
self._length = initial_length
self.pixels = []
self.pixels.resize(initial_length)
self.show_calls = 0
end
def length()
return self._length
end
def set_length(new_length)
self._length = new_length
self.pixels.resize(new_length)
end
def set_pixel_color(index, color)
if index >= 0 && index < self._length
self.pixels[index] = color
end
end
def clear()
var i = 0
while i < self._length
self.pixels[i] = 0
i += 1
end
end
def show()
self.show_calls += 1
end
def can_show()
return true
end
end
# Create engine with dynamic strip
var dynamic_strip = MockDynamicStrip(15)
var dynamic_engine = animation.animation_engine(dynamic_strip)
# Test initial state
assert_equals(dynamic_engine.width, 15, "Engine should start with strip length 15")
assert_equals(dynamic_engine.frame_buffer.width, 15, "Frame buffer should match initial length")
assert_equals(dynamic_engine.temp_buffer.width, 15, "Temp buffer should match initial length")
# Store references to check object reuse
var original_frame_buffer = dynamic_engine.frame_buffer
var original_temp_buffer = dynamic_engine.temp_buffer
# Test 10a: No change detection
print("\n--- Test 10a: No change detection ---")
var length_changed = dynamic_engine.check_strip_length()
assert_test(!length_changed, "Should detect no change when length is same")
assert_equals(dynamic_engine.width, 15, "Engine width should remain 15")
# Test 10b: Manual length change detection
print("\n--- Test 10b: Manual length change detection ---")
dynamic_strip.set_length(25)
length_changed = dynamic_engine.check_strip_length()
assert_test(length_changed, "Should detect length change from 15 to 25")
assert_equals(dynamic_engine.width, 25, "Engine width should update to 25")
assert_equals(dynamic_engine.frame_buffer.width, 25, "Frame buffer should resize to 25")
assert_equals(dynamic_engine.temp_buffer.width, 25, "Temp buffer should resize to 25")
# Verify buffer objects were reused (efficient)
var frame_reused = (dynamic_engine.frame_buffer == original_frame_buffer)
var temp_reused = (dynamic_engine.temp_buffer == original_temp_buffer)
assert_test(frame_reused, "Frame buffer object should be reused for efficiency")
assert_test(temp_reused, "Temp buffer object should be reused for efficiency")
# Test 10c: Runtime detection during on_tick()
print("\n--- Test 10c: Runtime detection during on_tick() ---")
dynamic_engine.start()
# Add a test animation
var runtime_anim = animation.solid(dynamic_engine)
runtime_anim.color = 0xFF00FF00 # Green
runtime_anim.priority = 10
dynamic_engine.add_animation(runtime_anim)
# Simulate several ticks with stable length
var tick_time = tasmota.millis()
for i : 0..2
dynamic_engine.on_tick(tick_time + i * 10)
end
assert_equals(dynamic_engine.width, 25, "Width should remain stable during normal ticks")
# Change strip length during runtime
dynamic_strip.set_length(35)
var old_show_calls = dynamic_strip.show_calls
# Next tick should detect the change automatically
dynamic_engine.on_tick(tick_time + 50)
assert_equals(dynamic_engine.width, 35, "Engine should detect length change during on_tick()")
assert_equals(dynamic_engine.frame_buffer.width, 35, "Frame buffer should resize during on_tick()")
assert_equals(dynamic_engine.temp_buffer.width, 35, "Temp buffer should resize during on_tick()")
# Verify rendering still works after length change
var new_show_calls = dynamic_strip.show_calls
assert_test(new_show_calls >= old_show_calls, "Strip should be updated after length change (or at least not decrease)")
# Test 10d: Multiple length changes
print("\n--- Test 10d: Multiple length changes ---")
var lengths_to_test = [10, 50, 5, 30]
for new_length : lengths_to_test
dynamic_strip.set_length(new_length)
dynamic_engine.on_tick(tasmota.millis())
assert_equals(dynamic_engine.width, new_length, f"Engine should adapt to length {new_length}")
assert_equals(dynamic_engine.frame_buffer.width, new_length, f"Frame buffer should adapt to length {new_length}")
assert_equals(dynamic_engine.temp_buffer.width, new_length, f"Temp buffer should adapt to length {new_length}")
end
# Test 10e: Length change with multiple animations
print("\n--- Test 10e: Length change with multiple animations ---")
dynamic_engine.clear()
# Add multiple animations
var red_anim = animation.solid(dynamic_engine)
red_anim.color = 0xFFFF0000
red_anim.priority = 20
dynamic_engine.add_animation(red_anim)
var blue_anim = animation.solid(dynamic_engine)
blue_anim.color = 0xFF0000FF
blue_anim.priority = 10
dynamic_engine.add_animation(blue_anim)
assert_equals(dynamic_engine.size(), 2, "Should have 2 animations")
# Change length and verify all animations continue working
dynamic_strip.set_length(40)
old_show_calls = dynamic_strip.show_calls
dynamic_engine.on_tick(tasmota.millis())
assert_equals(dynamic_engine.width, 40, "Engine should handle length change with multiple animations")
new_show_calls = dynamic_strip.show_calls
assert_test(new_show_calls >= old_show_calls, "Rendering should continue with multiple animations (or at least not decrease)")
assert_equals(dynamic_engine.size(), 2, "Should still have 2 animations after length change")
# Test 10f: Invalid length handling
print("\n--- Test 10f: Invalid length handling ---")
var current_width = dynamic_engine.width
# Test zero length (should be ignored)
dynamic_strip.set_length(0)
dynamic_engine.on_tick(tasmota.millis())
assert_equals(dynamic_engine.width, current_width, "Should ignore zero length")
# Test negative length (should be ignored)
dynamic_strip.set_length(-5)
dynamic_engine.on_tick(tasmota.millis())
assert_equals(dynamic_engine.width, current_width, "Should ignore negative length")
# Restore valid length
dynamic_strip.set_length(20)
dynamic_engine.on_tick(tasmota.millis())
assert_equals(dynamic_engine.width, 20, "Should accept valid length after invalid ones")
# Test 10g: Performance impact of length checking
print("\n--- Test 10g: Performance impact of length checking ---")
dynamic_strip.set_length(30)
dynamic_engine.check_strip_length() # Ensure stable state
var perf_start_time = tasmota.millis()
# Run many ticks with stable length (should be fast)
for i : 0..99
dynamic_engine.on_tick(perf_start_time + i)
end
var stable_time = tasmota.millis() - perf_start_time
# Now test with length changes (should still be reasonable)
perf_start_time = tasmota.millis()
for i : 0..19
dynamic_strip.set_length(30 + (i % 5)) # Change length every few ticks
dynamic_engine.on_tick(perf_start_time + i * 5)
end
var changing_time = tasmota.millis() - perf_start_time
assert_test(stable_time < 100, f"100 stable ticks should be fast (took {stable_time}ms)")
assert_test(changing_time < 200, f"20 ticks with length changes should be reasonable (took {changing_time}ms)")
dynamic_engine.stop()
# Cleanup
engine.stop()

View File

@ -383,63 +383,63 @@ def test_closure_math_methods()
assert(scale_neg == 0, f"Expected scale(0,-50,50,-100,100)=0, got {scale_neg}")
print("✓ scale function works correctly")
# Test 6: sine function
# Test 6: sin function
provider.closure = def(self, name, time_ms)
if name == "sine_0"
return self.sine(0) # sin(0°) = 0
elif name == "sine_64"
return self.sine(64) # sin(90°) = 1 -> 255
elif name == "sine_128"
return self.sine(128) # sin(180°) = 0
elif name == "sine_192"
return self.sine(192) # sin(270°) = -1 -> -255
if name == "sin_0"
return self.sin(0) # sin(0°) = 0
elif name == "sin_64"
return self.sin(64) # sin(90°) = 1 -> 255
elif name == "sin_128"
return self.sin(128) # sin(180°) = 0
elif name == "sin_192"
return self.sin(192) # sin(270°) = -1 -> -255
else
return 0
end
end
var sine_0 = provider.produce_value("sine_0", 1000)
var sine_64 = provider.produce_value("sine_64", 1000)
var sine_128 = provider.produce_value("sine_128", 1000)
var sine_192 = provider.produce_value("sine_192", 1000)
var sin_0 = provider.produce_value("sin_0", 1000)
var sin_64 = provider.produce_value("sin_64", 1000)
var sin_128 = provider.produce_value("sin_128", 1000)
var sin_192 = provider.produce_value("sin_192", 1000)
assert(sine_0 >= -5 && sine_0 <= 5, f"Expected sine(0)~0, got {sine_0}")
assert(sine_64 >= 250 && sine_64 <= 255, f"Expected sine(64)~255, got {sine_64}")
assert(sine_128 >= -5 && sine_128 <= 5, f"Expected sine(128)~0, got {sine_128}")
assert(sine_192 >= -255 && sine_192 <= -250, f"Expected sine(192)~-255, got {sine_192}")
print("✓ sine function works correctly")
assert(sin_0 >= -5 && sin_0 <= 5, f"Expected sin(0)~0, got {sin_0}")
assert(sin_64 >= 250 && sin_64 <= 255, f"Expected sin(64)~255, got {sin_64}")
assert(sin_128 >= -5 && sin_128 <= 5, f"Expected sin(128)~0, got {sin_128}")
assert(sin_192 >= -255 && sin_192 <= -250, f"Expected sin(192)~-255, got {sin_192}")
print("✓ sin function works correctly")
# Test 7: cosine function (matches oscillator COSINE behavior)
# Test 7: cos function (matches oscillator COSINE behavior)
provider.closure = def(self, name, time_ms)
if name == "cosine_0"
return self.cosine(0) # Oscillator cosine at 0° = minimum -> -255
elif name == "cosine_64"
return self.cosine(64) # Oscillator cosine at 90° = ~0
elif name == "cosine_128"
return self.cosine(128) # Oscillator cosine at 180° = maximum -> 255
elif name == "cosine_192"
return self.cosine(192) # Oscillator cosine at 270° = ~0
if name == "cos_0"
return self.cos(0) # Oscillator cosine at 0° = minimum -> -255
elif name == "cos_64"
return self.cos(64) # Oscillator cosine at 90° = ~0
elif name == "cos_128"
return self.cos(128) # Oscillator cosine at 180° = maximum -> 255
elif name == "cos_192"
return self.cos(192) # Oscillator cosine at 270° = ~0
else
return 0
end
end
var cosine_0 = provider.produce_value("cosine_0", 1000)
var cosine_64 = provider.produce_value("cosine_64", 1000)
var cosine_128 = provider.produce_value("cosine_128", 1000)
var cosine_192 = provider.produce_value("cosine_192", 1000)
var cos_0 = provider.produce_value("cos_0", 1000)
var cos_64 = provider.produce_value("cos_64", 1000)
var cos_128 = provider.produce_value("cos_128", 1000)
var cos_192 = provider.produce_value("cos_192", 1000)
assert(cosine_0 >= -255 && cosine_0 <= -250, f"Expected cosine(0)~-255, got {cosine_0}")
assert(cosine_64 >= -5 && cosine_64 <= 5, f"Expected cosine(64)~0, got {cosine_64}")
assert(cosine_128 >= 250 && cosine_128 <= 255, f"Expected cosine(128)~255, got {cosine_128}")
assert(cosine_192 >= -5 && cosine_192 <= 5, f"Expected cosine(192)~0, got {cosine_192}")
print("✓ cosine function works correctly")
assert(cos_0 >= -255 && cos_0 <= -250, f"Expected cos(0)~-255, got {cos_0}")
assert(cos_64 >= -5 && cos_64 <= 5, f"Expected cos(64)~0, got {cos_64}")
assert(cos_128 >= 250 && cos_128 <= 255, f"Expected cos(128)~255, got {cos_128}")
assert(cos_192 >= -5 && cos_192 <= 5, f"Expected cos(192)~0, got {cos_192}")
print("✓ cos function works correctly")
# Test 8: Complex expression using multiple math functions
provider.closure = def(self, name, time_ms)
if name == "complex_math"
var angle = time_ms % 256 # 0-255 angle based on time
var sine_val = self.abs(self.sine(angle)) # Absolute sine value
var sine_val = self.abs(self.sin(angle)) # Absolute sine value
var scaled = self.scale(sine_val, 0, 255, 50, 200) # Scale to 50-200 range
return self.min(self.max(scaled, 75), 175) # Clamp to 75-175 range
else

View File

@ -150,8 +150,10 @@ def test_nested_function_calls()
assert(berry_code != nil, "Should compile nested function calls with newline syntax")
assert(string.find(berry_code, "var nested_ = animation.pulsating_animation(engine)") >= 0, "Should generate main animation")
assert(string.find(berry_code, "var temp_solid_") >= 0, "Should generate nested solid call")
assert(string.find(berry_code, "var temp_triangle_") >= 0, "Should generate nested triangle call")
assert(string.find(berry_code, "nested_.color = (def (engine)") >= 0, "Should generate nested solid call as anonymous function")
assert(string.find(berry_code, "nested_.period = (def (engine)") >= 0, "Should generate nested triangle call as anonymous function")
assert(string.find(berry_code, "var provider = animation.solid(engine)") >= 0, "Should generate solid provider in anonymous function")
assert(string.find(berry_code, "var provider = animation.triangle(engine)") >= 0, "Should generate triangle provider in anonymous function")
print("✓ Nested function calls test passed")
return true

View File

@ -173,6 +173,9 @@ def test_cosine_waveform()
var value_75 = osc.produce_value("test", start_time + 750) # t=750ms (75% - falling)
var value_100 = osc.produce_value("test", start_time + 999) # t=999ms (back to minimum)
# Print actual values for debugging
print(f" COSINE values: t=0%: {value_0}, t=25%: {value_25}, t=50%: {value_50}, t=75%: {value_75}, t=99.9%: {value_100}")
# Cosine should be smooth curve from min to max and back
# Note: The cosine implementation uses sine with phase shift, so values may differ from pure cosine
assert(value_0 >= 0 && value_0 <= 10, f"Value at 0% should be ~0, got {value_0}")
@ -181,6 +184,12 @@ def test_cosine_waveform()
assert(value_75 >= 40 && value_75 <= 60, f"Value at 75% should be ~50, got {value_75}")
assert(value_100 >= 0 && value_100 <= 10, f"Value at 99.9% should be ~0, got {value_100}")
# Verify values are actually changing over time
assert(value_0 != value_25, "COSINE values should change between 0% and 25%")
assert(value_25 != value_50, "COSINE values should change between 25% and 50%")
assert(value_50 != value_75, "COSINE values should change between 50% and 75%")
assert(value_75 != value_100, "COSINE values should change between 75% and 99.9%")
print("✓ COSINE waveform test passed")
end
@ -204,6 +213,9 @@ def test_sine_waveform()
var value_75 = osc.produce_value("test", start_time + 750) # t=750ms (75% - minimum)
var value_100 = osc.produce_value("test", start_time + 999) # t=999ms (back to middle)
# Print actual values for debugging
print(f" SINE values: t=0%: {value_0}, t=25%: {value_25}, t=50%: {value_50}, t=75%: {value_75}, t=99.9%: {value_100}")
# Sine should be smooth curve starting at middle, going to max, middle, min, middle
# At t=0: sine(0) = 0, which maps to middle value (50)
# At t=25%: sine(π/2) = 1, which maps to max value (100)
@ -215,6 +227,12 @@ def test_sine_waveform()
assert(value_75 >= 0 && value_75 <= 10, f"Value at 75% should be ~0 (min), got {value_75}")
assert(value_100 >= 45 && value_100 <= 55, f"Value at 99.9% should be ~50 (back to middle), got {value_100}")
# Verify values are actually changing over time
assert(value_0 != value_25, "SINE values should change between 0% and 25%")
assert(value_25 != value_50, "SINE values should change between 25% and 50%")
assert(value_50 != value_75, "SINE values should change between 50% and 75%")
assert(value_75 != value_100, "SINE values should change between 75% and 99.9%")
print("✓ SINE waveform test passed")
end
@ -282,15 +300,25 @@ def test_static_constructors()
var smooth1 = animation.smooth(mock_engine)
assert(smooth1.form == animation.COSINE, "smooth() should use COSINE")
# Test sine() constructor
var sine1 = animation.sine(mock_engine)
# Test sine_osc() constructor
var sine1 = animation.sine_osc(mock_engine)
sine1.min_value = 0
sine1.max_value = 255
sine1.duration = 2000
assert(sine1.form == animation.SINE, "sine() should use SINE")
assert(sine1.min_value == 0, "sine() should set min_value")
assert(sine1.max_value == 255, "sine() should set max_value")
assert(sine1.duration == 2000, "sine() should set duration")
assert(sine1.form == animation.SINE, "sine_osc() should use SINE")
assert(sine1.min_value == 0, "sine_osc() should set min_value")
assert(sine1.max_value == 255, "sine_osc() should set max_value")
assert(sine1.duration == 2000, "sine_osc() should set duration")
# Test cosine_osc() constructor (alias for smooth)
var cosine1 = animation.cosine_osc(mock_engine)
cosine1.min_value = 25
cosine1.max_value = 200
cosine1.duration = 1800
assert(cosine1.form == animation.COSINE, "cosine_osc() should use COSINE")
assert(cosine1.min_value == 25, "cosine_osc() should set min_value")
assert(cosine1.max_value == 200, "cosine_osc() should set max_value")
assert(cosine1.duration == 1800, "cosine_osc() should set duration")
# Test square() constructor
var square1 = animation.square(mock_engine)
@ -399,6 +427,79 @@ def test_edge_cases()
print("✓ Edge cases test passed")
end
# Test time evolution of COSINE and SINE waveforms
def test_cosine_sine_time_evolution()
print("Testing COSINE and SINE time evolution...")
# Test COSINE evolution over time
var cosine_osc = animation.oscillator_value(mock_engine)
cosine_osc.min_value = 0
cosine_osc.max_value = 255
cosine_osc.duration = 5000 # 5 second cycle
cosine_osc.form = animation.COSINE
var start_time = 10000
cosine_osc.start(start_time)
print(" COSINE waveform evolution (0-255 range, 5000ms duration):")
var cosine_values = []
for i: 0..10
var time_offset = i * 500 # Every 500ms (10% of cycle)
var value = cosine_osc.produce_value("test", start_time + time_offset)
cosine_values.push(value)
var percentage = (i * 10)
print(f" t={percentage}% ({time_offset}ms): {value}")
end
# Test SINE evolution over time
var sine_osc = animation.oscillator_value(mock_engine)
sine_osc.min_value = 0
sine_osc.max_value = 255
sine_osc.duration = 5000 # 5 second cycle
sine_osc.form = animation.SINE
sine_osc.start(start_time)
print(" SINE waveform evolution (0-255 range, 5000ms duration):")
var sine_values = []
for i: 0..10
var time_offset = i * 500 # Every 500ms (10% of cycle)
var value = sine_osc.produce_value("test", start_time + time_offset)
sine_values.push(value)
var percentage = (i * 10)
print(f" t={percentage}% ({time_offset}ms): {value}")
end
# Verify that values are actually changing for both waveforms
var cosine_changes = 0
var sine_changes = 0
for i: 1..10
if cosine_values[i] != cosine_values[i-1]
cosine_changes += 1
end
if sine_values[i] != sine_values[i-1]
sine_changes += 1
end
end
assert(cosine_changes >= 8, f"COSINE should change values at least 8 times out of 10 steps, got {cosine_changes}")
assert(sine_changes >= 8, f"SINE should change values at least 8 times out of 10 steps, got {sine_changes}")
# Verify COSINE starts at minimum and reaches maximum at 50%
assert(cosine_values[0] <= 10, f"COSINE should start near minimum (0), got {cosine_values[0]}")
assert(cosine_values[5] >= 245, f"COSINE should reach near maximum (255) at 50%, got {cosine_values[5]}")
assert(cosine_values[10] <= 10, f"COSINE should return near minimum (0) at 100%, got {cosine_values[10]}")
# Verify SINE starts at middle and follows expected pattern
assert(sine_values[0] >= 120 && sine_values[0] <= 135, f"SINE should start near middle (127), got {sine_values[0]}")
assert(sine_values[2] >= 240, f"SINE should reach near maximum around 25%, got {sine_values[2]} at 20%")
assert(sine_values[5] >= 120 && sine_values[5] <= 135, f"SINE should return to middle at 50%, got {sine_values[5]}")
assert(sine_values[7] <= 15, f"SINE should reach near minimum around 75%, got {sine_values[7]} at 70%")
print("✓ COSINE and SINE time evolution test passed")
end
# Test tostring() method
def test_tostring()
print("Testing tostring() method...")
@ -433,6 +534,7 @@ def run_oscillator_value_provider_tests()
test_square_waveform()
test_cosine_waveform()
test_sine_waveform()
test_cosine_sine_time_evolution()
test_phase_shift()
test_static_constructors()
test_produce_value_method()

View File

@ -109,7 +109,7 @@ def test_is_math_method_function()
var transpiler = animation_dsl.SimpleDSLTranspiler([])
# Test mathematical methods
var math_methods = ["min", "max", "abs", "round", "sqrt", "scale", "sine", "cosine"]
var math_methods = ["min", "max", "abs", "round", "sqrt", "scale", "sin", "cos"]
for method : math_methods
if !transpiler.is_math_method(method)
print(f" ❌ {method} should be detected as a math method")
@ -165,10 +165,10 @@ def test_math_method_transpilation()
var dsl_code3 =
"set angle = 45\n"
"animation rotate = pulsating_animation(color=green, period=2s)\n"
"rotate.brightness = round(sine(angle) * 180 + cosine(angle) * 90)\n"
"rotate.brightness = round(sin(angle) * 180 + cos(angle) * 90)\n"
"run rotate"
var result3 = test_transpilation_case(dsl_code3, ["round", "sine", "cosine"], "Complex math expressions")
var result3 = test_transpilation_case(dsl_code3, ["round", "sin", "cos"], "Complex math expressions")
if !result3
return false
end