JSFiddle - React, Tailwind, and code Playground
by Joshua
HTML
<textarea>
[
{"x":0,"y":0},
{"x":10,"y":100},
{"x":90,"y":50},
{"x":300,"y":100},
{"x":400,"y":0}
]
</textarea>
<svg width="400" height="400">
<path d="" fill="none" stroke="#000" stroke-width="2px" />
</svg>
CSS
textarea {
display:block;
width:400px; height:200px;
}
JavaScript
var svg_helper = {
point: function(x, y){
if((typeof x !== 'undefined') && (typeof y !== 'undefined')){
var ar = {x:x, y:y};
} else {
var ar = [];
for(var i=0; i<x; i++)
ar.push({});
}
return ar;
},
curve: {
get_control_points: function(knots){
function get_first_control_points(rhs){
var n = rhs.length;
var x = []; // solution vector.
var tmp = []; // temp workspace.
var b = 2.0;
x[0] = rhs[0] / b;
for (var i = 1; i < n; i++) // decomposition and forward substitution.
{
tmp[i] = 1 / b;
b = (i < n - 1 ? 4.0 : 3.5) - tmp[i];
x[i] = (rhs[i] - x[i - 1]) / b;
}
for (var i = 1; i < n; i++)
x[n - i - 1] -= tmp[n - i] * x[n - i]; // backsubstitution.
return x;
}
if (!knots || n < 1)
return false;
var first_control_points,
second_control_points,
n = knots.length - 1;
if (n == 1)
{ // straight line
first_control_points = new svg_helper.point(1);
// 3p1 = 2p0 + p3
first_control_points[0].x = (2 * knots[0].x + knots[1].x) / 3;
first_control_points[0].y = (2 * knots[0].y + knots[1].y) / 3;
second_control_points = new svg_helper.point(1);
// p2 = 2p1 – p0
second_control_points[0].x = 2 *
first_control_points[0].x - knots[0].x;
second_control_points[0].y = 2 *
first_control_points[0].y - knots[0].y;
} else {
// calculate first bezier control points
// right hand side vector
var rhs = [];
// set right hand side x values
for (var i = 1; i < n - 1; ++i)
rhs[i] = 4 * knots[i].x + 2 * knots[i + 1].x;
rhs[0] = knots[0].x + 2 * knots[1].x;
rhs[n - 1] = (8 * knots[n - 1].x + knots[n].x) / 2.0;
// get first control points x-values
var x = get_first_control_points(rhs);
// set right hand side y values
for (var i = 1; i < n - 1; ++i)
rhs[i] = 4 * knots[i].y + 2 * knots[i + 1].y;
rhs[0] = knots[0].y + 2 * knots[1].y;
rhs[n - 1] = (8 * knots[n - 1].y + knots[n].y)...