<div class="worklet-canvas"></div>
<script>
CSS.paintWorklet.addModule('https://codepen.io/georgedoescode/pen/qBXYama.js');
document.documentElement.style.setProperty('--pattern-seed', Math.random() * 10000);
</script>
@property --pattern-seed {
syntax: "<number>";
initial-value: 1000;
inherits: true;
}
@property --pattern-colors {
syntax: "<color>#";
initial-value: #2d58b5, #f43914, #f9c50e, #ffecdc;
inherits: true;
}
@property --pattern-size {
syntax: "<number>";
initial-value: 1024;
inherits: true;
}
@property --pattern-detail {
syntax: "<number>";
initial-value: 16;
inherits: true;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.worklet-canvas {
/* the default custom properties defined above could be overriden here */
width: 100vw;
height: 100vh;
background-color: #18111d;
/* use the worklet to create the background-image for this element */
background-image: paint(bauhausPattern);
}
import random from "https://cdn.skypack.dev/random";
import seedrandom from "https://cdn.skypack.dev/seedrandom";
class BauhausPattern {
static get inputProperties() {
return [
"--pattern-seed",
"--pattern-colors",
"--pattern-size",
"--pattern-detail"
];
}
paint(ctx, geometry, props) {
const { width, height } = geometry;
const patternSize = props.get("--pattern-size").value;
const patternDetail = props.get("--pattern-detail").value;
const seed = props.get("--pattern-seed").value;
const colors = props.getAll("--pattern-colors").map((c) => c.toString());
random.use(seedrandom(seed));
this.scaleCtx(ctx, patternSize, patternSize, width, height);
const cellSize = patternSize / patternDetail;
for (let x = 0; x < patternSize; x += cellSize) {
for (let y = 0; y < patternSize; y += cellSize) {
const color = colors[random.int(0, colors.length - 1)];
ctx.fillStyle = color;
const cx = x + cellSize / 2;
const cy = y + cellSize / 2;
const shapeChoice = ["circle", "arc", "rectangle", "triangle"][
random.int(0, 3)
];
const rotationDegrees = [0, 90, 180][random.int(0, 2)];
ctx.save();
ctx.translate(cx, cy);
ctx.rotate((rotationDegrees * Math.PI) / 180);
ctx.translate(-cx, -cy);
switch (shapeChoice) {
case "circle":
circle(ctx, cx, cy, cellSize / 2);
break;
case "arc":
arc(ctx, cx, cy, cellSize / 2);
break;
case "rectangle":
rectangle(ctx, cx, cy, cellSize);
break;
case "triangle":
triangle(ctx, cx, cy, cellSize);
break;
}
ctx.fill();
ctx.restore();
}
}
}
scaleCtx(ctx, width, height, elementWidth, elementHeight) {
const ratio = Math.max(elementWidth / width, elementHeight / height);
const centerShiftX = (elementWidth - width * ratio) / 2;
const centerShiftY = (elementHeight - height * ratio) / 2;
ctx.setTransform(ratio, 0, 0, ratio, centerShiftX, centerShiftY);
}
}
function circle(ctx, cx, cy, radius) {
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
ctx.closePath();
}
function arc(ctx, cx, cy, radius) {
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 1);
ctx.closePath();
}
function rectangle(ctx, cx, cy, size) {
ctx.beginPath();
ctx.rect(cx - size / 2, cy - size / 2, size, size);
ctx.closePath();
}
function triangle(ctx, cx, cy, size) {
const originX = cx - size / 2;
const originY = cy - size / 2;
ctx.beginPath();
ctx.moveTo(originX, originY);
ctx.lineTo(originX + size, originY + size);
ctx.lineTo(originX, originY + size);
ctx.closePath();
}
if (typeof registerPaint !== "undefined") {
registerPaint("bauhausPattern", BauhausPattern);
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.