case0 / web /src /engine /draw.ts
HusseinEid's picture
Case Zero - initial public release (fully local: Qwen2.5-1.5B via llama.cpp + Supertonic, custom pixel-noir SPA via gradio.Server)
414dc55
raw
history blame
1.86 kB
// Low-level pixel drawing helpers, shared by the canvas components and the procedural
// art. Ported verbatim from the prototype's pixel.jsx so rendering stays pixel-accurate.
export type Pal = Record<string, string> | null | undefined
/** Draw a string-grid map: rows of chars, each char a key in `pal`. */
export function drawMap(
ctx: CanvasRenderingContext2D,
map: string[],
pal: Pal,
px: number,
): void {
for (let y = 0; y < map.length; y++) {
const row = map[y]
for (let x = 0; x < row.length; x++) {
const c = row[x]
if (c === '.' || c === ' ' || c == null) continue
const col = pal ? pal[c] || c : c
if (!col || col === '.') continue
ctx.fillStyle = col
ctx.fillRect(x * px, y * px, px, px)
}
}
}
/** Ordered 4x4 Bayer matrix for dithering. */
export const BAYER4 = [
[0, 8, 2, 10],
[12, 4, 14, 6],
[3, 11, 1, 9],
[15, 7, 13, 5],
]
/** Dither between two colors over a region; `t` in 0..1 is the `near` coverage. */
export function dither(
ctx: CanvasRenderingContext2D,
x0: number,
y0: number,
w: number,
h: number,
near: string,
far: string,
t: number,
): void {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const thr = (BAYER4[y & 3][x & 3] + 0.5) / 16
ctx.fillStyle = thr < t ? near : far
ctx.fillRect(x0 + x, y0 + y, 1, 1)
}
}
}
/** Vertical dither gradient from colTop to colBottom across height h. */
export function ditherGrad(
ctx: CanvasRenderingContext2D,
x0: number,
y0: number,
w: number,
h: number,
colTop: string,
colBottom: string,
): void {
for (let y = 0; y < h; y++) {
const t = 1 - y / h
for (let x = 0; x < w; x++) {
const thr = (BAYER4[y & 3][x & 3] + 0.5) / 16
ctx.fillStyle = thr < t ? colTop : colBottom
ctx.fillRect(x0 + x, y0 + y, 1, 1)
}
}
}