JSFiddle - React, Tailwind, and code Playground
HTML
<button id="point0">Start</button>
<button id="point1">Control Point 1</button>
<button id="point2">Control Point 2</button>
<button id="point3">End</button>
<span id="t1"></span>
<span id="t2"></span>
<span id="valid"></span>
<svg viewBox="0 0 500 500">
<path id="editor" fill="none" stroke="#000000" stroke-width="10" stroke-linecap="round" d="M0,0" />
<path id="control1" fill="none" stroke="#ff0000" stroke-width="2" stroke-linecap="round" d="M0,0" />
<path id="control2" fill="none" stroke="#0000ff" stroke-width="2" stroke-linecap="round" d="M0,0" />
<path id="bezier1" fill="none" stroke="#ff0000" stroke-width="2" stroke-linecap="round" d="M0,0" />
<path id="bezier2" fill="none" stroke="#00ff00" stroke-width="2" stroke-linecap="round" d="M0,0" />
<path id="bezier3" fill="none" stroke="#0000ff" stroke-width="2" stroke-linecap="round" d="M0,0" />
</svg>
CSS
* {
margin: 0;
padding: 0;
}
svg {
width:500px;
height:500px;
border: 1px solid black;
}
JavaScript
var x0 = 200;
var y0 = 100;
var x1 = 300;
var y1 = 100;
var x2 = 400;
var y2 = 200;
var x3 = 400;
var y3 = 300;
// (0.707, 0.707)
var tangent = {x: 1 / Math.sqrt(2), y: 1 / Math.sqrt(2) };
var leftMouseDown = false;
var action = 'point1';
function SplitCubicBezier(t, point1, point2, point3, point4)
{
// Split the bezier curve at the time
// https://en.wikipedia.org/wiki/De_Casteljau's_algorithm
function interpolate(a, b, t)
{
return {
x: a.x + (b.x - a.x) * t,
y: a.y + (b.y - a.y) * t
};
}
var p0 = point1;
var p1 = point2;
var p2 = point3;
var p3 = point4;
var p4 = interpolate(p0, p1, t);
var p5 = interpolate(p1, p2, t);
var p6 = interpolate(p2, p3, t);
var p7 = interpolate(p4, p5, t);
var p8 = interpolate(p5, p6, t);
var p9 = interpolate(p7, p8, t);
return { first: [p0, p4, p7, p9], second: [p9, p8, p6, p3] };
}
function Update()
{
$('#control1').attr('d', 'm' + (x1 - 2) + ',' + (y1 - 2) + ' 4,0 0,4 -4,0Z');
$('#control2').attr('d', 'm' + (x2 - 2) + ',' + (y2 - 2) + ' 4,0 0,4 -4,0Z');
$('#editor').attr('d', 'M' + x0 + ',' + y0 + 'C' + x1 + ',' + y1 + ' ' + x2 + ',' + y2 + ' ' + x3 + ',' + y3);
$('#bezier1').attr('d', 'M0,0');
$('#bezier2').attr('d', 'M0,0');
$('#bezier3').attr('d', 'M0,0');
var tx0 = x0 * tangent.y;
var tx1 = x1 * tangent.y;
var tx2 = x2 * tangent.y;
var tx3 = x3 * tangent.y;
var ty0 = y0 * tangent.x;
var ty1 = y1 * tangent.x;
var ty2 = y2 * tangent.x;
var ty3 = y3 * tangent.x;
// Division by zero will need to be checked later along with inequality checks using an epsilon to correct for floating point error
var temp1 = (tx2 - tx3) / (y2 - y3);
var temp2 = (tx1 * tx1 + tx2 * tx2 + tx2 * (ty0 + ty1 - 2 * ty2) + tx1 * (-tx2 - tx3 - 2 * ty1 + ty2 + ty3) + tx3 * (ty1 - ty0) + ty1 * ty1 - ty0 * ty2 + ty2 * ty2 + ty0 * ty3 - ty1 * (ty2 + ty3)) / (tangent.y * (tx2 - tx3 - ty2 + ty3));
console.log ('Temp1: ', temp1, ' Temp2: ', temp2);
if
(
tangent.x < temp1 &&
(
...