IrisBackgroundsTrace
Trace
Eight staggered rows of hot magenta circuit trace, each jogging on a true diagonal between two levels, over a near-black warm-maroon ground — a direct build of the reference photo.
Trace
Eight rows of Manhattan-routed trace run left to right across a near-black, warm-maroon ground that blooms faintly toward a soft bloom left of centre. Each row runs flat, jogs on a true 45° diagonal to a second level, holds there, then jogs back and keeps running past the frame edge — never a printed grid, since every row starts, jogs and ends at its own staggered point. A small bright dot marks every joint, a third of the rows carry a soft elongated lens-glow over their shifted stretch, and two rows carry a short run of directional chevron ticks, the way the reference photo marks flow along a couple of its own traces. A scatter of faint, twinkling specks sits in the dark beyond the traces.
A slow signal pulse rides every row on its own phase, born at that row's own left end and fading out at its own right end. The pointer works like a hand held near a live board: whichever traces pass close to the cursor light brighter, right where it's actually pointed, rather than the whole frame flashing at once.
Install
No installation needed — self-contained, paste-in code.
Usage
Drop it straight into a page.
import { TraceField } from "./TraceField";
export default function Example() {
return (
// Fills its nearest positioned ancestor (it renders itself `absolute
// inset-0`) — give it a sized, relatively positioned box.
<div className="relative isolate h-[32rem] w-full overflow-hidden rounded-2xl">
<TraceField />
</div>
);
}Component
The real source, exactly as it ships — multiple files, kept together.
"use client";
import { useEffect, useRef } from "react";
import { mountShaderSurface } from "@/lib/shader-surface";
/**
* A live WebGL circuit-board schematic — eight horizontal trace rows, each a
* staggered polyline that runs flat, jogs on a true 45° diagonal to a second
* level, holds there, then jogs back and keeps running, exactly the
* Manhattan-routed look of a PCB trace diagram. Every jog carries a small
* bright junction dot, a third of the rows carry an elongated lens-glow
* "pill" over their shifted stretch, and two rows carry a short run of
* directional chevron ticks — the reference photo this was built from reads
* as hot magenta-pink neon on a near-black, warm-maroon ground, so the
* palette stays fixed rather than drawn from the site's own accent ramp,
* the same call `CoronaField` and `SlipstreamField` make for their own
* fixed neon palettes.
*
* Row breakpoints are procedural, not a literal traced coordinate list: each
* of the eight rows hashes its own start position, run lengths and jog
* direction from its index, so the geometry reads as the same kind of
* staggered, never-quite-aligned trace diagram as the source without
* hand-carrying forty-odd magic numbers that would only ever fit one
* viewport's aspect ratio. A slow signal pulse rides every row on its own
* phase, born at its own left end and fading out at its own right end.
*
* The pointer lights whichever traces pass near it — a localised heat term
* multiplies every wire's core, halo and node brightness, so the effect
* stays where the cursor actually is rather than a global flash.
*
* Drop it into any `position: relative`/`isolate` parent — it fills the box.
* Built on `lib/shader-surface.ts`, so every degradation path is already
* handled: no WebGL, a blocked or lost context, a hidden tab, or
* `prefers-reduced-motion` all leave the CSS `.iris-tracefield__floor`
* underneath visible — a still composition in the same palette, never a
* blank box.
*
* Reading guard: when `guardSelector` resolves to an element, the field
* measures that block every frame and clamps its own luminance under a
* ceiling inside that region (hue and saturation untouched). `null` (the
* default) turns the guard off — for decorative use where nothing sits on
* top.
*/
/* Palette, sRGB 0–1. Uniforms, not tokens — the hot magenta-pink-on-maroon
read lives nowhere in the site's own accent ramp. */
const PALETTE: Record<string, [number, number, number]> = {
u_ground: [0.02, 0.004, 0.004], // near-black, warm maroon
u_groundWarm: [0.15, 0.013, 0.011], // the soft centre-left bloom
u_wireGlow: [0.85, 0.08, 0.34], // the broad magenta-red halo
u_wireCore: [1.0, 0.5, 0.68], // the hot pink-white core
u_node: [1.0, 0.72, 0.83], // bright junction dots
u_pill: [1.0, 0.6, 0.75], // the lens-glow pill on a third of the rows
u_star: [0.95, 0.55, 0.62], // faint background specks
};
const FRAG = `
uniform vec2 u_res;
uniform float u_time;
uniform float u_scale;
uniform vec3 u_pointer; /* x, y (0 bottom .. 1 top), presence 0..1 */
uniform vec3 u_ground;
uniform vec3 u_groundWarm;
uniform vec3 u_wireGlow;
uniform vec3 u_wireCore;
uniform vec3 u_node;
uniform vec3 u_pill;
uniform vec3 u_star;
uniform vec4 u_readA;
uniform float u_guard;
float hash1(float n) { return fract(sin(n * 78.233) * 43758.5453123); }
/* Distance to a segment, in the aspect-corrected q-space every field here
uses — equal deltas in x and y are equal physical pixels, which is what
makes a jog with matched dx/dy read as a true 45°. */
float segDist(vec2 p, vec2 a, vec2 b) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / max(dot(ba, ba), 1e-6), 0.0, 1.0);
return length(pa - ba * h);
}
void main() {
vec2 res = u_res / u_scale;
vec2 uv = gl_FragCoord.xy / u_scale / res; /* 0..1, y up */
vec2 sc = vec2(res.x / max(res.y, 1.0), 1.0);
vec2 q = uv * sc;
/* the ground: near-black maroon, warming toward a soft bloom left of
centre, darkening again toward every corner */
vec2 warmCentre = vec2(sc.x * 0.42, 0.56);
vec2 wd = (q - warmCentre) / vec2(sc.x * 0.5, 0.5);
float warm = exp(-dot(wd, wd) * 2.2);
vec3 col = mix(u_ground, u_groundWarm, warm * 0.55);
float corner = length((uv - 0.5) * 1.5);
col *= mix(1.0, 0.4, smoothstep(0.4, 1.1, corner));
/* a faint, twinkling starfield — a jittered point per lattice cell, only
a small fraction of cells ever lit */
float starFreq = 30.0;
vec4 sd = dotCell(q * starFreq);
float sh = dotHash(sd.zw);
vec2 jitter = (vec2(dotHash(sd.zw + 4.0), dotHash(sd.zw + 9.0)) - 0.5) * 0.7;
vec2 starOff = (sd.xy - jitter) / starFreq;
float starMask = step(0.965, sh);
float twinkle = 0.5 + 0.5 * sin(u_time * 1.6 + sh * 40.0);
col += u_star * exp(-dot(starOff, starOff) * 80000.0) * starMask * twinkle * 0.7;
/* the pointer's local heat: brightens whichever wire passes near it,
rather than the whole frame */
vec2 ptr = u_pointer.xy * sc;
vec2 pd = q - ptr;
float hot = exp(-dot(pd, pd) / 0.02) * u_pointer.z;
float boost = 1.0 + hot * 1.6;
for (int i = 0; i < 8; i++) {
float fi = float(i);
float rowY = 0.80 - fi * 0.082;
float h1 = hash1(fi * 3.7 + 1.0);
float h2 = hash1(fi * 3.7 + 2.0);
float h3 = hash1(fi * 3.7 + 3.0);
float h4 = hash1(fi * 3.7 + 4.0);
float dir = mod(fi, 2.0) < 0.5 ? 1.0 : -1.0;
float jog = 0.034 * dir;
float absJog = abs(jog);
/* the polyline: flat, jog on a true diagonal, flat at the shifted
level, jog back, flat again to (and past) the right edge */
float xA = mix(-0.08, 0.08, h1) * sc.x;
float xB = xA + mix(0.10, 0.20, h2) * sc.x;
vec2 p0 = vec2(xA, rowY);
vec2 p1 = vec2(xB, rowY);
vec2 p2 = vec2(xB + absJog, rowY + jog);
float midLen = mix(0.16, 0.30, h3) * sc.x;
vec2 p3 = vec2(p2.x + midLen, p2.y);
vec2 p4 = vec2(p3.x + absJog, rowY);
float tailLen = mix(0.20, 0.42, h4) * sc.x;
vec2 p5 = vec2(p4.x + tailLen, rowY);
float d = segDist(q, p0, p1);
d = min(d, segDist(q, p1, p2));
d = min(d, segDist(q, p2, p3));
d = min(d, segDist(q, p3, p4));
d = min(d, segDist(q, p4, p5));
float coreSigma = 0.0026;
float haloSigma = 0.016;
float core = exp(-d * d / (coreSigma * coreSigma));
float halo = exp(-d * d / (haloSigma * haloSigma));
col += u_wireGlow * halo * 0.55 * boost;
col += u_wireCore * core * boost;
/* a small bright dot at every joint */
float nodeGlow = 0.0;
nodeGlow += exp(-dot(q - p1, q - p1) / 0.00028);
nodeGlow += exp(-dot(q - p2, q - p2) / 0.00028);
nodeGlow += exp(-dot(q - p3, q - p3) / 0.00028);
nodeGlow += exp(-dot(q - p4, q - p4) / 0.00028);
col += u_node * nodeGlow * boost;
/* a slow signal pulse, born at this row's own left end, fading out at
its own right end, on its own phase */
float cycle = fract(u_time * 0.05 + h1 * 4.0);
float travelX = mix(p0.x, p5.x, cycle);
float pulseFade = smoothstep(0.0, 0.06, cycle) * (1.0 - smoothstep(0.9, 1.0, cycle));
float pulse = exp(-(q.x - travelX) * (q.x - travelX) / 0.0009) * halo;
col += u_wireCore * pulse * 0.6 * pulseFade;
/* a soft lens-glow pill over the shifted stretch, on a third of the
rows */
if (mod(fi, 3.0) < 0.5) {
vec2 pillC = mix(p2, p3, 0.5);
vec2 dp = q - pillC;
dp.x /= 0.05;
dp.y /= 0.014;
col += u_pill * exp(-dot(dp, dp) * 1.4) * 0.9;
}
/* a short run of directional chevron ticks on two of the rows */
if (i == 1 || i == 4) {
float xs = p0.x + 0.02 * sc.x;
float xe = p1.x - 0.01 * sc.x;
if (q.x > xs && q.x < xe) {
float cell = 0.03 * sc.x;
float lx = mod(q.x - xs, cell) - cell * 0.5;
vec2 cpt = vec2(lx, q.y - rowY);
float cd = min(
segDist(cpt, vec2(-cell * 0.28, cell * 0.28), vec2(cell * 0.14, 0.0)),
segDist(cpt, vec2(cell * 0.14, 0.0), vec2(-cell * 0.28, -cell * 0.28))
);
col += u_wireCore * exp(-cd * cd / (0.0016 * 0.0016)) * 0.8;
}
}
}
col = max(col, 0.0);
/* ---- the reading guard (see TileField for the full rationale) ---- */
vec2 rd = abs(uv - u_readA.xy) / max(u_readA.zw, vec2(0.02));
float m = mix(max(rd.x, rd.y), length(rd), 0.4);
float band = 1.0 - smoothstep(0.72, 2.1, m);
col = mix(col, holdUnder(col, 0.09), band * u_guard);
gl_FragColor = vec4(col, 1.0);
}
`;
export interface TraceFieldProps {
className?: string;
/**
* CSS selector for the block the reading guard should keep readable,
* resolved against `document`. `null` (the default) turns the guard off.
*/
guardSelector?: string | null;
}
export function TraceField({
className,
guardSelector = null,
}: TraceFieldProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const guardOn = guardSelector != null;
let guardEl: Element | null | undefined;
const readGuardEl = () => {
if (guardEl === undefined) {
guardEl = guardOn ? document.querySelector(guardSelector as string) : null;
}
return guardEl;
};
return mountShaderSurface(canvas, {
fragment: FRAG,
uniforms: [...Object.keys(PALETTE), "u_readA", "u_guard"],
onInit: (gl, u) => {
for (const name of Object.keys(PALETTE)) {
if (u[name]) gl.uniform3fv(u[name], PALETTE[name]);
}
if (u.u_readA) gl.uniform4f(u.u_readA, 0.5, 0.5, 0.44, 0.32);
if (u.u_guard) gl.uniform1f(u.u_guard, guardOn ? 1 : 0);
},
onFrame: (gl, u, s) => {
if (!guardOn || !u.u_readA) return;
let cx = 0.5, cy = 0.5, hw = 0.44, hh = 0.32;
const el = readGuardEl();
const { rect } = s;
if (el && rect.width > 0 && rect.height > 0) {
const r = el.getBoundingClientRect();
const padX = rect.width * 0.09;
const padY = rect.height * 0.11;
cx = (r.left + r.width / 2 - rect.left) / rect.width;
cy = 1 - (r.top + r.height / 2 - rect.top) / rect.height;
hw = (r.width / 2 + padX) / rect.width;
hh = (r.height / 2 + padY) / rect.height;
}
gl.uniform4f(u.u_readA, cx, cy, hw, hh);
},
onPainted: () => canvas.setAttribute("data-shader", "on"),
/* No onIdle — same contract as CoronaField/SpillwayField: once
painted, the last frame stays on screen while the surface is parked
off-view, so scrolling away and back does not crossfade to the
static floor. A lost context still clears it below. */
onLost: () => canvas.removeAttribute("data-shader"),
maxPixels: 1_800_000,
dprCap: 1.5,
alpha: false,
});
}, [guardSelector]);
return (
<div
className={`absolute inset-0 overflow-hidden${className ? ` ${className}` : ""}`}
aria-hidden="true"
>
<div className="absolute inset-0 [background:radial-gradient(_60%_55%_at_42%_56%,oklch(0.24_0.08_20)_0%,oklch(0.12_0.05_20_/_0.7)_35%,transparent_65%_),oklch(0.05_0.02_20)] after:content-[''] after:absolute after:inset-0 after:[background:repeating-linear-gradient(_45deg,transparent_0_26px,oklch(0.62_0.24_350_/_0.22)_26px_27px,transparent_27px_52px_)] after:[-webkit-mask-image:radial-gradient(_65%_60%_at_42%_56%,#000_30%,transparent_82%_)] after:[mask-image:radial-gradient(_65%_60%_at_42%_56%,#000_30%,transparent_82%_)] after:[opacity:0.5]" />
<canvas ref={canvasRef} className="absolute inset-0 w-full h-full opacity-0 transition-opacity duration-[--duration-slow] ease-[--ease-standard] data-[shader=on]:opacity-100" />
</div>
);
}Custom work
Need one that isn't in the catalogue?
Describe what you're after and I'll reply by email — no promise on turnaround yet, this is a new channel, not a service with a set price or queue.
Fardin Omor Afnan
Reads and answers every request himself