Files
Android-247-Radio/docs/plans/2026-03-11-ticker-text-design.md
cottongin 202a631897 Add ticker text design doc
Captures the design for replacing BounceMarqueeText with a
constant-speed TickerText composable (33 dp/s, continuous leftward
scroll with gap looping).

Made-with: Cursor
2026-03-11 18:22:23 -04:00

39 lines
1.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ticker Text Design
## Problem
The `BounceMarqueeText` composable in `NowPlayingScreen.kt` scrolls long text at a speed proportional to overflow, clamped to 20008000ms. For very long titles, the 8000ms cap means the text covers more distance in the same time — making it visibly faster and harder to read. The bounce-back pattern (scroll left, pause, scroll right) also feels unnatural compared to a continuous ticker.
## Decision
Replace `BounceMarqueeText` with a `TickerText` composable that scrolls at a constant 33 dp/s leftward, regardless of text length.
## Design
### `TickerText` composable
**Parameters:**
- `text`, `style`, `color`, `strokeColor`, `strokeWidth`, `modifier` — same as current `BounceMarqueeText`
- `velocityDpPerSecond: Float = 33f` — constant scroll speed
**Behavior:**
- Text fits in container: rendered centered and static (no animation).
- Text overflows: scrolls continuously leftward at 33 dp/s.
- After the text exits the left edge, a gap equal to the container width passes (screen appears empty), then the text reappears from the start position and repeats.
**Animation math:**
- `totalScrollPx = textWidthPx + containerWidthPx`
- `durationMs = (totalScrollPx / (velocityDpPerSecond * density)) * 1000`
- No upper clamp — longer text simply takes longer at the same speed.
- Keyframes: `0f``-(textWidthPx)` with `LinearEasing`, then restart.
- Initial delay of ~1.5s before first scroll so user can read the beginning.
**Stroke overlay:** Both the stroke `Text` and fill `Text` remain in the same translated `Box`, moving together.
**Callers:** `TrackInfoSection` swaps `BounceMarqueeText``TickerText` with no other changes.
## Rejected alternatives
- **`Modifier.basicMarquee()`** — less control over gap/looping, uncertain Compose BOM version support, harder to keep the stroke overlay working.
- **Custom `Canvas` + `drawText`** — maximum control but overkill; significantly more code for the same result.