Files
mcp_screen/voice_animations/breathing_idle.py
T
2026-06-21 21:19:51 -04:00

81 lines
2.5 KiB
Python

# Standalone MicroPython Voice Animation: Breathing Idle
# 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 "READY"
frame = 0
try:
while True:
if frames is not None and frames > 0 and frame >= frames:
break
display.clear(0)
# Cosine-based breathing curve: slow and smooth, scaling from 0 to 1 and back
breath_scale = 0.5 + 0.5 * math.cos(frame * 0.07)
# Draw three concentric breathing boxes
# Base radii are scaled dynamically
r1 = int(24 + 32 * breath_scale)
r2 = int(14 + 18 * breath_scale)
r3 = int(6 + 8 * breath_scale)
# Outer box
display.rect(cx - r1, cy - r1, r1 * 2, r1 * 2, 1)
# Middle box
display.rect(cx - r2, cy - r2, r2 * 2, r2 * 2, 1)
# Inner solid core
display.fill_rect(cx - r3, cy - r3, r3 * 2, r3 * 2, 1)
# Draw small accent dots at the corners of the outer breathing box
accent = r1 + 8
display.fill_rect(cx - accent - 2, cy - accent - 2, 4, 4, 1)
display.fill_rect(cx + accent - 2, cy - accent - 2, 4, 4, 1)
display.fill_rect(cx - accent - 2, cy + accent - 2, 4, 4, 1)
display.fill_rect(cx + accent - 2, cy + accent - 2, 4, 4, 1)
# Draw centered text label at the bottom
draw_center_text(display, label, height - 30, width, scale=1, c=1)
display.show()
frame += 1
try:
time.sleep_ms(65)
except AttributeError:
time.sleep(0.065)
except KeyboardInterrupt:
print("Animation interrupted by user.")
if __name__ in ('__main__', '__name__'):
run()