// This layer acts to convert squares and their edges to pixel coords and back. // i and j are notations for the grid of squares. // x and y are notations for absolute pixels. // // Grid: XY pair. 0-i on x and 0-j on y. // Absolute: XY pair. 0-width and 0-height, relative to viewport // Edge: A string. i1-j1-i1-j2. const Squares = function() { const controlBounds = document.getElementById('controls-container').getBoundingClientRect(); const contentBounds = document.getElementById('content-container').getBoundingClientRect(); const h = contentBounds.height - 40; const w = contentBounds.width - controlBounds.right - 40; const min = Math.min(h, w); // Centering const offsetX = (min === h) ? ((w - min) / 2) : 0; const offsetY = (min === h) ? 0 : ((h - min) / 2); this.perSide = 20; this.sideLength = Math.floor(min / this.perSide); // Origin (top left) this.x0 = controlBounds.left + controlBounds.width + 40 + offsetX; this.y0 = contentBounds.top + 40 + offsetY; } Squares.prototype.ijToXy = function({ i, j }) { if ((i !== 0 && !i) || (j !== 0 && !j)) { return } return { x: this.x0 + i * this.sideLength, y: this.y0 + j * this.sideLength } } Squares.prototype.xyToIj = function({ x, y }) { const i = Math.floor((x - this.x0) / this.sideLength); const j = Math.floor((y - this.y0) / this.sideLength); const min = 0; const max = this.perSide - 1; // Coalesce outlying results to grid edges. return { i: Math.min(Math.max(min, i), max), j: Math.min(Math.max(min, j), max), } }