A simple clipping region
HTML
<div class="border">
<div class="frame">
<canvas id="c"></canvas>
</div>
</div>
<div class="callback">
<p>The code for the frame is coming from <a href="https://generativeartistry.com" target="_blank">Generative Artistry</a></p>
</div>
SCSS
body {
background: #fff;
display: flex;
height: 100vh;
margin: 0;
align-items: center;
justify-content: center;
position: relative;
min-height: 560px;
--blur: 2px;
}
.border {
box-sizing: border-box;
position: relative;
background: black;
background-image: -webkit-gradient(linear, right top, left bottom, from(#111), to(#000));
padding: 20px;
box-shadow: -1px 1px var(--blur) 1px rgba(0, 0, 0, 0.1), -2px 2px var(--blur) 1px rgba(0, 0, 0, 0.09), -3px 3px var(--blur) 1px rgba(0, 0, 0, 0.08), -4px 4px var(--blur) 1px rgba(0, 0, 0, 0.07), -5px 5px var(--blur) 1px rgba(0, 0, 0, 0.06), -6px 6px var(--blur) 1px rgba(0, 0, 0, 0.05), -7px 7px var(--blur) 1px rgba(0, 0, 0, 0.04), -8px 8px var(--blur) 1px rgba(0, 0, 0, 0.03), -9px 9px var(--blur) 1px rgba(0, 0, 0, 0.03), -10px 10px var(--blur) 1px rgba(0, 0, 0, 0.03), -11px 11px var(--blur) 1px rgba(0, 0, 0, 0.03), -12px 12px var(--blur) 1px rgba(0, 0, 0, 0.02), -13px 13px var(--blur) 1px rgba(0, 0, 0, 0.02), -14px 14px var(--blur) 1px rgba(0, 0, 0, 0.01), -15px 15px var(--blur) 1px rgba(0, 0, 0, 0.01), -16px 16px var(--blur) 1px rgba(0, 0, 0, 0.01);
}
.frame {
left: 3%;
top: 2.5%;
box-shadow: inset -1px 1px 6px 1px rgba(0, 0, 0, 0.24);
background: white;
align-items: center;
display: flex;
padding: 40px;
box-sizing: border-box;
}
canvas {
box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.2);
height: 320px;
width: 320px;
padding: 10px;
background-size: cover;
background-position: center center;
}
.callback {
position: absolute;
font-family: monospace;
bottom: 10px;
}
JavaScript
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const size = window.innerWidth;
const dpr = window.devicePixelRatio;
const s = size * dpr;
canvas.width = s;
canvas.height = s;
ctx.scale(dpr, dpr);
ctx.lineWidth = 8;
ctx.lineCap = 'round';
const center = s / 4;
const radius = s / 4;
const gap = 20;
const step = radius / gap;
const start = center - radius - (step / 2);
const end = center + radius + (step / 2);
const blockGap = s / 30;
/* Pythagorean theorem */
const pyT = y => Math.sqrt(Math.pow(radius, 2) - Math.pow(y, 2))
let y, half;
const points = [];
for (let index = start; index <= end; index = index + step) {
y = index;
half = pyT(center - y);
if (Number.isNaN(half)) {
continue;
}
points.push({
from: center - half + 10,
to: center + half - 10,
y
})
}
const getRandomArbitrary = (max, min = 0) => Math.floor(Math.random() * (max - min + 1)) + min;
const splitToNums = (from, to) => {
let n = to - from;
const a = [];
let s;
while (n > 0) {
s = getRandomArbitrary(n)
a.push(s);
n -= s;
}
return a;
}
const shuffle = a => {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
const limit = (v = []) => {
const c = [];
for (let index = 0; index < v.length; index++) {
if (v[index] < blockGap) {
if (index === 0) {
c.push(v[index]);
} else {
c[0] = c[0] + v[index];
}
} else {
c[c.length] = v[index]
}
}
return c;
}
const splitToBlocks = p => {
const {
from,
to,
y
} = p;
const blox = shuffle(limit(splitToNums(from, to)));
return {
froms: [from, ...blox.map(v => Math.round(v + from))],
tos: [...blox.map(v => {
const s = Math.round(v + from - blockGap);
return s < from ? from : s;
}), to],
y
}
}
let blocks;
points.forEach((p, index) => {
const {
froms,
tos,
...