Add RLCD animations and screensavers
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# Standalone MicroPython Voice Animation: Waiting Orbit
|
||||
# Exposes run(text="", frames=...) and runs automatically if executed directly.
|
||||
import time
|
||||
import math
|
||||
|
||||
try:
|
||||
import board_config
|
||||
display = getattr(board_config, 'display_instance', None)
|
||||
except Exception:
|
||||
board_config = None
|
||||
display = None
|
||||
|
||||
def draw_center_text(d, msg, y, w, scale=1, c=1):
|
||||
char_w = 8 * scale
|
||||
x = max(0, (w - len(msg) * char_w) // 2)
|
||||
if hasattr(d, 'text_large') and scale > 1:
|
||||
try:
|
||||
d.text_large(msg, x, y, scale, c)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
d.text(msg, x, y, c)
|
||||
|
||||
def run(text="", frames=100):
|
||||
if not display:
|
||||
print("board_config.display_instance is not available. Skipping animation.")
|
||||
return
|
||||
|
||||
width = getattr(display, 'width', 400)
|
||||
height = getattr(display, 'height', 300)
|
||||
cx, cy = width // 2, height // 2
|
||||
|
||||
label = text if text else "THINKING..."
|
||||
frame = 0
|
||||
|
||||
try:
|
||||
while True:
|
||||
if frames is not None and frames > 0 and frame >= frames:
|
||||
break
|
||||
|
||||
display.clear(0)
|
||||
|
||||
# Draw central pulsing core
|
||||
# Uses sin wave to expand/contract
|
||||
pulse = int(14 + 4 * math.sin(frame * 0.18))
|
||||
display.rect(cx - pulse, cy - pulse, pulse * 2, pulse * 2, 1)
|
||||
display.rect(cx - pulse + 3, cy - pulse + 3, (pulse - 3) * 2, (pulse - 3) * 2, 1)
|
||||
display.fill_rect(cx - 3, cy - 3, 6, 6, 1)
|
||||
|
||||
# Draw a dotted circular path of radius 60
|
||||
for a_deg in range(0, 360, 15):
|
||||
angle = math.radians(a_deg)
|
||||
px = cx + int(60 * math.cos(angle))
|
||||
py = cy + int(60 * math.sin(angle))
|
||||
display.fill_rect(px, py, 2, 2, 1)
|
||||
|
||||
# Draw 4 orbiting ring nodes
|
||||
for node_idx in range(4):
|
||||
angle = (frame * 0.08) + (node_idx * math.pi / 2)
|
||||
nx = cx + int(60 * math.cos(angle))
|
||||
ny = cy + int(60 * math.sin(angle))
|
||||
|
||||
# Draw square ring nodes
|
||||
display.fill_rect(nx - 6, ny - 6, 12, 12, 1)
|
||||
display.fill_rect(nx - 4, ny - 4, 8, 8, 0)
|
||||
|
||||
# Draw centered text label at the bottom
|
||||
draw_center_text(display, label, height - 35, width, scale=1, c=1)
|
||||
|
||||
display.show()
|
||||
frame += 1
|
||||
|
||||
try:
|
||||
time.sleep_ms(50)
|
||||
except AttributeError:
|
||||
time.sleep(0.05)
|
||||
except KeyboardInterrupt:
|
||||
print("Animation interrupted by user.")
|
||||
|
||||
if __name__ in ('__main__', '__name__'):
|
||||
run()
|
||||
Reference in New Issue
Block a user