canvas实现圆角多边形需手动构造圆弧或贝塞尔曲线:用arcto()基于切线生成相切圆弧,或用quadraticcurveto()拟合柔顺过渡;需逐顶点计算向量、限制半径、闭合处理,并配合linecap='round'和linejoin='round'提升视觉一致性。

Canvas 本身不自动给多边形顶点加圆角,所谓“圆角多边形”,本质是把每个尖角替换成一段圆弧路径——核心靠 arcTo() 或贝塞尔曲线手动构造,而不是靠 lineJoin 等样式属性“一键平滑”。
用 arcTo() 替换直角顶点
arcTo(x1, y1, x2, y2, r) 是实现圆角最直接的方式。它不画任意弧,而是基于两条切线生成与之相切、半径为 r 的圆弧:
- 前一段线终点设为 A,下一段线起点设为 C,两线交点为 B;
- 调用
arcTo(C.x, C.y, D.x, D.y, r)(其中 D 是下一段线的终点),Canvas 会自动计算出从 B 到 C 的圆弧; - 关键:
r不能超过两条边夹角所允许的最大内切圆半径,否则弧会“撑出”顶点外侧; - 实际绘制时,需在每个顶点前先
lineTo(B),再arcTo(C.x, C.y, D.x, D.y, r),避免跳点。
用贝塞尔曲线拟合圆角
当需要更可控的曲率(比如非均匀圆角或动态变化),可用 quadraticCurveTo() 或 bezierCurveTo():
- 对每两个相邻边 AB 和 BC,在 B 点附近插入控制点:让 AB 延伸方向取 1/3 长度作控制点 P1,BC 起始方向取 1/3 长度作 P2;
- 用
quadraticCurveTo(P1.x, P1.y, B.x, B.y)进入顶点,再用quadraticCurveTo(P2.x, P2.y, C.x, C.y)离开; - 这种方式适合手绘轨迹、数据折线图等需柔顺过渡的场景,比
arcTo()更灵活但计算稍重。
批量处理顶点的通用逻辑
对 n 个顶点的多边形,圆角处理需循环遍历每组连续三点(prev → curr → next):
- 计算向量 v1 = curr − prev,v2 = next − curr;
- 归一化后求单位切线方向,确定圆弧起止切线;
- 根据夹角大小动态限制最大可用
r(锐角处r必须小,否则弧会重叠); - 首尾闭合时注意:最后一个顶点的 “next” 应是第一个顶点,prev 是倒数第二个,避免断开或错位。
配合 lineJoin 提升视觉一致性
arcTo() 或贝塞尔已负责顶点圆角,但线段端点和连接处仍可能突兀,可协同设置:
-
ctx.lineCap = 'round':让每条边起止端呈半圆,消除直线段末端的方角; -
ctx.lineJoin = 'round':虽对 arcTo 生成的弧无作用,但能统一处理未被替换的折线段连接处; -
ctx.lineWidth适当加粗(如 ≥2px):细线下的圆弧易显锯齿,加粗后过渡更自然。











