xxxxxxxxxx
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
recalc();
}
function setColor(c) {
fill(c);
stroke(c);
}
const quads = [];
// the outer array represents rows, the inner arrays represent each column
let grid = [
[]
];
const palettes = [
"1a4b73-25435c-422663-215b8a-583582",
"074f57-077187-74a57f-9ece9a-e4c5af",
"241e4e-960200-ce6c47-ffd046-eadaa2",
"222e50-007991-439a86-bcd8c1-e9d985",
"966b9d-c98686-f2b880-fff4ec-e7cfbc",
"243010-87a330-a1c349-cad593-2a3c24",
"eac435-345995-03cea4-fb4d3d-ca1551",
"272727-fed766-009fb7-696773-eff1f3",
"e8c547-30323d-4d5061-5c80bc-cdd1c4",
"010400-30332e-fffbfc-62bbc1-ec058e",
"4281a4-48a9a6-e4dfda-d4b483-c1666b",
"c1f7dc-c3d2d5-bda0bc-a2708a-824670",
"987284-9dbf9e-d0d6b5-f9b5ac-ee7674",
].map(p => p.split('-').map(c => `#${c}`));
let colors = palettes[0];
let xStart, yStart;
let xStep, yStep;
let rows, cols;
let colOffset;
// oh my god I hate this
function resizeArray(ary, size, newValue = null) {
if (ary.length == size) return ary;
if (ary.length > size) ary.splice(size);
while (ary.length < size) ary.push(newValue);
}
function recalc() {
// start by creating a throwaway quad we'll use to do some math for us
const q = new Quad(0, 0, size, angle);
// calculate how many rows and columns we should have. the adds
// are important because the shape isn't square and treating it
// as such will result in blank spots on the edge of the screen.
rows = int(height / q.height) + 3;
cols = int(width / q.width) + 2;
// next calculate the origin of our grid. these were hand-tuned
// to make sure we always cover the entire viewport.
//
// I do not have confidence it works correctly
xStart = -(q.width / 4)
yStart = -(q.height / 2) * 2;
// now calculate how many pixels there are between each shape
// in both directions
xStep = q.width;
yStep = q.height;
// finally calculate how far we need to offset the even columns
// in order to get the grid to line up. this is just the difference
// in the y axis between the top left and top right corners
colOffset = int(q.points.tr.y - q.points.tl.y);
// now let's fix our grid. we're doing several things at once here:
// 1) resize the storage to match the grid we intend to draw,
// adding or removing rows and columns as necessary
// 2) ensuring each spot on the grid has a quad object
// 3) reconfiguring existing quad objects as necessary
//
// see above (where grid is declared) for an explanation of its structure
resizeArray(grid, rows);
for (let r = 0; r < rows; r++) {
grid[r] ||= [];
resizeArray(grid[r], cols);
const ly = yStart + r * yStep;
for (let c = 0; c < cols; c++) {
let q = grid[r][c];
const theta = c % 2 ? -angle : angle;
const offset = c % 2 ? colOffset : 0;
const lx = xStart + c * xStep;
if (q) {
q.resize({
length: size,
angle: theta,
x: lx,
y: ly + offset
});
} else {
q = new Quad(lx, ly + offset, size, theta);
q.colorIndex = int(random(palettes[0].length));
grid[r][c] = q;
}
}
}
}
function setup() {
createCanvas(windowWidth, windowHeight);
angleMode(DEGREES);
// normally there are tiny gaps between shapes. I don't understand
// why, but probably anti-aliasing? but noSmooth() doesn't fix it
//
// what *does* fix it is setting pixelDensity, which doesn't make
// sense to me but hey whatever works, right?
pixelDensity(2);
colors = random(palettes);
recalc();
}
function draw() {
background("#ff00ff");
for (const row of grid) {
for (const quad of row) {
if (quad.colorIndex === null) {
setColor("#ff00ff");
} else {
setColor(colors[quad.colorIndex]);
}
quad.draw();
}
}
}