forked from genewildish/Mainline
feat: implement dynamic shifting gradients for messages and scrolling content, and adjust rendering parameters
This commit is contained in:
29
mainline.py
29
mainline.py
@@ -147,7 +147,7 @@ KATA = "ハミヒーウシナモニサワツオリアホテマケメエカキム
|
|||||||
_FONT_PATH = "/Users/genejohnson/Documents/CS Bishop Drawn/CSBishopDrawn-Italic.otf"
|
_FONT_PATH = "/Users/genejohnson/Documents/CS Bishop Drawn/CSBishopDrawn-Italic.otf"
|
||||||
_FONT_OBJ = None
|
_FONT_OBJ = None
|
||||||
_FONT_SZ = 60
|
_FONT_SZ = 60
|
||||||
_RENDER_H = 8 # terminal rows per rendered text line
|
_RENDER_H = 16 # terminal rows per rendered text line
|
||||||
|
|
||||||
# Non-Latin scripts → macOS system fonts
|
# Non-Latin scripts → macOS system fonts
|
||||||
_SCRIPT_FONTS = {
|
_SCRIPT_FONTS = {
|
||||||
@@ -502,9 +502,10 @@ def _save_cache(items):
|
|||||||
|
|
||||||
|
|
||||||
# ─── STREAM ───────────────────────────────────────────────
|
# ─── STREAM ───────────────────────────────────────────────
|
||||||
_SCROLL_DUR = 3.75 # seconds per headline
|
_SCROLL_DUR = 5.625 # seconds per headline (2/3 original speed)
|
||||||
_FRAME_DT = 0.05 # 50ms base frame rate (20 FPS)
|
_FRAME_DT = 0.05 # 50ms base frame rate (20 FPS)
|
||||||
FIREHOSE_H = 12 # firehose zone height (terminal rows)
|
FIREHOSE_H = 12 # firehose zone height (terminal rows)
|
||||||
|
GRAD_SPEED = 0.08 # gradient traversal speed (cycles/sec, ~12s full sweep)
|
||||||
_mic_db = -99.0 # current mic level, written by background thread
|
_mic_db = -99.0 # current mic level, written by background thread
|
||||||
_mic_stream = None
|
_mic_stream = None
|
||||||
|
|
||||||
@@ -636,8 +637,8 @@ def _big_wrap(text, max_w, font=None):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def _lr_gradient(rows):
|
def _lr_gradient(rows, offset=0.0):
|
||||||
"""Color each non-space block character with a left-to-right gradient."""
|
"""Color each non-space block character with a shifting left-to-right gradient."""
|
||||||
n = len(_GRAD_COLS)
|
n = len(_GRAD_COLS)
|
||||||
max_x = max((len(r.rstrip()) for r in rows if r.strip()), default=1)
|
max_x = max((len(r.rstrip()) for r in rows if r.strip()), default=1)
|
||||||
out = []
|
out = []
|
||||||
@@ -650,7 +651,8 @@ def _lr_gradient(rows):
|
|||||||
if ch == ' ':
|
if ch == ' ':
|
||||||
buf.append(' ')
|
buf.append(' ')
|
||||||
else:
|
else:
|
||||||
idx = min(round(x / max(max_x - 1, 1) * (n - 1)), n - 1)
|
shifted = (x / max(max_x - 1, 1) + offset) % 1.0
|
||||||
|
idx = min(round(shifted * (n - 1)), n - 1)
|
||||||
buf.append(f"{_GRAD_COLS[idx]}{ch}\033[0m")
|
buf.append(f"{_GRAD_COLS[idx]}{ch}\033[0m")
|
||||||
out.append("".join(buf))
|
out.append("".join(buf))
|
||||||
return out
|
return out
|
||||||
@@ -730,7 +732,6 @@ def _make_block(title, src, ts, w):
|
|||||||
("\u201d",'"'), ("\u2013","-"), ("\u2014","-")]:
|
("\u201d",'"'), ("\u2013","-"), ("\u2014","-")]:
|
||||||
title_up = title_up.replace(old, new)
|
title_up = title_up.replace(old, new)
|
||||||
big_rows = _big_wrap(title_up, w - 4, lang_font)
|
big_rows = _big_wrap(title_up, w - 4, lang_font)
|
||||||
big_rows = _lr_gradient(big_rows)
|
|
||||||
hc = random.choice([
|
hc = random.choice([
|
||||||
"\033[38;5;46m", # matrix green
|
"\033[38;5;46m", # matrix green
|
||||||
"\033[38;5;34m", # dark green
|
"\033[38;5;34m", # dark green
|
||||||
@@ -861,10 +862,10 @@ def stream(items):
|
|||||||
cache_key = (display_text, w)
|
cache_key = (display_text, w)
|
||||||
if _msg_cache[0] != cache_key:
|
if _msg_cache[0] != cache_key:
|
||||||
msg_rows = _big_wrap(display_text, w - 4)
|
msg_rows = _big_wrap(display_text, w - 4)
|
||||||
msg_rows = _lr_gradient(msg_rows)
|
|
||||||
_msg_cache = (cache_key, msg_rows)
|
_msg_cache = (cache_key, msg_rows)
|
||||||
else:
|
else:
|
||||||
msg_rows = _msg_cache[1]
|
msg_rows = _msg_cache[1]
|
||||||
|
msg_rows = _lr_gradient(msg_rows, (time.monotonic() * GRAD_SPEED) % 1.0)
|
||||||
# Center vertically in scroll zone
|
# Center vertically in scroll zone
|
||||||
total_h = len(msg_rows) + 4 # +4 for border + meta + padding
|
total_h = len(msg_rows) + 4 # +4 for border + meta + padding
|
||||||
y_off = max(0, (sh - total_h) // 2)
|
y_off = max(0, (sh - total_h) // 2)
|
||||||
@@ -933,6 +934,7 @@ def stream(items):
|
|||||||
# Draw scroll zone
|
# Draw scroll zone
|
||||||
top_zone = max(1, int(sh * 0.25))
|
top_zone = max(1, int(sh * 0.25))
|
||||||
bot_zone = max(1, int(sh * 0.10))
|
bot_zone = max(1, int(sh * 0.10))
|
||||||
|
grad_offset = (time.monotonic() * GRAD_SPEED) % 1.0
|
||||||
buf = []
|
buf = []
|
||||||
for r in range(sh):
|
for r in range(sh):
|
||||||
cy = cam + r
|
cy = cam + r
|
||||||
@@ -943,13 +945,18 @@ def stream(items):
|
|||||||
for content, hc, by, midx in active:
|
for content, hc, by, midx in active:
|
||||||
cr = cy - by
|
cr = cy - by
|
||||||
if 0 <= cr < len(content):
|
if 0 <= cr < len(content):
|
||||||
ln = _vis_trunc(content[cr], w)
|
raw = content[cr]
|
||||||
|
if cr != midx:
|
||||||
|
colored = _lr_gradient([raw], grad_offset)[0]
|
||||||
|
else:
|
||||||
|
colored = raw
|
||||||
|
ln = _vis_trunc(colored, w)
|
||||||
if row_fade < 1.0:
|
if row_fade < 1.0:
|
||||||
ln = _fade_line(ln, row_fade)
|
ln = _fade_line(ln, row_fade)
|
||||||
if cr == midx:
|
if cr == midx:
|
||||||
buf.append(f"\033[{r+1};1H{W_COOL}{ln}{RST}\033[K")
|
buf.append(f"\033[{r+1};1H{W_COOL}{ln}{RST}\033[K")
|
||||||
elif ln.strip():
|
elif ln.strip():
|
||||||
buf.append(f"\033[{r+1};1H{hc}{ln}{RST}\033[K")
|
buf.append(f"\033[{r+1};1H{ln}{RST}\033[K")
|
||||||
else:
|
else:
|
||||||
buf.append(f"\033[{r+1};1H\033[K")
|
buf.append(f"\033[{r+1};1H\033[K")
|
||||||
drawn = True
|
drawn = True
|
||||||
|
|||||||
Reference in New Issue
Block a user