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

p5.js如何在不修改背景、不使用额外canvas的前提下给形状打孔

无需额外context的p5.js画布打孔实现方案

完全可以直接在默认画布实现需求,不需要创建额外的离屏canvas,不会产生额外内存占用、色差问题,以下是两种可直接运行的实现方案:


方案1:反向裁剪法(推荐)

利用p5的路径裁剪能力,先构造带孔洞的裁剪区域,再绘制前景内容,前景只会显示在裁剪区域内,孔洞位置不会绘制任何内容,完全不会影响已完成的背景。

function setup() {
  createCanvas(600,600);
  background(255, 0, 0);
  noStroke();
}

function draw() {
  // 先绘制所有不需要被打孔的背景内容
  fill("blue");
  rect(20,20,500,500);

  push(); // 保存画布状态,避免裁剪影响后续绘制
  
  // 构造带孔洞的裁剪路径:外层为全屏矩形,内层为所有需要打孔的形状
  beginShape();
  // 外层顺时针绘制全屏矩形
  vertex(0, 0);
  vertex(width, 0);
  vertex(width, height);
  vertex(0, height);
  // 第一个孔洞(逆时针绘制,要求与外层路径方向相反)
  beginContour();
  for(let a = 0; a < TAU; a += 0.01) {
    let x = 140 + cos(a) * 75;
    let y = 140 + sin(a) * 75;
    vertex(x, y);
  }
  endContour(CLOSE);
  // 第二个孔洞
  beginContour();
  for(let a = 0; a < TAU; a += 0.01) {
    let x = 180 + cos(a) * 75;
    let y = 180 + sin(a) * 75;
    vertex(x, y);
  }
  endContour(CLOSE);
  endShape(CLOSE);
  // 应用裁剪,后续绘制仅在裁剪区域生效
  clip();

  // 绘制前景内容,自动跳过孔洞区域
  fill("green");
  rect(100, 100, 200, 200);
  fill("yellow");
  rect(80, 80, 100, 300);

  pop(); // 恢复状态,取消裁剪

  noLoop();
}

方案2:混合模式法

使用DESTINATION_OUT混合模式,直接删除前景对应位置的像素,不会影响已绘制的背景,代码更简洁。

function setup() {
  createCanvas(600,600);
  background(255, 0, 0);
  noStroke();
}

function draw() {
  // 绘制背景
  fill("blue");
  rect(20,20,500,500);

  push();
  // 第一步:绘制所有前景内容
  fill("green");
  rect(100, 100, 200, 200);
  fill("yellow");
  rect(80, 80, 100, 300);

  // 切换混合模式:后续绘制的形状会删除同位置已有的像素
  blendMode(DESTINATION_OUT);
  // 绘制所有孔洞形状
  fill(255); // 填充色不影响效果,只要alpha不为0即可
  circle(140, 140, 150);
  circle(180, 180, 150);

  pop(); // 恢复默认混合模式,避免影响后续绘制

  noLoop();
}

方案对比

  • 反向裁剪法:无混合模式兼容风险,适合孔洞形状复杂、后续有多层绘制的场景,仅需要注意孔洞路径的绘制方向与外层路径相反。
  • 混合模式法:代码更简洁,适合逻辑简单的场景,需要严格控制绘制顺序,必须用push()/pop()包裹避免混合模式污染后续绘制逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 05:24:08