# Market ticker strip

Seamless scrolling ticker of symbols with logo, price and change — stocks, crypto or anything with a number. 1920×160 strip, 10 s loop.

- Category: ticker · Tags: ticker, stocks, crypto, finance, loop
- Spec: 1920×160 @ 30 fps · 10s (12:1)
- License: CC0 · Tier: free
- JSON: https://gimgs.net/motion/market-ticker.json
- Kind: html
- Template HTML: https://gimgs.net/motion/market-ticker/template.html
- Player: https://gimgs.net/motion/market-ticker/play?p=<base64url JSON params>[&t=<seconds>]
- Credits: gimgs — https://gimgs.net/motion
- Page: https://gimgs.net/motion/market-ticker.html

## Params

| name | type | default | description |
|---|---|---|---|
| `items` | array | `[{"symbol":"BTC","name":"Bitcoin","price":"$112,430","change":"+2.4%","logo":"https://gimgs.net/crypto/btc.svg"},{"symbol":"ETH","name":"Ethereum","price":"$4,120","change":"-0.8%","logo":"https://gimgs.net/crypto/eth.svg"},{"symbol":"AAPL","name":"Apple","price":"$248.10","change":"+1.1%","logo":"https://gimgs.net/stock/apple.svg"},{"symbol":"NVDA","name":"NVIDIA","price":"$181.20","change":"+3.6%","logo":"https://gimgs.net/stock/nvidia.svg"},{"symbol":"TSLA","name":"Tesla","price":"$412.00","change":"-1.9%","logo":"https://gimgs.net/stock/tesla.svg"}]` | Ticker items in order. Each: {symbol, name, price, change, logo}. change starting with '-' is red. logo: https://gimgs.net/stock/{tradingview-slug}.svg, /crypto/{ticker}.svg or /brand-logo/{slug}.svg |
| `bg` | string (color) | `"#0b0c10"` | Strip background |
| `up` | string (color) | `"#22c55e"` | Positive change colour |
| `down` | string (color) | `"#ef4444"` | Negative change colour |

Default params (base64url for `?p=`): `eyJpdGVtcyI6W3sic3ltYm9sIjoiQlRDIiwibmFtZSI6IkJpdGNvaW4iLCJwcmljZSI6IiQxMTIsNDMwIiwiY2hhbmdlIjoiKzIuNCUiLCJsb2dvIjoiaHR0cHM6Ly9naW1ncy5uZXQvY3J5cHRvL2J0Yy5zdmcifSx7InN5bWJvbCI6IkVUSCIsIm5hbWUiOiJFdGhlcmV1bSIsInByaWNlIjoiJDQsMTIwIiwiY2hhbmdlIjoiLTAuOCUiLCJsb2dvIjoiaHR0cHM6Ly9naW1ncy5uZXQvY3J5cHRvL2V0aC5zdmcifSx7InN5bWJvbCI6IkFBUEwiLCJuYW1lIjoiQXBwbGUiLCJwcmljZSI6IiQyNDguMTAiLCJjaGFuZ2UiOiIrMS4xJSIsImxvZ28iOiJodHRwczovL2dpbWdzLm5ldC9zdG9jay9hcHBsZS5zdmcifSx7InN5bWJvbCI6Ik5WREEiLCJuYW1lIjoiTlZJRElBIiwicHJpY2UiOiIkMTgxLjIwIiwiY2hhbmdlIjoiKzMuNiUiLCJsb2dvIjoiaHR0cHM6Ly9naW1ncy5uZXQvc3RvY2svbnZpZGlhLnN2ZyJ9LHsic3ltYm9sIjoiVFNMQSIsIm5hbWUiOiJUZXNsYSIsInByaWNlIjoiJDQxMi4wMCIsImNoYW5nZSI6Ii0xLjklIiwibG9nbyI6Imh0dHBzOi8vZ2ltZ3MubmV0L3N0b2NrL3Rlc2xhLnN2ZyJ9XSwiYmciOiIjMGIwYzEwIiwidXAiOiIjMjJjNTVlIiwiZG93biI6IiNlZjQ0NDQifQ`

## Prompt

## When to use
A finance/news strip at the bottom of a video, a looping background for a market update, a dashboard header. The output is a 1920×160 strip: overlay it on 1080p footage with ffmpeg `overlay=0:920`.

## How to adapt
- Fill `items` with real data — prices and changes are plain strings so format them however the audience expects (`€1.234,56`, `+0.8 %`, `▲ 2.4%`). Anything whose `change` starts with `-` is coloured `down`.
- Logos: stock → `https://gimgs.net/stock/{tradingview slug}.svg` (apple, microsoft, nvidia…; use `/api/stock-search?q=` to find the slug), crypto → `/crypto/{ticker}.svg`, brands → `/brand-logo/{slug}.svg`. Omit `logo` to hide the circle.
- 5–8 items fill the width nicely; the list is duplicated internally so the loop is seamless at any count.
- Speed: the rail travels half its width in `duration` (10 s). More items = faster. Change `window.motion.duration` in the source for a slower loop.

## Do not change
`window.motion`, `#stage` size, the rail's `translateX(-50%)` loop (that is what makes frame 0 and the last frame line up).

## Flow

1. **Collect quotes** — tool: any market data API
   Format numbers as strings.
2. **Resolve logos** — tool: gimgs /api/stock-search?q=apple → logoid
   → https://gimgs.net/stock/{logoid}.svg
3. **Render loop**
   `frames 0…299 at t=i/30 → ffmpeg -framerate 30 -i frame-%04d.png -c:v libx264 -pix_fmt yuv420p ticker.mp4`
4. **Overlay**
   `ffmpeg -i video.mp4 -stream_loop -1 -i ticker.mp4 -filter_complex "[1]format=yuva420p[t];[0][t]overlay=0:920:shortest=1" out.mp4`

## Render

Open frame_url in a headless browser with viewport width×height (deviceScaleFactor 1), wait for document.documentElement.dataset.motionReady === '1', screenshot; repeat for t = i/fps (i = 0…frames-1); then `ffmpeg -framerate <fps> -i frame-%04d.png -c:v libx264 -pix_fmt yuv420p out.mp4`. Or drop ?t to play it live.

## Contract

Self-contained HTML. Declares window.motion = { width, height, fps, duration, params, apply(params) [, seek(t)] }; root element #stage sized width×height; animations are CSS/WAAPI with animation-fill-mode: both so any t can be seeked via document.getAnimations(). The host runtime (injected by /play) merges ?p params, calls apply(), scales #stage to the viewport and, when ?t is given, pauses and seeks deterministically.
