grid.js
2.2 kB · javascript · 75 lines
1// GRID23const round = (v) => (v < 0 ? -Math.round(-v) : Math.round(v));45export class Grid {6 constructor(frame, cols, rows, gap) {7 this.frame = frame;8 this.cols = Math.max(cols, 1);9 this.rows = Math.max(rows, 1);10 this.gap = gap;11 }1213 cell(col, row) {14 const { x, y } = this.frame;15 const w = this.frame.w / this.cols;16 const h = this.frame.h / this.rows;17 if (this.gap <= 0) {18 const x0 = round(x + col * w);19 const x1 = round(x + (col + 1) * w);20 const y0 = round(y + row * h);21 const y1 = round(y + (row + 1) * h);22 return [x0, y0, x1 - x0, y1 - y0];23 }24 const pad = (this.gap * Math.min(w, h)) / 2;25 return [x + col * w + pad, y + row * h + pad, w - 2 * pad, h - 2 * pad];26 }2728 fill(pen, col, row, color) {29 const [x, y, w, h] = this.cell(col, row);30 pen.rect(x, y, w, h, color);31 }3233 paint(pen, cells, ink) {34 const [height, width] = cells.shape;35 for (let row = 0; row < Math.min(this.rows, height); row++) {36 for (let col = 0; col < Math.min(this.cols, width); col++) {37 const color = ink(cells.types[row * width + col] & 255);38 if (color) this.fill(pen, col, row, color);39 }40 }41 }4243 carpet(pen, mask, color) {44 for (let row = 0; row < Math.min(mask.length, this.rows); row++) {45 for (let col = 0; col < Math.min(mask[row].length, this.cols); col++) {46 if (mask[row][col]) this.fill(pen, col, row, color);47 }48 }49 }50}5152// MASKS5354export const LOGO = Object.freeze(["11111", "10101", "11111", "10101", "11111"]);5556export function mask(rows, level) {57 const seed = rows.map((row) => [...row].map((c) => c === "1"));58 const width = seed.length ? seed[0].length : 0;59 let out = seed;60 for (let step = 1; step < Math.max(level, 1); step++) {61 const next = [];62 for (const row of out) {63 for (const inner of seed) next.push(row.flatMap((on) => (on ? inner : new Array(width).fill(false))));64 }65 out = next;66 }67 return out;68}6970export function carpet(pen, frame, mask, gap, color) {71 const rows = mask.length;72 const cols = rows ? mask[0].length : 0;73 if (rows === 0 || cols === 0) return;74 new Grid(frame, cols, rows, gap).carpet(pen, mask, color);75}