我试图为Libet任务做一个时钟--心理学家使用的一项认知任务。按照惯例,这些钟需要2560毫秒才能完成一场革命。我的车跑得慢多了,我能找出原因。
我在这里给出了一个例子:https://jsfiddle.net/Sumoza/re4v7Lcj/8/
在延迟1ms的setInterval迭代中,用(Math.PI*2)/2560增大手的旋转角,即半径圆的1/2560。因此,递增其中的一个,每个ms应该在这个毫秒数中完成圆圈。正如你从时钟中看到的那样,它运行得稍微慢一些。有谁能解释一下为什么。有趣的是,*10看起来更接近我想要的东西--但这对我来说没有多大意义,所以我对修复很谨慎。相关的JS从小提琴下面。谢谢你的帮助。
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);发布于 2022-04-06 21:18:16
以当前时间为基础,并且不依赖于setInterval在您设置的触发时间触发它。如果在setInterval应该触发的时候出现了队列中的东西,那么它将首先执行队列中的操作,然后运行连接到setIterval的函数(导致所看到的延迟--随着时间的推移,这种延迟会越来越多)。了解事件循环和requestAnimationFrame。
相反,在做某事之前,先得到时间(新鲜的),然后计算一下从开始时间到现在已经过去了多少时间。将动画建立在这些计算的基础上。这样,即使有轻微的延迟,您的最后一个操作总是将事情同步到它们现在应该看到的样子。
当您这样做时,您可能会丢失一些帧(跳过引擎没有时间做的事情),但是它很可能会完成更接近预期的完成时间。
底线是,如果你告诉浏览器在特定的时间内做的比它能做的更多,就会有延迟。但是,您可以跳过动画的框架,以使事情更接近预期的完成时间。
发布于 2022-04-06 21:22:41
尝尝这个
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)
}发布于 2022-04-06 21:02:16
您要求setInterval每1ms调用一次回调,但实际上是每1ms调用一次吗?
试试下面的代码:
let cnt = 0;
setInterval(() => cnt++, 1);
setTimeout(() => { console.log(cnt); }, 1000);对我来说,它印的东西在230到235之间。所以看起来我的实际(平均)最小间隔是超过4ms。
https://stackoverflow.com/questions/71773517
复制相似问题