Spaces:
Running
Running
File size: 1,862 Bytes
414dc55 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | // 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)
}
}
}
|