<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Demo smooth connection</title>
</head>
<body>
<canvas id="canvas"></canvas>
<style>
html {
position: relative;
height: 100%;
width: 100%;
}
body {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: 0;
}
canvas {
outline: 1px solid red;
}
</style>
<script>
const getDistance = (p1, p2) => {
return Math.sqrt(
Math.pow(p1.x + p2.x, 2)
+
Math.pow(p1.y + p1.y, 2)
)
}
const getControlpoint = (points) => {//三个点出两个控制点
const p01 = getDistance(points[0], points[1])
const p12 = getDistance(points[1], points[2])
const p02 = p01 + p12
let vector = [points[2].x - points[0].x, points[2].y - points[0].y]
return [
{
x: points[1].x - vector[0] * 0.5 * p01 / p02,
y: points[1].y - vector[1] * 0.5 * p01 / p02
},
{
x: points[1].x + vector[0] * 0.5 * p01 / p02,
y: points[1].y + vector[1] * 0.5 * p01 / p02
}
]
}
let canvas = document.querySelector('canvas')
let ctx = canvas.getContext('2d')
window.onload = window.onresize = () => {
canvas.width = document.body.clientWidth
canvas.height = document.body.clientHeight
drawBezierCurve()
drawPoint()
}
let points = [
{ x: 131, y: 193 },
{ x: 187, y: 128 },
{ x: 231, y: 240 },
{ x: 280, y: 124 },
{ x: 340, y: 236 },
{ x: 368, y: 131 },
{ x: 416, y: 239 },
]
const drawPoint = () => {
points.forEach(point => {
ctx.beginPath()
ctx.arc(point.x, point.y, 5, 0, 2 * Math.PI)
ctx.fill()
})
}
const drawBezierCurve = () => {
let len = points.length
if (len < 2) {
return
}
ctx.beginPath()
ctx.moveTo(points[0].x, points[0].y)
if (len === 2) {
ctx.lineTo(points[1].x, points[1].y)
} else {
let controlPoint = []
for (let i = 1; i < len - 1; i++) {
controlPoint = controlPoint.concat(getControlpoint([points[i - 1], points[i], points[i + 1]]))
}
let i = 2
ctx.quadraticCurveTo(controlPoint[0].x, controlPoint[0].y, points[1].x, points[1].y)
for (; i < len - 1; i++) {
ctx.bezierCurveTo(
controlPoint[(i - 2) * 2 + 1].x,
controlPoint[(i - 2) * 2 + 1].y,
controlPoint[(i - 1) * 2].x,
controlPoint[(i - 1) * 2].y,
points[i].x,
points[i].y
)
}
console.log(controlPoint, i)
ctx.quadraticCurveTo(
controlPoint[(i - 2) * 2 + 1].x,
controlPoint[(i - 2) * 2 + 1].y,
points[i].x,
points[i].y
)
}
ctx.strokeStyle = 'blue'
ctx.stroke()
}
</script>
</body>
</html>
注意点:1.第二个点和最后一个点要使用quadraticCurveTo, 2.线1受2点和3点控制
参考资料:https://stackoverflow.com/questions/7054272/how-to-draw-smooth-curve-through-n-points-using-javascript-html5-canvas/10060462#10060462
原理:http://scaledinnovation.com/analytics/splines/aboutSplines.html
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。