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

p5.js如何将一个对象渲染在另一对象前方 解决圆形被遮挡问题

问题描述

我已经被这个问题困扰了数小时,不知道该如何处理。

我的代码

JS代码

var circles = [];
var circles2 = [];

function setup() {
  createCanvas(500, 500);
  //there's a "b" for every "a"
  for (var a = 50; a < width - 300; a += 20) {
    for (var b = 50; b < height - 300; b += 20) {
      //add the circles to the array at x = a and y = b
      circles.push(new Circle(a, b));
      circles2.push(new Conn(a, b));
    }
  }
  for (var a = 250; a < width - 50; a += 20) {
    for (var b = 250; b < height - 50; b += 20) {
      //add the circles to the array at x = a and y = b

    }
  }
  console.log(circles.length);
}

function draw() {
  background(50);
  for (var b = 0; b < circles.length; b++) {
    circles2[b].show();
    circles[b].show();
    //console.log("shown");
  }
  for (var b = 0; b < circles2.length; b++) {
    //circles2[b].show();
    //console.log("shown");
  }
}

function Circle(x, y) {
  this.x = x;
  this.y = y;

  this.show = function() {
    fill(255);
    noStroke();
    ellipse(this.x, this.y, 10, 10);
    //console.log("showing");
    push();
    fill(255);
    noStroke();
    translate(250, 250);
    ellipse(this.x, this.y, 10, 10);
    pop();
  }
}

function Conn(x, y) {
  this.x = x;
  this.y = y;

  this.show = function() {
    noStroke();
    let h = 0;
    for (let i = 0; i < 251; i++) {
      fill(h, 90, 120);
      h = (h + 1) % 500;
      noStroke();
      push()
      ellipse(this.x + i, this.y + i, 10, 10);
      noStroke();
      noLoop();
    }
  }
}

HTML代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

问题说明

代码预期生成圆形网格,通过渐变线条连接到另一组圆形网格。但实际运行时右下角圆形网格只有最后一行和最右列的圆形可见,其余圆形都被渐变线条遮挡。我尝试过push、pop等方法都没有效果,想知道如何让右下角网格的所有圆形都显示在渐变线条前方,为什么仅部分圆形能正常显示?


问题原因及解决方案

为什么仅部分右下角圆形可见

p5.js的绘制遵循层叠规则,后执行的绘制内容会覆盖在先绘制的内容上方:

  • 你当前的绘制逻辑是循环每一组圆点,先画对应渐变连线,再画左上角和右下角的两个圆点
  • 前面索引的圆点对应的渐变连线,绘制范围会覆盖后面索引圆点在右下角区域的绘制位置
  • 只有最后一行和最右列的圆点,绘制时机晚于所有会遮挡它们的渐变连线,所以可以正常显示

修复方案

调整绘制顺序,先把所有渐变连线全部绘制完成,再统一绘制所有圆点即可,修改draw函数逻辑如下:

function draw() {
  background(50);
  // 第一步:先绘制所有渐变连线
  for (var b = 0; b < circles2.length; b++) {
    circles2[b].show();
  }
  // 第二步:统一绘制所有圆点,此时圆点会全部覆盖在连线上方
  for (var b = 0; b < circles.length; b++) {
    circles[b].show();
  }
}

另外注意你Conn类的show方法里的noLoop()位置错误,现在每次调用show都会触发全局停止绘制,导致画布只渲染一次就终止,你可以把noLoop()移到setup函数的最后一行即可解决这个异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:09:03