JavaScript是否提供高分辨率计时器?
JavaScript是否提供高分辨率计时器 我从零开始编写了一些游戏引擎,一些是用C编写的,一些是用Java编写的,还有一些是用Flash编写的。当涉及到动画和交互式图形时,我总是遵循相同的基本模型。使用以下设计创建基本类/结构:JavaScript是否提供高分辨率计时器?,javascript,animation,Javascript,Animation,JavaScript是否提供高分辨率计时器 我从零开始编写了一些游戏引擎,一些是用C编写的,一些是用Java编写的,还有一些是用Flash编写的。当涉及到动画和交互式图形时,我总是遵循相同的基本模型。使用以下设计创建基本类/结构: void init() { /* Called once, preload essential resources here. */ } void update(double time) { /* Updates game/animation state using
void init() { /* Called once, preload essential resources here. */ }
void update(double time) { /* Updates game/animation state using high resolution time. */ }
void render(double time) { /* Updates screen graphics using high resolution time. */ }
void run()
{
double time;
init();
while (!done)
{
time = queryTime();
update(time);
render(time);
}
}
时间对于平滑动画和游戏状态计算非常重要。在本机代码窗口中,我使用QueryPerformanceCounter()
和QueryPerformanceFrequency()
在每个游戏循环中执行queryTime()
角色,并将时间用于更新/渲染。在Java中,我使用System.nanoTime()
JavaScript中的等价物是什么?也就是说,一些函数,如queryTime()
,返回的时间值精度很高(亚毫秒)。据我所知,JavaScript的最高精确度大约为15毫秒。。。这对动画来说是可怕的。请参见-这是正确的答案。
在JavaScript中,毫秒是最好的。而且,就像你说的,它不是很准确。请参阅堆栈溢出问题
据称可提供高达微秒的分辨率,但仅适用于
更新:timer.js不支持微秒分辨率。它只是将毫秒计数乘以1000
对不起,没有更好的消息了 使用递归,而不是
while(true)
/setInterval
。它将比基于超时的动画运行更平滑。如果您需要动画以较慢的路径运行,它会提供时间戳。以下是JavaScript中的代码,因此它不会阻塞用户界面,也不会使用跨浏览器不起作用的代码
/* Called once, preload essential resources here. */
function init() {}
/* Updates game/animation state */
function update(time) {}
/* Updates screen graphics */
function render(time) {}
window.onload = function()
{
var time;
var done = false;
init();
// Using setTimeout passing zero makes the animate function run
// as soon as possible, but yielding first.
setTimeout(animate, 0);
function animate () {
time = new Date();
update(time);
render(time);
if (!done) {
setTimeout(animate, 0);
}
}
}
这种方法的一个问题是调用
animate()
的频率可能比屏幕更新的频率更高(在60赫兹时,它不会比每16毫秒更新一次的频率更高),这会导致额外的渲染,而不会出现在屏幕上。这就是为什么如果可能的话,你应该坚持使用requestAnimationFrame。你可以使用CSS3转换来制作简单的动画,这样可以获得完全的硬件加速,并且在大多数现代浏览器上运行起来非常流畅。。。如果您希望在JavaScript上实现平滑的动画,那就太不走运了,因为JavaScript没有亚毫秒精度
目前,在为web启用游戏相关技术方面取得了很多进展(例如,我们正在全屏上积极开发的鼠标锁草稿…也许你可以在JavaScript中启动微秒精度计时器的移动;-)几乎所有现代浏览器都提供高分辨率计时器。这是“高分辨率时间”W3C标准: 它允许您通过调用window.performance.now()获得亚毫秒的准确时间戳。这将返回一个时间戳,单位为ms,但它是一个浮点值,因此您仍然可以获得亚毫秒的分辨率
var d = 0;
var p = window.performance;
for(var i=0; i<10; i++) {
d = -1 * (p.now() - p.now());
console.log(d*1000);
}
非常旧的浏览器可能会实现此标准的“前缀”版本,例如用于实现window.performance.webkitNow()的基于WebKit的浏览器
以下是一些代码,您可以使用这些代码在时间戳可用时获取准确的时间戳,否则返回到标准精度:
if (window.performance.now) {
console.log("Using high performance timer");
getTimestamp = function() { return window.performance.now(); };
} else {
if (window.performance.webkitNow) {
console.log("Using webkit high performance timer");
getTimestamp = function() { return window.performance.webkitNow(); };
} else {
console.log("Using low performance timer");
getTimestamp = function() { return new Date().getTime(); };
}
}
getTimestamp();
请注意,此函数不返回表示当前日期/时间的值。返回值只能通过减去两个不同的时间戳来测量时间段。
例如
Node.js也有一个高分辨率计时器
process.hrtime()
请看截至目前(2013年2月25日),Chrome 24的高性能时间质量非常糟糕
var old = 0;
for (var i=0; i<10; i++) {
var t = window.performance.now();
var d = t - old;
old = t;
console.log(t + ' += ' +d);
}
这表明
1) 取样很少发生
2) 精度仍然在1ms左右,不在微秒范围内。因为这是在搜索JavaScript和高分辨率计时器时出现的,所以值得注意的是
window.performance.now
现在可以正常工作(至少在Google Chrome v.26中)并提供~微秒的分辨率
var d = 0;
var p = window.performance;
for(var i=0; i<10; i++) {
d = -1 * (p.now() - p.now());
console.log(d*1000);
}
我对几组10公里以上的成绩进行了统计。在我的机器上,最小值约为1微秒,平均值约为1.25微秒()。偶尔在100+微秒标记处会出现高异常值,但在10微秒以上时会出现频繁的结果
因此,高分辨率计时器现在能够以微秒分辨率进行计时减法。除了已经提供的优秀答案外,您还可以查看
var d = 0;
var p = window.performance;
for(var i=0; i<10; i++) {
d = -1 * (p.now() - p.now());
console.log(d*1000);
}
基于performance.mark/measure的高分辨率JavaScript计时器
(最小461字节+gz)
它还包括开发工具可视化,并在各种浏览器中进行了测试。刚才我搜索了这样的解决方案,发现了这个线程。正如我所看到的,所有测量都不正确,因为没有人知道work console.log是如何工作的。根据我的经验(和实践),这需要太多的时间,甚至异步工作 只需比较以下代码示例:
var old = 0;
for (var i=0; i<10; i++) {
var t = window.performance.now();
var d = t - old;
old = t;
console.log(t + ' += ' +d);
}
var-old=0;
对于(var i=0;iMight提供了一些见解:JS中的繁忙循环将阻止任何交互,因为只有一个线程。请查看,但目前仅在chrome和FF中工作。Juan,感谢您的回复。请参阅下面我对katspaugh的回复。好的,请跟进。如果浏览器不支持精确计时,推广html+javascript+canvas的人将如何期待开发使用html+javascript+canvas为浏览器创建漂亮的动画或实时交互式图形?动画应该基于时间而不是帧数。基于帧数的动画会导致它们在不同的硬件/系统配置上以不同的速度运行。这也不是很平滑。随着时间的推移,您可以插入增量。到据我所知,Flash也没有亚毫秒的计时。我认为没有人期望与本机应用程序具有同等的多媒体性能,而是朝着正确的方向迈出了一步。很高兴知道timer.js至少有这么多功能,乘以10
var old = 0;
for (var i=0; i<10; i++) {
var t = window.performance.now();
var d = t - old;
old = t;
console.log(t + ' += ' +d);
}
var old = 0;
var out = [];
for (var i=0; i<10; i++) {
var t = window.performance.now();
var d = t - old;
old = t;
out.push(t + ' += ' +d)
}
console.log(out);