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}