首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >制作一个花费2560毫秒的时钟来完成JavaScript的革命

制作一个花费2560毫秒的时钟来完成JavaScript的革命
EN

Stack Overflow用户
提问于 2022-04-06 20:56:23
回答 4查看 54关注 0票数 1

我试图为Libet任务做一个时钟--心理学家使用的一项认知任务。按照惯例,这些钟需要2560毫秒才能完成一场革命。我的车跑得慢多了,我能找出原因。

我在这里给出了一个例子:https://jsfiddle.net/Sumoza/re4v7Lcj/8/

在延迟1ms的setInterval迭代中,用(Math.PI*2)/2560增大手的旋转角,即半径圆的1/2560。因此,递增其中的一个,每个ms应该在这个毫秒数中完成圆圈。正如你从时钟中看到的那样,它运行得稍微慢一些。有谁能解释一下为什么。有趣的是,*10看起来更接近我想要的东西--但这对我来说没有多大意义,所以我对修复很谨慎。相关的JS从小提琴下面。谢谢你的帮助。

代码语言:javascript
复制
var time = 0;
var rad_tick = (Math.PI*2)/2560; //radians per tick: last number is ms per revolution

// Draw Clock
const clock = document.getElementById('clock')
const clock_ctx = clock.getContext('2d')
clock_ctx.translate(clock.width/2, clock.height/2);
radius = (clock.height/2) * 0.7;

function drawClock() {
    clock_ctx.clearRect(-clock.width/2, -clock.height/2, clock.width, clock.height);
    clock.style.backgroundColor = 'transparent'; 
    clock_ctx.beginPath();
    clock_ctx.arc(0, 0, radius, 0 , 2 * Math.PI);
    clock_ctx.stroke();
}

drawClock();

// Draw Hand
const hand = document.getElementById('hand')
const hand_ctx = hand.getContext('2d')
hand_ctx.translate(hand.width/2, hand.height/2);

function drawHand(time){
    hand_ctx.clearRect(-hand.width/2, -hand.height/2, hand.width, hand.height);
    hand_ctx.beginPath();
    hand_ctx.moveTo(0,0);
    hand_ctx.rotate(time);
    hand_ctx.lineTo(0, -radius*0.9);
    hand_ctx.stroke();
    hand_ctx.rotate(-time);
}

function drawTime(){
    time+=rad_tick;//*10
    drawHand(time)
}

var intervalId = setInterval(drawTime, 1);
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2022-04-06 21:18:16

以当前时间为基础,并且不依赖于setInterval在您设置的触发时间触发它。如果在setInterval应该触发的时候出现了队列中的东西,那么它将首先执行队列中的操作,然后运行连接到setIterval的函数(导致所看到的延迟--随着时间的推移,这种延迟会越来越多)。了解事件循环requestAnimationFrame

相反,在做某事之前,先得到时间(新鲜的),然后计算一下从开始时间到现在已经过去了多少时间。将动画建立在这些计算的基础上。这样,即使有轻微的延迟,您的最后一个操作总是将事情同步到它们现在应该看到的样子。

当您这样做时,您可能会丢失一些帧(跳过引擎没有时间做的事情),但是它很可能会完成更接近预期的完成时间。

底线是,如果你告诉浏览器在特定的时间内做的比它能做的更多,就会有延迟。但是,您可以跳过动画的框架,以使事情更接近预期的完成时间。

票数 1
EN

Stack Overflow用户

发布于 2022-04-06 21:22:41

尝尝这个

代码语言:javascript
复制
var starttime = new Date().getTime();

function drawTime() {
    var elapsed = new Date().getTime() - starttime;
    var time = elapsed % 2560;
    time = time * rad_tick;
    console.log(elapsed + "->" + time);
    drawHand(time)
}
票数 2
EN

Stack Overflow用户

发布于 2022-04-06 21:02:16

您要求setInterval每1ms调用一次回调,但实际上是每1ms调用一次吗?

试试下面的代码:

代码语言:javascript
复制
let cnt = 0;
setInterval(() => cnt++, 1);
setTimeout(() => { console.log(cnt); }, 1000);

对我来说,它印的东西在230到235之间。所以看起来我的实际(平均)最小间隔是超过4ms。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71773517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档