feat: Implement scrolling camera with layout-aware filtering

- Rename VERTICAL camera mode to FEED (rapid single-item view)
- Add SCROLL camera mode with float accumulation for smooth movie-credits style scrolling
- Add estimate_block_height() for cheap layout calculation without full rendering
- Replace ViewportFilterStage with layout-aware filtering that tracks camera position
- Add render caching to FontStage to avoid re-rendering items
- Fix CameraStage to use global canvas height for scrolling bounds
- Add horizontal padding in Camera.apply() to prevent ghosting
- Add get_dimensions() to MultiDisplay for proper viewport sizing
- Fix PygameDisplay to auto-detect viewport from window size
- Update presets to use scroll camera with appropriate speeds
This commit is contained in:
2026-03-17 00:21:18 -07:00
parent 4c97cfe6aa
commit 57de835ae0
12 changed files with 303 additions and 66 deletions

View File

@@ -12,7 +12,7 @@
description = "Demo mode with effect cycling and camera modes"
source = "headlines"
display = "pygame"
camera = "vertical"
camera = "scroll"
effects = ["noise", "fade", "glitch", "firehose"]
viewport_width = 80
viewport_height = 24
@@ -23,7 +23,7 @@ firehose_enabled = true
description = "Poetry feed with subtle effects"
source = "poetry"
display = "pygame"
camera = "vertical"
camera = "scroll"
effects = ["fade"]
viewport_width = 80
viewport_height = 24
@@ -33,7 +33,7 @@ camera_speed = 0.5
description = "Test border rendering with empty buffer"
source = "empty"
display = "terminal"
camera = "vertical"
camera = "scroll"
effects = ["border"]
viewport_width = 80
viewport_height = 24
@@ -45,7 +45,7 @@ border = false
description = "WebSocket display mode"
source = "headlines"
display = "websocket"
camera = "vertical"
camera = "scroll"
effects = ["noise", "fade", "glitch"]
viewport_width = 80
viewport_height = 24
@@ -56,7 +56,7 @@ firehose_enabled = false
description = "Sixel graphics display mode"
source = "headlines"
display = "sixel"
camera = "vertical"
camera = "scroll"
effects = ["noise", "fade", "glitch"]
viewport_width = 80
viewport_height = 24
@@ -67,7 +67,7 @@ firehose_enabled = false
description = "High-speed firehose mode"
source = "headlines"
display = "pygame"
camera = "vertical"
camera = "scroll"
effects = ["noise", "fade", "glitch", "firehose"]
viewport_width = 80
viewport_height = 24
@@ -78,7 +78,7 @@ firehose_enabled = true
description = "Live pipeline introspection with DAG and performance metrics"
source = "pipeline-inspect"
display = "pygame"
camera = "vertical"
camera = "scroll"
effects = ["crop"]
viewport_width = 100
viewport_height = 35