JSFiddle - React, Tailwind, and code Playground
HTML
<canvas style='float:left' width='510' height='510' id='c'>
</canvas>
<div style='padding-left:550px; font-family:Arial'>
<span class='h' style='width:123px'>Control Points</span><br />
(<input type='text' id='x0' size='3' maxlength='3' />,<input type='text' id='y0' size='3' maxlength='3' />)<br />
(<input type='text' id='x1' size='3' maxlength='3' />,<input type='text' id='y1' size='3' maxlength='3' />)<br />
(<input type='text' id='x2' size='3' maxlength='3' />,<input type='text' id='y2' size='3' maxlength='3' />)<br />
(<input type='text' id='x3' size='3' maxlength='3' />,<input type='text' id='y3' size='3' maxlength='3' />)<br /><br />
<span class='h' style='width:200px'>Appearance</span><br />
<span style='font-weight:bold'>Guide lines</span><br />
<input type='checkbox' checked='checked' id='u' onchange='' /> Use curve colors<br />
<table style='border-collapse:collapse'>
<tr><td><input type='checkbox' id='guide-show-0' /></td><td><input type='color' id='guide-color-0' disabled='disabled' /></td><td class='t'>Frame</td><td><input type='text' id='guide-width-0' size='2' maxlength='2' /></td></tr>
<tr><td><input type='checkbox' id='guide-show-1' /></td><td><input type='color' id='guide-color-1' disabled='disabled' /></td><td class='t'>1</td><td><input type='text' id='guide-width-1' size='2' maxlength='2' /></td></tr>
<tr><td><input type='checkbox' id='guide-show-2' /></td><td><input type='color' id='guide-color-2' disabled='disabled' /></td><td class='t'>2</td><td><input type='text' id='guide-width-2' size='2' maxlength='2' /></td></tr>
<tr><td><input type='checkbox' id='guide-show-3' /></td><td><input type='color' id='guide-color-3' disabled='disabled' /></td><td class='t'>3</td><td><input type='text' id='guide-width-3' size='2' maxlength='2' /></td></tr>
</table>
<span style='font-weight:bold'>Curves</span>
<table style='border-collapse:collapse'>
<tr><td><input type='checkbox' id='curve-show-0' /></td><td><input type='color' id='curve-color-0' /></td><td...
CSS
span.h{
display: inline-block;
text-align: center;
text-decoration: underline;
font: bold 1em Arial;
}
input[type="color"]{
-webkit-appearance: button-bevel;
vertical-align: -7px;
width: 21px;
height: 27px;
}
input[type="color"][disabled]{background: #FFF}
td{position:relative; padding:1px; text-align:center}
table[class] td{text-align:left}
td.t{padding:1px 5px; width:46px;}
table input[type="checkbox"]{visibility:hidden}
tr:hover input[type="checkbox"]{visibility:visible}
JavaScript
function Bezier(c){
if(c.length==2) return function(t){return [c[0][0]+t*(c[1][0]-c[0][0]),c[0][1]+t*(c[1][1]-c[0][1])]}
else return function(t){return Bezier([Bezier(c.slice(0,-1))(t),Bezier(c.slice(1))(t)])(t)}
}
function Bezier2(f1,f2){
return function(t){return Bezier([f1(t),f2(t)])(t)}
}
//============================================
var c = null
var settings = {'guide':{'show':[true,true,true,true], 'color':['#EEEEEE','#00FF00','#0000FF','#FF00FF'], 'width':[10,1,1,1]}, 'curve':{'show':[false,false,false,false], 'color':['#EEEEEE','#00FF00','#0000FF','#FF00FF'], 'width':[10,3,3,3]}, 'main':{'show':true, 'color':'#FF0000', 'width':10}, 'sample': 100, 'steps':100, 'stepTime':10, 'mode':'Bezier', 'coords':[[0,500],[125,450],[125,0],[500,0]]}
var itv = 0
window.addEventListener('load',function(){
c = $('c').getContext('2d')
c.lineCap = 'round'
c.lineJoin = 'round'
draw(settings.coords,1)
},true)
function get(k,i){
var t = settings
if(k.constructor == Array) k.forEach(function(e){t = t[e]})
return t.length>i ? t[i] : t.slice(-1)[0]
}
function frame(coords){
c.strokeStyle = settings.curve.color[0]
c.lineWidth = settings.guide.width[0]
c.beginPath()
c.moveTo.apply(c,coords[0])
coords.slice(1).forEach(function(e){c.lineTo.apply(c,e)})
c.stroke()
}
function transf(c){
var t = []
c.forEach(function(e){t.push([e[0]+5,e[1]+5])})
return t
}
//============================================
function drawBezier(coords,t){
if(t===undefined) t = 1
coords = transf(coords)
c.clearRect(0,0,510,510)
frame(coords)
c.beginPath()
c.strokeStyle = settings.main.color
c.lineWidth = settings.main.width
c.moveTo.apply(c,coords[0])
for(var i=0;i<=t*settings.sample;i++) c.lineTo.apply(c,Bezier(coords)(i/settings.sample))
c.stroke()
}
function animateBezier(coords){
var s = settings.steps
var cur = ($('t').value==1 ? ($('t').value=$('T').innerHTML=(0).toFixed(3))*1 : $('t').value*s)+1
var b = drawBezier(coords,$('t').value*1)
itv =...