视频中提到的思路分为:
1.画线,通过对称的三次贝塞尔曲线将爱心形状拼出来
2.填充渐变色,径向渐变与填充色可参考以下两则
【效果图】
【实现思路与步骤】
现在我们需要使用到6个点(起始点、终点、4个辅助点),可以将原先的代码封装到函数里,通过6个坐标点的传值来同步画辅助点。
let pointBegin = [400, 200];
let pointEnd = [400, 450];
let pointCA1 = [180, 110];
let pointCA2 = [180, 400];
let pointCB1 = [620, 110];
let pointCB2 = [620, 400];
为函数起名为draw(),传6个点的参数给它。
function draw(begin, end, A1, A2, B1, B2) {
// ...
}
在draw()函数中,我们参考之前的代码,首先创建画布canvas。
// 1.创建canvas标签
const canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 800;
document.body.append(canvas);
// 2.得到context对象
const context = canvas.getContext('2d');
根据 33-贝赛尔曲线-CSDN博客 中提到的三次贝塞尔曲线的画法,先画爱心的A1,A2左侧,再画B1,B2右侧,最后stroke()时,提前设置 .strokeStyle 为 pink。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
// 目标:心形
// 1.给一个起始点
context.moveTo(begin[0], begin[1]);
// 2.调用 bezierCurveTo() 方法 , bezierCurveTo(控制点X1, 控制点Y1, 控制点X2, 控制点Y2,终点X, 终点Y)
context.bezierCurveTo(A1[0], A1[1], A2[0], A2[1], end[0], end[1]);
context.moveTo(begin[0], begin[1]);
context.bezierCurveTo(B1[0], B1[1], B2[0], B2[1], end[0], end[1]);
// 3.调用 绘制线段的方法
context.strokeStyle = 'pink'
context.stroke();
在爱心的线条都完成之后,开始进行径向渐变色的填充,参考 09-使用径向渐变-CSDN博客 。
let g = context.createRadialGradient(330, 240, 0, 360, 260, 100)
g.addColorStop(0, '#fff')
g.addColorStop(1, 'pink')
context.fillStyle = g
context.fill()
将4个辅助点push到一个arr中,循环arr进行辅助点的打点。
// 辅助点
let controllArr = [];
controllArr.push(A1);
controllArr.push(A2);
controllArr.push(B1);
controllArr.push(B2);
for (let i = 0; i < controllArr.length; i++) {
context.beginPath()
context.arc(controllArr[i][0], controllArr[i][1], 5, 0, toArc(360))
context.fillStyle = 'hotpink'
context.fill()
context.closePath()
}
// 辅助点 END
【完整代码】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
let pointBegin = [400, 200];
let pointEnd = [400, 450];
let pointCA1 = [180, 110];
let pointCA2 = [180, 400];
let pointCB1 = [620, 110];
let pointCB2 = [620, 400];
// // 转换公式 弧度 = 角度 * Math.PI / 180
function toArc(value) {
return value * Math.PI / 180
}
function draw(begin, end, A1, A2, B1, B2) {
// 1.创建canvas标签
const canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 800;
document.body.append(canvas);
// 2.得到context对象
const context = canvas.getContext('2d');
// 目标:心形
// 1.给一个起始点
context.moveTo(begin[0], begin[1]);
// 2.调用 bezierCurveTo() 方法 , bezierCurveTo(控制点X1, 控制点Y1, 控制点X2, 控制点Y2,终点X, 终点Y)
context.bezierCurveTo(A1[0], A1[1], A2[0], A2[1], end[0], end[1]);
context.moveTo(begin[0], begin[1]);
context.bezierCurveTo(B1[0], B1[1], B2[0], B2[1], end[0], end[1]);
// 3.调用 绘制线段的方法
context.strokeStyle = 'pink'
context.stroke();
let g = context.createRadialGradient(330, 240, 0, 360, 260, 100)
g.addColorStop(0, '#fff')
g.addColorStop(1, 'pink')
context.fillStyle = g
context.fill()
// 辅助点
let controllArr = [];
controllArr.push(A1);
controllArr.push(A2);
controllArr.push(B1);
controllArr.push(B2);
for (let i = 0; i < controllArr.length; i++) {
context.beginPath()
context.arc(controllArr[i][0], controllArr[i][1], 5, 0, toArc(360))
context.fillStyle = 'hotpink'
context.fill()
context.closePath()
}
// 辅助点 END
}
draw(pointBegin, pointEnd, pointCA1, pointCA2, pointCB1, pointCB2)
</script>
</html>