JSFiddle - React, Tailwind, and code Playground
HTML
<canvas width="400px" height="400px"></canvas>
JavaScript
function splitCurve(options) {
var z = options.z,
cz = z-1,
z2 = z*z,
cz2 = cz*cz,
z3 = z2*z,
cz3 = cz2*cz,
x = options.x,
y = options.y;
var left = [
x[0],
y[0],
z*x[1] - cz*x[0],
z*y[1] - cz*y[0],
z2*x[2] - 2*z*cz*x[1] + cz2*x[0],
z2*y[2] - 2*z*cz*y[1] + cz2*y[0],
z3*x[3] - 3*z2*cz*x[2] + 3*z*cz2*x[1] - cz3*x[0],
z3*y[3] - 3*z2*cz*y[2] + 3*z*cz2*y[1] - cz3*y[0]];
var right = [
z3*x[3] - 3*z2*cz*x[2] + 3*z*cz2*x[1] - cz3*x[0],
z3*y[3] - 3*z2*cz*y[2] + 3*z*cz2*y[1] - cz3*y[0],
z2*x[3] - 2*z*cz*x[2] + cz2*x[1],
z2*y[3] - 2*z*cz*y[2] + cz2*y[1],
z*x[3] - cz*x[2],
z*y[3] - cz*y[2],
x[3],
y[3]];
return { left: left, right: right};
}
var x = [0, 0.4, 0.2, 1];
var y = [0, 0.25, 1, 1];
var cvs = document.querySelector("canvas");
cvs.width = 400;
cvs.height = 400;
var ctx = cvs.getContext("2d");
ctx.fillStyle = "rgba(255,255,0,0.2)";
ctx.fillRect(0,0,400,400);
ctx.strokeStyle = "black";
// original curve
ctx.beginPath();
ctx.moveTo(0,400);
ctx.bezierCurveTo(
x[1] * 400, 400 - y[1]*400,
x[2] * 400, 400 - y[2]*400,
x[3] * 400, 400 - y[3]*400
);
ctx.stroke();
ctx.closePath();
// left / right splits
var result = splitCurve({
z: 0.4,
x: x,
y: y
});
console.log(result);
x = result.left.filter(function(v,idx) { return idx % 2 == 0; });
y = result.left.filter(function(v,idx) { return idx % 2 != 0; });
ctx.strokeStyle = "red";
ctx.beginPath();
ctx.moveTo(
x[0] * 400, 400 - y[0]*400
);
ctx.bezierCurveTo(
x[1] * 400, 400 - y[1]*400,
x[2] * 400, 400 - y[2]*400,
x[3] * 400, 400 - y[3]*400
);
ctx.stroke();
ctx.closePath();
x = result.right.filter(function(v,idx) { return idx % 2 == 0; });
y = result.right.filter(function(v,idx) { return...