#!/usr/bin/env python3 """Gold Latin mottoes scrolling continuously around the portal ring.""" from __future__ import annotations import math from leds.bpm_limits import band, resolve_pulse, resolve_scroll from leds.colors import dim from leds.pattern import Color, Param, Pattern, run_cli, set_pixel, size from leds.portal_span import global_x, ring_metrics from leds.text import CHAR_HEIGHT, draw_text, text_width MOTTOES = ( "AVE", "SPQR", "VENI VIDI VICI", "CARPE DIEM", "TEMPUS FUGIT", "MEMENTO MORI", "ALEA IACTA EST", ) SEPARATOR = " * " DEFAULT_TEXT = SEPARATOR.join(MOTTOES) class Inscription(Pattern): id = "inscription" label = "Inscription" fps = 28 colors = { "ink": Color("#e0b44a"), "stone": Color("#2a1c10"), } params = { "text": Param( DEFAULT_TEXT, kind="text", max_length=160, label="Text", placeholder="AVE * SPQR", ), "text_brightness": Param(1.0, min=0.0, max=1.0, step=0.05, label="Text brightness"), "bg_brightness": Param(0.55, min=0.0, max=1.0, step=0.05, label="Background"), } def draw(self, surface, t, params): w, h = size(surface) extras = params["extras"] pulse = resolve_pulse(params, t, fallback_bpm=96, attack=0.18) bass = band(params, "bass") energy = band(params, "energy") ink = dim( params["colors"]["ink"], float(extras["text_brightness"]) * (0.85 + 0.15 * max(pulse, bass)), ) stone = params["colors"]["stone"] bg_b = float(extras["bg_brightness"]) banner = str(extras.get("text") or DEFAULT_TEXT).strip() or DEFAULT_TEXT x_offset, ring, _ = ring_metrics(params, w) for y in range(h): for x in range(w): gx = global_x(x, params, w) grain = 0.55 + 0.45 * math.sin(gx * 0.37 + y * 1.1) level = grain * (0.92 + 0.08 * energy) set_pixel(surface, x, y, dim(stone, level * bg_b)) span = text_width(banner) if span <= 0: return loop = max(span + max(ring // 8, 8), ring) scroll = resolve_scroll( params, t, fallback_bpm=96, pixels_per_beat=max(2.0, ring / 8.0), loop=loop, ) origin = -scroll - x_offset y0 = max(0, (h - CHAR_HEIGHT) // 2) draw_text(surface, banner, origin, y0, ink) draw_text(surface, banner, origin + loop, y0, ink) if __name__ == "__main__": run_cli(Inscription)