@wrkspace/shell
theme

Dithering

the ordered bayer engine under every texture

shell paints its progress bars, spinners, avatars and surfaces with an ordered dithering engine instead of css gradients. it is a small, framework-free set of functions that turn a continuous value into a pixel texture.

each pixel is compared to a threshold from a fixed matrix at its (x, y) position. a value above the threshold is on, below is off.

this produces a regular, repeatable texture with no per-pixel state, so it is cheap and deterministic. the bayer 4×4 matrix, below, is the coarsest option.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

two matrix sizes trade chunkiness for banding. bayer 4×4 shows the visible retro tile; bayer 8×8 is fine enough to read as smooth.

bayer 4x4 - coarse
bayer 8x8 - fine

the engine paints a single colour at varying alpha instead of different shades. an on-cell uses a higher alpha tier, an off-cell the same colour at a lower tier.

that keeps the texture readable on both light and dark themes without duplicating palettes.

a mini-lab for paintDitherCell. tweak density, matrix, off tier, floor, opacity and colour - every cell uses the same params.

density
0.62
matrixbayer8
off tier
0.40
floor
0.30
opacity
1.00
coloraccent

while ordered bayer dithering uses fixed threshold matrices, error diffusion calculates quantization error per cell and distributes it to forward neighbors.

floyd-steinberg conserves 100% of error across 4 neighbors for smooth, fine-grained photographic stippling. atkinson (bill atkinson, classic mac 1984) diffuses 75% of error across 6 neighbors and absorbs 25%, keeping clean punchy highlights and shadows without worms.

bayer 4×4 - coarse ordered tile
bayer 8×8 - fine ordered tile
blue noise 16×16 - organic void-and-cluster (O(1) stateless)
floyd-steinberg - error diffusion (smooth 16/16)
atkinson - classic mac 1984 (punchy 6/8)

classic mac and hypercard style 1-bit pixel reveals. instead of fading alpha, transitions dissolve, wipe, or open shutters using dithered threshold geometry.

play the animation or scrub progress manually to inspect the frame-by-frame pixel pattern.

progress: 50%
progress
0.50
effectdissolve
matrixblue-noise
coloraccent

a tiny surface:

ditherLit(value, x, y, matrix?)ditherLevel(value, x, y, levels, matrix?)ditherDiffusion(cols, rows, density, opts?)ditherTransitionMask(cols, rows, progress, type?, opts?)paintDitherGradient(canvas, cols, rows, from, to?, opts?)paintDitherTransition(canvas, progress, type, fill, opts?)paintDitherBar(canvas, pct, cols, rows, fill, opts?)resolveColor(el, color?)

progress bars, spinners, avatars, the logo, and dither surfaces all run through the same engine. browse the dither category to see them.