Canvas中能否结合clip为透明圆形添加shadowBlur阴影效果?
原因说明
shadowBlur 不生效是逻辑问题:Canvas的阴影只会渲染在实际执行填充/描边的图形上,你现在用的 clip() + clearRect() 是擦除像素的操作,不属于图形绘制,自然不会带出阴影效果。
你之前尝试的线性渐变方案方向不对,这种挖洞场景的边缘柔化,用径向渐变配合混合模式实现,效果和原生阴影完全一致。
正确实现代码
核心改动是去掉裁剪擦除的逻辑,改用 globalCompositeOperation = 'destination-out' 配合径向渐变绘制挖洞区域:中心区域完全不透明擦出全透的圆形,向外渐变到全透明,自然形成边缘模糊的阴影过渡。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .Preloader { background-color: #7bf; } canvas { display: block; } </style> </head> <body> <div class="Preloader"> <canvas id="myCanvas"></canvas> </div> <script> const c = document.getElementById("myCanvas"); const ctx = c.getContext("2d"); c.width = window.innerWidth; c.height = window.innerHeight; class Ball { constructor(x, y) { this.position = {x, y} this.r = 100 // 阴影模糊范围,可自行调整 this.shadowWidth = 20 } draw() { // 先铺半透明黑色遮罩 ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; ctx.fillRect(0, 0, c.width, c.height); // 切换混合模式:绘制内容会擦除已有像素 ctx.save() ctx.globalCompositeOperation = 'destination-out'; // 创建径向渐变:中心全透擦除,向外渐变到0不擦,形成模糊边 const gradient = ctx.createRadialGradient( this.position.x, this.position.y, this.r - this.shadowWidth, this.position.x, this.position.y, this.r + this.shadowWidth ) gradient.addColorStop(0, '#000') // 完全不透明,100%擦除 gradient.addColorStop(1, 'rgba(0,0,0,0)') // 完全透明,不擦除 ctx.fillStyle = gradient ctx.beginPath() ctx.arc(this.position.x, this.position.y, this.r + this.shadowWidth, 0, Math.PI * 2) ctx.fill() ctx.restore() } update() { this.draw() this.position.x++ this.position.y++ } } const ball = new Ball(c.width / 2, c.height / 2) function animate() { requestAnimationFrame(animate); ctx.clearRect(0, 0, c.width, c.height); ball.update(); }; animate(); window.addEventListener('resize', () => { c.width = window.innerWidth c.height = window.innerHeight }) </script> </body> </html>
参数调整说明
- 修改
shadowWidth的值可以控制边缘模糊的范围,数值越大阴影越宽 - 如果需要完全硬边的洞,把
shadowWidth设为0即可 - 渐变的中间色标可以自行调整,实现不同硬度的边缘过渡效果,比原生
shadowBlur的可控性更高
内容的提问来源于stack exchange,提问作者TomFan
相关产品推荐
相关产品推荐

