canvas 绘制多边形的通用步骤:
- 找到每个点的坐标,形成路径
- 设置状态
- 绘制
五角星的模样:
如果遇到正某形的情况,可以借助圆来计算。 这边,借助两个圆寻找每个点的坐标:
- 五角星的外圈相邻点之间的角度是:360/5 = 72
- 同理,五角星的内圈相邻点之间的角度是:360/5 = 72
- 于是,五角星两个相邻点的之间的角度是:72/2 = 36
- 于是,五角星最右边的点和 x 轴之间的角度是:90-36-36 = 18
- 于是,直角三角形中斜边为 R,一个夹角是 18,则夹角的那边长度是
R*cos(18deg)
,非夹角的那边长度是R*sin(18deg)
- 于是,外圈最右边的点坐标是
(R*cos(18deg),-R*sin(18deg))
,外圈往左的一个点是(R*cos(18+72deg),-R*sin(18+72deg))
,以此类推 - 于是,内圈最右边的点坐标是
(r*cos(54deg),-r*sin(54deg))
,内圈往左的一个点是(r*cos(54+72deg),-r*sin(54+72deg))
,以此类推
这样可以写一个五角星的路径函数,这里注意 cos 函数需要另外封装下,这样更方便使用:
五角星需要旋转角度的话,修改成
// ..参数加个rotate即可
ctx.lineTo(
R * cos(18 + i * angle - rotate) + x,
-R * sin(18 + i * angle - rotate) + y
);
ctx.lineTo(
r * cos(54 + i * angle - rotate) + x,
-r * sin(54 + i * angle - rotate) + y
);
修改 R 和 r 的值会有很多不同感觉的五角星,两者差距越大,五角星越尖锐,反之越圆润。
代码
<canvas id="canvas" width="500" height="500"></canvas>
<script>
const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");
// 角度转化成弧度
const getRadianFromAngle = (angle) => (Math.PI / 180) * angle;
// 封装下cos sin
const cos = (angle) => Math.cos(getRadianFromAngle(angle));
const sin = (angle) => Math.sin(getRadianFromAngle(angle));
function getStarPath({ ctx, x, y, R, r, rotate = 0 }) {
ctx.beginPath();
const horn = 5;
const angle = 360 / horn;
for (let i = 0; i < horn; i++) {
ctx.lineTo( R * cos(18 + i * angle - rotate) + x, -R * sin(18 + i * angle - rotate) + y );
ctx.lineTo( r * cos(54 + i * angle - rotate) + x, -r * sin(54 + i * angle - rotate) + y );
}
ctx.closePath();
}
// 1.设置路径
getStarPath({ ctx, x: 200, y: 200, R: 100, r: 50 });
// 2.设置状态
ctx.lineWidth = "3";
ctx.strokeStyle = "#f69";
// 3.绘制
ctx.stroke();
</script>
引用
liuyubobobo 的绘制五角星 视频
liuyubobobo 的 Canvas 绘图与动画基础 视频
liuyubobobo 的 Canvas 绘图详解 视频