如何在 HTML canvas 中仅将两个形状混合在一起而不影响其他形状

How to make only two shapes compost together in HTML canvas without effecting other shapes

所以我的目标很简单……我想。我想画一个矩形,中间挖一个洞。但我不希望那个洞穿过 canvas 上的任何其他东西。 现在我有这样的东西:

context.fillStyle = 'blue';
    context.fillRect(0, 0, width, height);

    context.fillStyle = "#000000";
    context.beginPath();
    context.rect(0, 0 , width, height);
    context.fill();
    enter code here

    context.globalCompositeOperation="destination-out";

    context.beginPath();
    context.arc(width / 2, height / 2 , 80, 0, 50);
    context.fill();

但是这也会切穿背景,我怎样才能让它只切穿黑色矩形而不切其他?

视觉示例,以防我解释得不好:

这是您希望实现的目标吗?

const context = document.getElementById("canvas").getContext('2d');
const width = 100;
const height = 100;
const circleSize = 30;

context.fillStyle = "black";
context.fillRect(0, 0 , width, height);

context.beginPath();
context.arc(width / 2, height / 2, circleSize, 0, 2 * Math.PI);
context.clip();

context.fillStyle = "blue";
context.fillRect(0, 0, width, height);
<canvas id="canvas"/>

这篇文章可能有用:
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing

在上面的示例中,我使用的是 clip。 正如文档所述:

The CanvasRenderingContext2D.clip() method of the Canvas 2D API turns the current or given path into the current clipping region.

这意味着在此行之后添加到上下文的任何元素都只会在该剪切路径内绘制。

看看这个是不是你要找的:

<canvas id="canvas" width="200" height="160"></canvas>

<script>
  class Shape {
    constructor(x, y, width, height, color) {
      this.color = color
      this.path = new Path2D();
      this.path.arc(x, y, height / 3, 0, 2 * Math.PI);
      this.path.rect(x + width / 2, y - height / 2, -width, height);
    }

    draw(ctx) {
      ctx.beginPath();
      ctx.fillStyle = this.color;
      ctx.fill(this.path);
    }
  }

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

  shapes = [];
  shapes.push(new Shape(40, 40, 80, 80, "blue"));
  shapes.push(new Shape(60, 65, 70, 70, "red"));
  shapes.push(new Shape(80, 40, 65, 65, "gray"));

  shapes.forEach((s) => {
    s.draw(ctx);
  });
</script>

我正在使用 Path2D(),因为我有一个我以前做过的简单示例,但没有它也应该可行。背后的理论很简单,我们只是想在圆上填充相反的部分。

我将半径硬编码为高度的三分之一,但您可以将所有这些更改为其他内容,甚至是最终用户可以更改的参数