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
相关产品推荐
相关产品推荐

