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

P5.js定时计数器问题:timeElapsed返回NaN求助

解决P5.js计数器的NaN问题与逻辑修正

嘿,我来帮你捋捋代码里的问题,一步步搞定这个计数器需求~

1. 导致NaN的核心原因:变量作用域冲突

你在全局声明了var startTime;,但在setup()里又写了var startTime = millis();——这会创建一个局部的startTime变量,全局的startTime依然是undefined。当你在draw()里计算timeElapsed = (startTime - millis())时,本质是undefined - 数字,结果自然是NaN啦。

2. 计数器逻辑的额外问题

  • 时间计算顺序搞反了:应该是当前时间 - 初始时间,也就是millis() - startTime,这样得到的才是程序启动后流逝的毫秒数。
  • draw()函数会以每秒60次的频率持续执行,你里面的for循环每次都会遍历0到10,而且timeElapsed % 3000 === 0的条件几乎不会精准触发(millis()精度很高,很难刚好卡在3000的整数倍时刻),就算触发了也会一次性打印所有数字,完全不是你想要的“依次输出”效果。

修正后的完整代码

var startTime;
var currentNum = 1; // 跟踪当前要打印的数字
var hasPrinted = false; // 标记当前数字是否已打印

function setup() {
  createCanvas(windowWidth, windowHeight);
  background("#dc3787");
  startTime = millis(); // 去掉var,直接给全局变量赋值
  console.log("程序启动时间:", startTime);
}

function draw() {
  var timeElapsed = millis() - startTime; // 修正时间计算顺序

  // 当到达当前数字对应的3秒节点,且未打印过该数字
  if (timeElapsed >= currentNum * 3000 && !hasPrinted) {
    console.log(currentNum);
    hasPrinted = true; // 标记为已打印,避免重复输出
    currentNum++;

    // 数字到10后停止draw循环,节省性能
    if (currentNum > 10) {
      noLoop();
      console.log("计数完成!");
    }
  }

  // 进入下一个3秒周期时,重置打印标记
  if (timeElapsed >= currentNum * 3000) {
    hasPrinted = false;
  }
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

代码说明

  • 用currentNum跟踪当前要输出的数字,从1逐步递增到10
  • hasPrinted标记确保每个数字只打印一次,不会因为draw的高频执行重复输出
  • 数字到10后调用noLoop()停止循环,避免不必要的性能消耗
  • 彻底修复了变量作用域问题,startTime能正确获取程序初始时间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:43:27