【问题标题】:Countdown timer not working倒数计时器不工作
【发布时间】:2013-05-27 04:46:01
【问题描述】:

我创建的倒数计时器不起作用。 有趣的是,如果我使用 console.log 打印 count 的值——从 3 开始——打印出类似 -3498 的内容,即使我只打开了大约 15 秒,所以设置的时间间隔肯定有问题代码。显示值(如果count大于0),但是设置间隔变化太快。

这是代码。

function countdown(){
  window_width=window.innerWidth-70;
  window_height=window.innerHeight-150;

  canvas = document.getElementById("gameCanvas");
  ctx=canvas.getContext("2d");
  canvas.width  = window_width;
  canvas.height=window_height;

  if(count>0){
    ctx.font = '40pt Calibri';
    ctx.fillStyle = "white";
    ctx.fillText(count, window_width/3, window_height/2);
  }
  else if(count===0){
    ctx.fillText("Go!", window_width/3, window_height/2);
  }
  else{
   return;
  }

  setInterval(function(){count=count-1},1000);
  requestAnimationFrame(countdown);
}

任何帮助将不胜感激。

【问题讨论】:

  • 看起来count 可能是一个全局变量,如果是这样,那就是你的问题所在。你的 setInterval 函数很好。 Here's a fiddle

标签: javascript html canvas html5-canvas setinterval


【解决方案1】:

我有点不清楚你想要完成什么,但这里有一个镜头:

window.count = 3;

setTimeout(countdown,1000);

function countdown(){
  window_width=window.innerWidth-70;
  window_height=window.innerHeight-150;

  canvas = document.getElementById("gameCanvas");
  ctx=canvas.getContext("2d");
  canvas.width  = window_width;
  canvas.height=window_height;

  count--;

  if(count>0){
    ctx.font = '40pt Calibri';
    ctx.fillStyle = "white";
    ctx.fillText(count, window_width/3, window_height/2);
    setTimeout(countdown,1000);
  }
  else if(count===0){
    ctx.fillText("Go!", window_width/3, window_height/2);
  }
  else{
   return;
  }

  requestAnimationFrame(countdown); // not sure if this is needed
}

据我所知,您不需要间隔。

【讨论】:

  • 谢谢,这真的很有帮助。
  • 不客气 :) 如果这个答案解决了你的问题,你可能想接受它和/或投票。
【解决方案2】:

数值显示,但变化太快

您需要区分逻辑和表示。当countdown函数被调用时,你安排一个函数以1s为单位减少计数,同时你安排countdown尽快被再次调用。画布的更新间隔大约是 16 毫秒……这意味着 count 以该速率减少,仅在启动后延迟 1 秒。

更糟糕的是,正如您使用 setInterval 一样,它永远重复减少 count,而该过程在每个动画帧都开始......

解决方案是根本不使用setTimeout/setInterval。它们不可靠,不应用于测量时间。相反,从Date object 获取准确的时间戳(每次您需要它们时,即每个动画帧):

var canvas = document.getElementById("gameCanvas");
var ctx = canvas.getContext("2d");
canvas.width  = window.innerWidth -70;
canvas.height = window.innerHeight-150;
ctx.font = '40pt Calibri';
ctx.fillStyle = "white";

var count = …;

var estimatedEnd = Date.now() + count*1000;

function countdown(){
    var currentCount = (estimatedEnd - Date.now()) / 1000;

    if (currentCount>0){
        ctx.fillText(currentCount, window_width/3, window_height/2);
        requestAnimationFrame(countdown);
    } else if (currentCount===0){
        ctx.fillText("Go!", window_width/3, window_height/2);
    }
}
countdown();

【讨论】:

  • Date.now() 这不是跨浏览器的最佳选择,因为旧浏览器没有实现它。建议将Date.now() 替换为new Date().getTime(),以确保与旧版浏览器的兼容性。
  • 当然,但正如你所说,如果需要支持过时的浏览器,那么很容易实现 shim……而且你可以期望支持 canvas 和 requestAnimationFrame 的浏览器也将支持 Date.now :-)跨度>
  • 完全正确!我的观点只有在触发了一些 requestAnimationFrame polyfill(带有 setInterval 或 setTimeout 后备)时才会成立,因为有些浏览器支持画布但不支持 requestAnimationFrame。
  • 我的主要营销方式是 Chrome 网上商店,所以几乎每个人都会在 Chrome 上运行。
  • 我通常会使用这种方法,但在我的情况下不需要特别准确。查看最终结果here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多