* {
margin: 0; padding: 0;
}
var canvas = document.createElement("canvas"),
c = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
c.fillStyle = "gray";
c.fillRect(0, 0, canvas.width, canvas.height);
c.strokeStyle = 'white';
c.lineWidth = 2;
c.beginPath();
c.moveTo(0, 0);
bezierSkin([ 10, 10, 210, 10, 10, 300, 210, 300 ], false);
bezierSkin([ 200, 10, 330, 10, 250, 300 ]);
bezierSkin(
Array(30).fill(0)
.map((a, b) => (b % 2 == 0) * 300 + Math.random() * 300)
);
c.stroke();
// array of xy coords, closed boolean
function bezierSkin(bez, closed = true) {
var avg = calcAvgs(bez),
leng = bez.length,
i, n;
if (closed) {
c.moveTo(avg[0], avg[1]);
for (i = 2; i < leng; i += 2) {
n = i + 1;
c.quadraticCurveTo(bez[i], bez[n], avg[i], avg[n]);
}
c.quadraticCurveTo(bez[0], bez[1], avg[0], avg[1]);
} else {
c.moveTo(bez[0], bez[1]);
c.lineTo(avg[0], avg[1]);
for (i = 2; i < leng - 2; i += 2) {
n = i + 1;
c.quadraticCurveTo(bez[i], bez[n], avg[i], avg[n]);
}
c.lineTo(bez[leng - 2], bez[leng - 1]);
}
}
// create anchor points by averaging the control points
function calcAvgs(p) {
var avg = [],
leng = p.length, prev;
for (var i = 2; i < leng; i++) {
prev = i - 2;
avg.push((p[prev] + p[i]) / 2);
}
// close
avg.push((p[0] + p[leng - 2]) / 2);
avg.push((p[1] + p[leng - 1]) / 2);
return avg;
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.