在p5.js中如何实现逐点绘制时的单个延迟效果?
Hey,我来帮你搞定这个问题!你的points_oben函数现在一次性画所有点,主要是两个小问题在搞鬼:
首先,你外层循环里的每个setTimeout都设置了相同的3000毫秒延迟——这就相当于你同时给所有点定了3秒后的闹钟,时间一到它们就一起触发,自然会一次性画出所有点。
其次,每个定时器内部还写了一个遍历所有koords的循环,就算延迟时间错开了,每个定时器也会把所有点再画一遍,结果就是重复绘制,根本达不到逐点显示的效果。
快速修复方案:调整延迟+只画当前点
把你的函数改成这样,就能实现每个点依次延迟3秒绘制:
function points_oben() { for (let a = 0; a < koords.length; a++) { // 给每个点设置递增的延迟,a从0开始,第一个点延迟0ms(立即),第二个3000ms,以此类推 // 如果想第一个点也等3秒再画,就把延迟改成 (a + 1) * 3000 setTimeout(function() { strokeWeight(10); stroke('blue'); // 只绘制当前循环对应的点,而不是所有点 point(koords[a].xkoord, koords[a].ykoord); }, a * 3000); } }
更贴合p5.js的优雅实现
其实p5.js本身有专门处理动画的draw()循环和时间函数millis(),用它们来做逐点绘制会更稳定,也符合p5的设计逻辑。比如这样:
let currentPoint = 0; const interval = 3000; // 点与点之间的间隔(毫秒) let lastDrawTime = 0; function setup() { createCanvas(600, 400); // 这里可以替换成你的koords数组 koords = [ {xkoord: 100, ykoord: 100}, {xkoord: 200, ykoord: 200}, {xkoord: 300, ykoord: 150}, {xkoord: 400, ykoord: 250} ]; } function draw() { background(240); // 先画出已经显示过的所有点 strokeWeight(10); stroke('blue'); for (let i = 0; i < currentPoint; i++) { point(koords[i].xkoord, koords[i].ykoord); } // 检查是否到了绘制下一个点的时间 if (millis() - lastDrawTime > interval && currentPoint < koords.length) { point(koords[currentPoint].xkoord, koords[currentPoint].ykoord); currentPoint++; lastDrawTime = millis(); } } // 如果需要手动触发这个逐点绘制流程,可以调用这个函数 function points_oben() { currentPoint = 0; lastDrawTime = millis(); }
这种方式的好处是,你可以在draw()里轻松控制背景刷新、其他元素的显示,而且不会有setTimeout可能带来的异步时序问题。
内容的提问来源于stack exchange,提问作者Sebastian Lauss
相关产品推荐
相关产品推荐

