Skip to content

SVG + Color Batch

This stack runs image pixels through @stopcock/img, color math through @stopcock/color, then uses @stopcock/svg and @stopcock/svg/la to build the final vector overlay.

import { fromRGBA, simulateCVD } from '@stopcock/img'
import { rgb } from '@stopcock/color'
import {
circle,
fill,
group,
image,
linear,
pattern,
rect,
render,
stroke,
use,
viewBox,
} from '@stopcock/svg'
import { symmetry, toQuad } from '@stopcock/svg/la'
const source = fromRGBA(rgbaBytes, width, height)
const simulated = simulateCVD('deuteranopia', 1)(source)
const href = canvasDataUrl(simulated)
const tile = pattern(image(href, width, height), width, height)
const badgeFill = linear([
{ offset: 0, color: rgb(0.2, 0.8, 0.45) },
{ offset: 1, color: rgb(0.1, 0.4, 0.9) },
])
const badge = toQuad([
[300, 58],
[380, 42],
[396, 112],
[316, 132],
])(fill(badgeFill)(rect(1, 1)))
const dots = symmetry(fill(rgb(1, 1, 1))(circle(7)), 2, [1, 0, 0, 1, 18, -4])
const doc = viewBox(
0,
0,
420,
220,
)(group([fill(tile)(rect(260, 168)), badge, stroke(rgb(1, 1, 1), 5)(use(badge)), dots]))
render(doc)

The important seam is the buffer convention: simulateCVD strips RGBA bytes into a packed Float64Array RGB channel buffer, calls the color batch API once over the full image, then recombines alpha. SVG stays vector-native and only quotes the processed bitmap through an <image> inside a hoisted <pattern>.