html5 canvas可通过clip()方法配合自定义路径实现心形或五角星等异形裁剪:先用beziercurveto()绘制闭合心形,或用极坐标计算顶点绘制星形,再调用clip()设可见区域,最后drawimage()仅在该形状内显示图像。

HTML5 Canvas 本身不提供“心形裁剪”或“星形抠图”的一键命令,但可以通过 clip() 方法配合自定义路径,精准实现这类异形区域的视觉裁剪——本质是先画出闭合路径,再用它当“模具”,只让图片在该形状内显示。
核心原理:clip() 是路径驱动的“绘制窗口”
Canvas 的 clip() 不修改像素,也不擦除图像,而是设置一个**后续所有绘制操作都必须遵守的可见边界**。这个边界必须是已闭合的路径(closePath() 或自动闭合的 arc()、rect() 等),且调用 clip() 前必须有 beginPath()。
- 裁剪只对
clip()之后的绘制生效(比如drawImage()) - 裁剪状态可堆栈管理:
save()保存当前裁剪范围,restore()恢复上一层,避免污染后续绘制 - 路径支持变换:可在
clip()前用translate()、scale()、rotate()调整形状位置/大小/朝向
画心形:用贝塞尔曲线拼出平滑轮廓
心形无法用基础几何方法直接生成,需用两次 quadraticCurveTo() 或 bezierCurveTo() 构建左右半边。以下是一个居中、适配 canvas 尺寸的简化心形路径示例:
- 设 canvas 宽高为
w、h,取心形大小比例系数(如r = Math.min(w, h) * 0.3) ctx.beginPath();ctx.moveTo(w/2, h/2 - r/2); // 顶部起点ctx.bezierCurveTo(w/2 + r, h/2 - r, w/2 + r, h/2 + r, w/2, h/2 + r*1.2); // 右下半边ctx.bezierCurveTo(w/2 - r, h/2 + r, w/2 - r, h/2 - r, w/2, h/2 - r/2); // 左下半边,闭合回起点ctx.clip();- 再调用
ctx.drawImage(img, 0, 0, w, h);—— 此时仅心形区域内可见
画五角星:用极坐标计算顶点,lineTo 连成闭合多边形
五角星是规则多边形,适合用循环+三角函数生成 5 个顶点,确保路径严格闭合:
- 确定中心
(cx, cy)和外接圆半径r ctx.beginPath();- 循环 i = 0 到 4,计算每个顶点:
x = cx + r * Math.cos(angle),y = cy + r * Math.sin(angle),其中angle = Math.PI / 2 + i * 2 * Math.PI / 5(起始向上) - 用
moveTo()到第一个点,再用lineTo()依次连接所有点(含跳过中间点的星形连线逻辑,即 i → i+2 mod 5) - 最后
ctx.closePath(); ctx.clip(); - 绘制图片即可得到星形抠图效果
实用注意事项
直接用 clip() 裁剪后导出图片,结果就是纯异形区域内容(透明背景 PNG)。但要注意几个易错点:
- 路径未闭合 →
clip()无效,整张图仍可见;务必检查是否调用了closePath()或路径自然首尾衔接 - 忘记
beginPath()→ 路径叠加旧路径,裁剪区域异常;每次新裁剪前应重置路径 - 图片绘制坐标与 canvas 尺寸不匹配 → 星形/心形太小或偏移,建议先将图片完整绘制到 canvas,再统一做居中路径
- 需要多次不同形状裁剪 → 必须用
save()/restore()隔离裁剪状态,否则后一次会继承前一次的剪辑范围
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











