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
74
|
/**
* Pattern definitions - 8x8 1-bit patterns
* 0 = foreground color, 1 = background color
*/
export const patterns = {
stitch: [
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
],
shingles: [
1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1,
0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1,
],
shadowGrid: [
1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0,
1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0,
],
wicker: [
0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0,
1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
],
};
/**
* Create a canvas pattern from a pattern definition
* @param {CanvasRenderingContext2D} ctx - Canvas context
* @param {Array<number>} patternData - 8x8 pattern array
* @param {number} pixelSize - Size of each pattern pixel
* @param {string} fgColor - Foreground color (for 0 values)
* @param {string} bgColor - Background color (for 1 values)
* @returns {Promise<CanvasPattern>} Canvas pattern
*/
export async function createPattern(
ctx,
patternData,
pixelSize,
fgColor,
bgColor,
) {
const size = 8;
let patternCanvas;
const isNode = typeof window === "undefined";
if (isNode) {
const { createCanvas } = await import("canvas");
patternCanvas = createCanvas(size * pixelSize, size * pixelSize);
} else {
patternCanvas = window.document.createElement("canvas");
patternCanvas.width = size * pixelSize;
patternCanvas.height = size * pixelSize;
}
const patternCtx = patternCanvas.getContext("2d");
for (let y = 0; y < size; y++) {
for (let x = 0; x < size; x++) {
const value = patternData[y * size + x];
patternCtx.fillStyle = value === 0 ? fgColor : bgColor;
patternCtx.fillRect(
x * pixelSize,
y * pixelSize,
pixelSize,
pixelSize,
);
}
}
return ctx.createPattern(patternCanvas, "repeat");
}
|