["#f5dc23", "#ed225d", "#1c1c1c"],
["#fe01ec", "#8a07da", "#102340"],
["#0d40bf", "#f4e361", "#f24679"],
["#ffffff", "#000000", "#ffe819"],
["#021d34", "#228fca", "#dcedf0"],
["#3cd86b", "#ebf7cd", "#0d150b"],
OPC.slider("seed", Math.floor(Math.random() * 1000), 0, 1000, 1)
OPC.slider("grid_size", 7, 3, 11, 1)
OPC.palette("palette", _palettes)
OPC.toggle("flip_colors", false)
OPC.toggle("line_only", false)
OPC.slider("line_thickness", 0.5, 0, 1, 0.25)
OPC.slider("effect", 2, 1, 2, 1)
let xCorner, yCorner, realSize
createCanvas(windowWidth, windowHeight)
xCorner + (realSize - grid_size * s) / 2,
yCorner + (realSize - grid_size * s) / 2
for (let i = 0; i < grid_size; i++) {
for (let j = 0; j < grid_size; j++) {
if (floor(j / 2) % 2 !== 0) {
_c = [colors[1], colors[0], colors[2]]
makeTile(i * s, getY(j, s), s, sw, _c)
makeTile2(i * s, getY(j, s), s, sw, _c)
function recalculateSizes() {
realSize = floor(min(windowWidth, windowHeight) * 0.8)
xCorner = width / 2 - realSize / 2
yCorner = height / 2 - (realSize * 9) / 10 / 2
sw = map(line_thickness, 0, 1, 0, s / 15)
tile = createGraphics(s, s)
tile2 = createGraphics(s, floor((s * 4) / 5) + 1)
return ceil(j * ((s * 9) / 10))
return getY(j - 1, s) + s
function makeTile(x, y, s, sw, colors) {
translate(x + s / 2, y + s / 2)
rotate(random([0, PI / 2, PI, (3 * PI) / 2]))
let _c = colors.map((c) => color(c))
lerpColor(_c[1], _c[0], phase),
lerpColor(_c[0], _c[1], phase),
tile.background(colors[0])
tile.circle(s / 2, s / 2, 2 * u)
tile.background(colors[1])
tile.background(colors[0])
tile.circle(s, (3 / 2) * u, u)
tile.circle((3 / 2) * u, s, u)
tile.background(colors[0])
tile.circle(s / 2, 0, 3 * u)
tile.circle(s, s / 2, 3 * u)
tile.circle(s / 2, s, 3 * u)
tile.circle(0, s / 2, 3 * u)
tile.background(colors[1])
tile.rect(-sw, 2 * u, s + 2 * sw, u)
tile.background(colors[0])
tile.circle((7 / 2) * u, 0, u)
tile.circle(s, (3 / 2) * u, u)
tile.circle(s / 2, s / 2, 2 * u)
function makeTile2(x, y, s, sw, colors) {
translate(x + s / 2, y + (s * 2) / 5)
let phase = getPhase(true)
scale(1, map(phase, 0, 1, -1, 1))
} else if (effect === 2) {
rotate(map(phase, 0, 1, PI, 0))
tile2.background(colors[1])
tile2.circle(0, 0, 2 * u)
tile2.circle(s, 0, 2 * u)
tile2.circle(0, 4 * u, 4 * u)
tile2.circle(s, 4 * u, 4 * u)
tile2.rect(2 * u, -u, u, 3 * u, u)
tile2.circle(0, 4 * u, 2 * u)
tile2.circle(s, 4 * u, 2 * u)
tile2.background(colors[1])
tile2.circle(0, 0, 6 * u)
tile2.circle(s, 0, 2 * u)
tile2.circle((3 * u) / 2, 4 * u, u)
tile2.circle(s, 4 * u, 4 * u)
tile2.circle(0, 0, 4 * u)
tile2.circle(s, 4 * u, 2 * u)
tile2.circle(0, 0, 2 * u)
tile2.background(colors[1])
tile2.circle(0, 0, 2 * u)
tile2.circle(s, 0, 2 * u)
tile2.circle(0, (5 * u) / 2, u)
tile2.circle(s, (5 * u) / 2, u)
tile2.rect(2 * u, -u, u, 2 * u, u)
tile2.circle(s / 2, 4 * u, 3 * u)
tile2.circle(s / 2, 4 * u, u)
tile2.background(colors[0])
tile2.circle(0, 0, 4 * u)
tile2.circle(s, 0, 4 * u)
tile2.circle(0, 4 * u, 2 * u)
tile2.circle(s, 4 * u, 2 * u)
tile2.rect(2 * u, 2 * u, u, 4 * u, u)
tile2.circle(0, 0, 2 * u)
tile2.circle(s, 0, 2 * u)
function drawBorders(s, colors) {
let gridHeight = getY(grid_size, s)
for (let i = 0; i < grid_size; i++) {
let c0_1 = [...colors[1], 255 * phase]
let c1_2 = [...colors[1], 255 * (1 - phase)]
let c2_1 = [...colors[2], 255 * phase]
let c2_2 = [...colors[2], 255 * (1 - phase)]
let swapColors = (i, n) => {
let isOdd = floor(i / 2) % 2 === 0
circle(i * s + (3 * s) / 10, 0, s / 5)
circle(i * s + (7 * s) / 10, 0, s / 5)
circle(i * s, 0, (2 * s) / 5)
circle(i * s + s / 2, 0, s / 5)
swapColors(grid_size, false)
circle(i * s, gridHeight, (2 * s) / 5)
circle(i * s + s / 2, gridHeight, s / 5)
swapColors(grid_size, true)
circle(i * s + (3 * s) / 10, gridHeight, s / 5)
circle(i * s + (7 * s) / 10, gridHeight, s / 5)
circle(0, getY(i, s) + (3 * s) / 10, s / 5)
circle(grid_size * s, getY(i, s) + (3 * s) / 10, s / 5)
circle(0, getY(i, s) + (7 * s) / 10, s / 5)
circle(grid_size * s, getY(i, s) + (7 * s) / 10, s / 5)
circle(0, getY(i, s), (2 * s) / 5)
circle(grid_size * s, getY(i, s), (2 * s) / 5)
circle(0, getY(i, s) + s / 2, s / 5)
circle(grid_size * s, getY(i, s) + s / 2, s / 5)
circle(0, getY(i, s) + (3 * s) / 10, s / 5)
circle(grid_size * s, getY(i, s) + (3 * s) / 10, s / 5)
circle(0, getY(i, s), (2 * s) / 5)
circle(grid_size * s, getY(i, s), (2 * s) / 5)
circle(0, getY(i, s) + (5 * s) / 10, s / 5)
circle(grid_size * s, getY(i, s) + (5 * s) / 10, s / 5)
swapColors(grid_size, false)
circle(grid_size * s, gridHeight, (2 * s) / 5)
function windowResized() {
resizeCanvas(windowWidth, windowHeight)
function parameterChanged(name, value) {
if (name === "palette") {
if (name === "grid_size") {
function recalculatePalette() {
colors = palette.map((c) => {
return [red(_c), green(_c), blue(_c)]
colors = [colors[1], colors[0], colors[2]]
colors = [colors[0], colors[0], colors[2]]
if (line_thickness == 0) {
colors = [colors[0], colors[2], colors[2]]
function getPhase(useEasing = false) {
let f = (frameCount + 2 * rest)
let phase = (f % p) / period
return useEasing ? easing(phase) : phase
return x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2
p5.Graphics.prototype.remove = function () {
if (this.elt.parentNode) {
this.elt.parentNode.removeChild(this.elt)
var idx = this._pInst._elements.indexOf(this)
this._pInst._elements.splice(idx, 1)
for (var elt_ev in this._events) {
this.elt.removeEventListener(elt_ev, this._events[elt_ev])