KQ-1794 · GHOSTING/LCD
Ghosting LCD
A reflective monochrome LCD with visible pixel gaps that you draw on: the pointer lays a soft brush whose edges are dithered through a 4×4 Bayer matrix, and every pixel answers on the slow, smeary response of an old pocket screen — darkening on a quarter of `response` and clearing on all of it — so a quick stroke leaves a longer, fainter ghost than a slow one, and each lit pixel casts a faint shadow `depth` px onto the reflector. A press squeezes the crystal into a dark bloom whose radius rides springs.recoil out and back with two visible bounces as the glass flexes; Delete wipes the glass with a scan bar. It is a focusable screen: arrow keys draw with a blinking pen (Shift for a quicker stroke), Enter and Space press.
screen idle · draw on it, press to squeeze
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/ghosting-lcd
Props
- response
- number
- default 600
- How long a pixel takes to clear once released, ms (80 to 2000): the slower it is, the longer the ghosts.
- pixel
- number
- default 6
- Pixel pitch in px (3 to 12).
- tint
- "olive" | "grey" | "teal" | "sepia"
- default "olive"
- The panel's tint: the classic olive pocket screen, a calculator grey, a pager teal or a warm sepia.
- colors
- { panel?: string; ink?: string }
- default —
- Overrides of the tint, as CSS colours: the panel and the lit pixels.
- gap
- number
- default 0.16
- Share of the pitch left as a gap between pixels (0 to 0.4).
- depth
- number
- default 1.5
- How far, px, each lit pixel's shadow sits below and right of it on the reflector; 0 hides the shadows.
- brush
- number
- default 1.4
- Radius of the drawing brush, in pixels (0.6 to 4).
- dither
- boolean
- default true
- Ordered (Bayer) dither at the stroke's soft edges; off, the edge is a hard threshold.
- bloom
- number
- default 0.6
- How far a press spreads through the crystal, 0 to 1; 0 turns the press bloom off.
- text
- string
- default ""
- A line of pixel text the device shows in its top-left corner (A–Z, 0–9, - . : / ! ? ' +); whole words only.
- interactive
- boolean
- default true
- The pointer, touch and keys draw.
- paused
- boolean
- default false
- Freezes the screen's response.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- onClear
- () => void
- default —
- The screen was wiped (Delete or Backspace).
- label
- string
- default "Drawing screen"
- The screen's accessible name.
- disabled
- boolean
- default false
- Nothing draws; the screen keeps what it shows, leaves the tab order and says it is disabled.
- className
- string
- default "h-52 w-full"
- Sizes and shapes the screen.
| Prop | Type | Default | Description |
|---|---|---|---|
| response | number | 600 | How long a pixel takes to clear once released, ms (80 to 2000): the slower it is, the longer the ghosts. |
| pixel | number | 6 | Pixel pitch in px (3 to 12). |
| tint | "olive" | "grey" | "teal" | "sepia" | "olive" | The panel's tint: the classic olive pocket screen, a calculator grey, a pager teal or a warm sepia. |
| colors | { panel?: string; ink?: string } | — | Overrides of the tint, as CSS colours: the panel and the lit pixels. |
| gap | number | 0.16 | Share of the pitch left as a gap between pixels (0 to 0.4). |
| depth | number | 1.5 | How far, px, each lit pixel's shadow sits below and right of it on the reflector; 0 hides the shadows. |
| brush | number | 1.4 | Radius of the drawing brush, in pixels (0.6 to 4). |
| dither | boolean | true | Ordered (Bayer) dither at the stroke's soft edges; off, the edge is a hard threshold. |
| bloom | number | 0.6 | How far a press spreads through the crystal, 0 to 1; 0 turns the press bloom off. |
| text | string | "" | A line of pixel text the device shows in its top-left corner (A–Z, 0–9, - . : / ! ? ' +); whole words only. |
| interactive | boolean | true | The pointer, touch and keys draw. |
| paused | boolean | false | Freezes the screen's response. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| onClear | () => void | — | The screen was wiped (Delete or Backspace). |
| label | string | "Drawing screen" | The screen's accessible name. |
| disabled | boolean | false | Nothing draws; the screen keeps what it shows, leaves the tab order and says it is disabled. |
| className | string | "h-52 w-full" | Sizes and shapes the screen. |