截图如下,拖动黄色控制点可以改变曲线:
<!DOCTYPE html> <html> <head> <title></title> <script type="text/javascript"> var start = { x: 10, y: 150 }, ctl = { x: 100, y: 50 }, end = { x: 200, y: 150 }; var mouseIndex = -1; function draw() { var ctx = document.getElementById("canvas").getContext("2d"); ctx.clearRect(0, 0, 600, 500); ctx.lineWidth = 1; ctx.strokeStyle = "#000000"; ctx.beginPath(); //辅助连线 ctx.moveTo(start.x, start.y); ctx.lineTo(ctl.x, ctl.y); ctx.lineTo(end.x, end.y); ctx.stroke(); //曲线 ctx.beginPath(); ctx.strokeStyle = "#ff0000"; ctx.lineWidth = 4; ctx.moveTo(start.x, start.y); ctx.quadraticCurveTo(ctl.x, ctl.y, end.x, end.y); ctx.stroke(); //控制点 ctx.beginPath(); ctx.strokeStyle = "#000000"; ctx.fillStyle = mouseIndex == 0 ? "rgba(250,250,0,1)" : "rgba(210,210,0,1)"; ctx.lineWidth = 2; ctx.arc(start.x, start.y, 7, 0, 2 * Math.PI, false); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.fillStyle = mouseIndex == 1 ? "rgba(250,250,0,1)" : "rgba(210,210,0,1)"; ctx.arc(ctl.x, ctl.y, 7, 0, 2 * Math.PI, false); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.fillStyle = mouseIndex == 2 ? "rgba(250,250,0,1)" : "rgba(210,210,0,1)"; ctx.arc(end.x, end.y, 7, 0, 2 * Math.PI, false); ctx.fill(); ctx.stroke(); } function getRect(point) { return { x: point.x - 8, y: point.y - 8, width: 16, height: 16 }; } function contains(rect, point) { return point.x > rect.x && point.x < rect.x + rect.width && point.y > rect.y && point.y < rect.y + rect.height; } function handleMove(event) { if (window.mousedown) { if (mouseIndex == 0) { start = { x: event.offsetX, y: event.offsetY }; } else if (mouseIndex == 1) { ctl = { x: event.offsetX, y: event.offsetY }; } else if (mouseIndex == 2) { end = { x: event.offsetX, y: event.offsetY }; } draw(); } else { var newMouseIndex = mouseIndex; if (contains(getRect(start), { x: event.offsetX, y: event.offsetY })) { newMouseIndex = 0; } else if (contains(getRect(ctl), { x: event.offsetX, y: event.offsetY })) { newMouseIndex = 1; } else if (contains(getRect(end), { x: event.offsetX, y: event.offsetY })) { newMouseIndex = 2; } else { newMouseIndex = -1; } if (newMouseIndex !== mouseIndex) { mouseIndex = newMouseIndex; draw(); } } } </script> </head> <body onload="draw()" onmousedown="window.mousedown=1" onmouseup="window.mousedown=0"> <canvas id="canvas" width="600" height="500" onmousemove="handleMove(event)"></canvas> </body> </html>
贝塞尔曲线:
<!DOCTYPE html> <html> <head> <title></title> <script type="text/javascript"> var start = { x: 10, y: 150 }, ctl = { x: 100, y: 50 }, ctl2={x:200,y:200},end = { x: 300, y: 150 }; var mouseIndex = -1; function draw() { var ctx = document.getElementById("canvas").getContext("2d"); ctx.clearRect(0, 0, 600, 500); ctx.lineWidth = 1; ctx.strokeStyle = "#000000"; ctx.beginPath(); //辅助连线 ctx.moveTo(start.x, start.y); ctx.lineTo(ctl.x, ctl.y); ctx.lineTo(ctl2.x, ctl2.y); ctx.lineTo(end.x, end.y); ctx.stroke(); //曲线 ctx.beginPath(); ctx.strokeStyle = "#ff0000"; ctx.lineWidth = 4; ctx.moveTo(start.x, start.y); ctx.bezierCurveTo(ctl.x, ctl.y, ctl2.x,ctl2.y,end.x, end.y); ctx.stroke(); //控制点 ctx.beginPath(); ctx.strokeStyle = "#000000"; ctx.fillStyle = mouseIndex == 0 ? "rgba(250,250,0,1)" : "rgba(210,210,0,1)"; ctx.lineWidth = 2; ctx.arc(start.x, start.y, 7, 0, 2 * Math.PI, false); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.fillStyle = mouseIndex == 1 ? "rgba(250,250,0,1)" : "rgba(210,210,0,1)"; ctx.arc(ctl.x, ctl.y, 7, 0, 2 * Math.PI, false); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.fillStyle = mouseIndex == 2 ? "rgba(250,250,0,1)" : "rgba(210,210,0,1)"; ctx.arc(ctl2.x, ctl2.y, 7, 0, 2 * Math.PI, false); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.fillStyle = mouseIndex == 3 ? "rgba(250,250,0,1)" : "rgba(210,210,0,1)"; ctx.arc(end.x, end.y, 7, 0, 2 * Math.PI, false); ctx.fill(); ctx.stroke(); } function getRect(point) { return { x: point.x - 8, y: point.y - 8, width: 16, height: 16 }; } function contains(rect, point) { return point.x > rect.x && point.x < rect.x + rect.width && point.y > rect.y && point.y < rect.y + rect.height; } function handleMove(event) { if (window.mousedown) { if (mouseIndex == 0) { start = { x: event.offsetX, y: event.offsetY }; } else if (mouseIndex == 1) { ctl = { x: event.offsetX, y: event.offsetY }; } else if (mouseIndex == 2) { ctl2 = { x: event.offsetX, y: event.offsetY }; }else if (mouseIndex == 3) { end = { x: event.offsetX, y: event.offsetY }; } draw(); } else { var newMouseIndex = mouseIndex; if (contains(getRect(start), { x: event.offsetX, y: event.offsetY })) { newMouseIndex = 0; } else if (contains(getRect(ctl), { x: event.offsetX, y: event.offsetY })) { newMouseIndex = 1; } else if (contains(getRect(ctl2), { x: event.offsetX, y: event.offsetY })) { newMouseIndex = 2; } else if (contains(getRect(end), { x: event.offsetX, y: event.offsetY })) { newMouseIndex = 3; }else { newMouseIndex = -1; } if (newMouseIndex !== mouseIndex) { mouseIndex = newMouseIndex; draw(); } } } </script> </head> <body onload="draw()" onmousedown="window.mousedown=1" onmouseup="window.mousedown=0"> <canvas id="canvas" width="600" height="500" onmousemove="handleMove(event)"></canvas> </body> </html>