HTML Canvas:如何仅在半透明重叠圆弧的外部绘制描边?
Canvas实现重叠半透明圆形的外描边效果
问题描述
需要在Canvas上绘制两个半透明圆形,仅在组合形状的外部添加描边(重叠区域内部无描边),同时保持填充的半透明性以显示下方元素。当前代码会为每个圆形单独描边,且出现多余的闭合路径线条,无法满足需求。
解决方案
利用Canvas的裁剪(clip())和全局复合操作(globalCompositeOperation)实现外描边,同时保留半透明填充效果:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Canvas Arcs</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; } </style> </head> <body> <canvas id="myCanvas" width="400" height="200"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); const strokeWidth = 2; // 自定义描边宽度 const circleRadius = 80; // 1. 绘制半透明填充的两个重叠圆 ctx.fillStyle = 'rgba(255, 0, 0, 0.5)'; ctx.beginPath(); ctx.arc(100, 100, circleRadius, 0, Math.PI * 2); ctx.arc(200, 100, circleRadius, 0, Math.PI * 2); ctx.fill(); // 默认非零环绕规则,重叠区域正常填充 // 2. 绘制外部描边 ctx.save(); // 裁剪区域设置为两个圆的联合范围 ctx.beginPath(); ctx.arc(100, 100, circleRadius, 0, Math.PI * 2); ctx.arc(200, 100, circleRadius, 0, Math.PI * 2); ctx.clip(); // 设置复合模式:仅保留裁剪区域外的绘制内容(即挖掉内部) ctx.globalCompositeOperation = 'destination-out'; // 绘制比原圆小半个描边宽度的圆,挖掉内部区域,留下描边宽度的轮廓 ctx.beginPath(); ctx.arc(100, 100, circleRadius - strokeWidth / 2, 0, Math.PI * 2); ctx.arc(200, 100, circleRadius - strokeWidth / 2, 0, Math.PI * 2); ctx.fillStyle = '#000'; // 颜色不影响,仅用于挖除内部 ctx.fill(); ctx.restore(); </script> </body> </html>
原理说明
- 半透明填充:使用默认的非零环绕规则填充两个圆形,重叠区域会正常显示半透明效果,不会被抵消。
- 外描边实现:
- 先通过
clip()将绘制范围限制在两个圆的联合区域内。 - 切换到
destination-out复合模式,该模式会将新绘制的区域从已有内容中移除。 - 绘制比原圆小半个描边宽度的圆形,挖掉内部区域后,剩下的就是刚好等于描边宽度的外部轮廓。
- 先通过
- 描边宽度调整:修改
strokeWidth变量时,对应缩小的圆半径也要同步减去strokeWidth/2,保证描边宽度准确。
内容的提问来源于stack exchange,提问作者koto
相关产品推荐
相关产品推荐

