frame.js
1.3 kB · javascript · 67 lines
1// FRAME23class Frame {4 constructor(x, y, w, h) {5 this.x = x;6 this.y = y;7 this.w = w;8 this.h = h;9 }1011 inset(px) {12 return new Frame(this.x + px, this.y + px, this.w - 2 * px, this.h - 2 * px);13 }1415 cell(n) {16 return this.w / n;17 }1819 at(u, v) {20 return [this.x + u * this.w, this.y + v * this.h];21 }2223 center() {24 return this.at(0.5, 0.5);25 }2627 square() {28 const side = Math.min(this.w, this.h);29 return new Frame(this.x + (this.w - side) / 2, this.y + (this.h - side) / 2, side, side);30 }3132 radius() {33 return Math.min(this.w, this.h) / 2;34 }3536 cols(n) {37 const w = this.w / n;38 return Array.from({ length: n }, (_, i) => new Frame(this.x + i * w, this.y, w, this.h));39 }4041 rows(n) {42 const h = this.h / n;43 return Array.from({ length: n }, (_, i) => new Frame(this.x, this.y + i * h, this.w, h));44 }45}4647export function frame(x, y, w, h) {48 return new Frame(x, y, w, h);49}5051// BOARD5253export const CLEAR = Object.freeze([0, 0, 0, 0]);5455export function board(width, height) {56 return {57 width,58 height,59 frame(margin) {60 const side = Math.min(width, height) * (1 - 2 * margin);61 return new Frame((width - side) / 2, (height - side) / 2, side, side);62 },63 area(margin) {64 return new Frame(0, 0, width, height).inset(Math.min(width, height) * margin);65 },66 };67}