Skip to content

Halftone Depth Field

A rotated print screen that swells into a pool of light under the pointer, with the gamma actually done right.

Canvas 2D0 deps1 file · 6 KB TSXreduced-motion aware

ProDither & ASCIIbrutalisteditorialminimal
Preview

Props

14
45
0.06
210
Decode gamma
Map by area

The source is part of Pro

$27/month or $179 once. See Pro

No runtime dependencies
"use client";

import { useEffect, useRef } from "react";

/**
 * A halftone screen that reacts to the pointer.
 *
 * Two pieces of colour science decide whether the tonal ramp looks even or
 * looks like a bad photocopy, and both are one line each:
 *
 *  · the eye integrates the AREA of a dot, not its radius, so radius has to go
 *    as the square root of the intended coverage;
 *  · coverage is a LINEAR-LIGHT quantity while the tone you are aiming at is
 *    sRGB-encoded, so it must be decoded before the square root is taken.
 */

/** sRGB transfer function, inverse. A 50% sRGB grey is ~21% linear light. */
function srgbToLinear(c: number): number {

  // ---------------------------------------------------------------
  // Full source available with a viberdy Pro subscription.
  // https://viberdy.dev/pricing
  // ---------------------------------------------------------------
}
Details

About this background

A halftone is a tonal ramp made of dots, and two pieces of colour science decide whether that ramp reads as even or as a bad photocopy. The first is that the eye integrates the AREA a dot covers, not its radius — and area goes as radius squared, so a dot sized in direct proportion to the tone you want delivers that tone squared, and every midtone collapses toward the dark end. The correction is a square root. The second is that coverage is a linear-light quantity while the tone being aimed at is sRGB-encoded, and a 50% sRGB grey is only about 21% of the light; without running the target through the inverse transfer function first, the midtones come out far too bright. Both are exposed as switches here, because the failure modes are much easier to believe when you can toggle them. Two details come straight from print. Full coverage needs a radius of pitch over root two rather than half the pitch — at exactly half, neighbouring circles only touch and leave about a fifth of the area as diamond-shaped gaps, so the darkest tone never goes solid. And the screen is rotated, because an axis-aligned dot grid bands hard against any horizontal or vertical edge in the content and moirés against the pixel grid itself; the lattice is generated rotated rather than the canvas being rotated, so the dots stay circular and culling stays trivial.

Curator’s note

Switch off 'map by area' and watch every midtone collapse. It is a square root, and it is the whole difference.

Pairs well with

Trending
Pro

Marbled Endpaper

backgrounds
Pro
Pro