You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用多边形(星形)和边缘模糊的圆形裁剪Canvas?

Canvas 实现锐利星形裁剪与边缘模糊圆形裁剪

要同时实现锐利边缘的星形裁剪和边缘渐变淡出的圆形裁剪,核心是利用Canvas的全局合成模式(globalCompositeOperation)分别处理两种遮罩效果,替代单纯依赖clip的逻辑。以下是修正后的实现:

完整代码

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }
    canvas {
      display: block;
    }
  </style>
</head>
<body>
  <canvas id="canvas"></canvas>
</body>
</html>

JavaScript

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const img = new Image();
img.src = "你的背景图片路径"; // 替换为实际图片路径
img.onload = function () {
  let mouseX = canvas.width / 2;
  let mouseY = canvas.height / 2;
  const starOuterRadius = 100;
  const starInnerRadius = 50;
  const circleRadius = 70;

  function draw() {
    // 1. 绘制背景图
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

    // 2. 添加深色遮罩层
    ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 3. 使用 destination-out 模式:绘制内容会清除原有像素(实现"挖洞")
    ctx.globalCompositeOperation = "destination-out";

    // 4. 绘制锐利边缘的星形挖洞
    const starPoints = createStar(5, mouseX, mouseY, starOuterRadius, starInnerRadius);
    ctx.beginPath();
    ctx.moveTo(starPoints[0].x, starPoints[0].y);
    for (let i = 1; i < starPoints.length; i++) {
      ctx.lineTo(starPoints[i].x, starPoints[i].y);
    }
    ctx.closePath();
    ctx.fill();

    // 5. 绘制边缘渐变的圆形挖洞
    const gradient = ctx.createRadialGradient(
      mouseX, mouseY, circleRadius * 0.6,
      mouseX, mouseY, circleRadius
    );
    // 渐变从中心完全挖空过渡到边缘保留遮罩,实现淡出效果
    gradient.addColorStop(0, "rgba(0, 0, 0, 1)");
    gradient.addColorStop(1, "rgba(0, 0, 0, 0)");
    
    ctx.fillStyle = gradient;
    ctx.beginPath();
    ctx.arc(mouseX, mouseY, circleRadius, 0, Math.PI * 2);
    ctx.fill();

    // 6. 恢复默认合成模式
    ctx.globalCompositeOperation = "source-over";
  }

  function createStar(points, cx, cy, outerRadius, innerRadius) {
    const result = [];
    const angleStep = Math.PI / points;
    for (let i = 0; i < 2 * points; i++) {
      const angle = i * angleStep - Math.PI / 2;
      const radius = i % 2 === 0 ? outerRadius : innerRadius;
      result.push({
        x: cx + radius * Math.cos(angle),
        y: cy + radius * Math.sin(angle),
      });
    }
    return result;
  }

  canvas.addEventListener("mousemove", function (event) {
    mouseX = event.clientX;
    mouseY = event.clientY;
    draw();
  });

  draw();
};

关键修改说明

  • 合成模式切换:用destination-out模式实现“挖洞”,替代原clip逻辑——clip会限制后续所有绘制区域,无法单独实现渐变边缘,而合成模式可精准控制像素清除。
  • 星形处理:直接绘制星形路径并填充,在destination-out模式下会生成锐利边缘的挖空区域。
  • 圆形渐变调整:反转渐变颜色停止点,从中心完全透明(挖空)过渡到边缘不透明(保留遮罩),自然呈现圆形边缘的渐变淡出效果。
  • 绘制顺序优化:先画背景图,再叠加遮罩,最后挖洞显示底层图像,逻辑更直观。

内容的提问来源于stack exchange,提问作者Guile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 15:53:14