简体   繁体   English

使用按钮单击更改 setTimeout 中的延迟

[英]Change delay in setTimeout using a button click

I am working on creating a 3D rotating cube in HTML canvas.我正在努力在 HTML canvas 中创建一个 3D 旋转立方体。 My code looks something like this我的代码看起来像这样

function rotateCubeZM() {
    fr = 5;
    stoppage = 1;   
    for(let i = 0;i<200;i++,fr+=dacc) {
        setTimeout(rotateCubeZ,i*fr*stoppage,1);
    }
}

Here dacc is a de-acceleration factor which slows down the rotation.这里的 dacc 是一个减慢旋转的减速因子。 I need to create button friction which will further slow down the de-acceleration by factor x.我需要创建按钮摩擦,这将进一步减慢 x 因子的减速。 How do I change the de-acceleration factor while setTimeout is still in progress?如何在 setTimeout 仍在进行时更改减速因子? I tried updating the value of dacc with an onclick function but that doesn't work.我尝试使用 onclick function 更新 dacc 的值,但这不起作用。 Or is there any other way to call the above function that can help in this?或者有没有其他方法可以调用上述 function 来帮助解决这个问题?

Thanks for the help.谢谢您的帮助。

Do not use timers to change speed.不要使用计时器来改变速度。 The display rate of the device is fixed at 60 frames a second.该设备的显示速率固定为每秒 60 帧。 You should animate in sync with this rate.您应该与此速率同步动画。 Use requestAnimationFrame (rAF)使用requestAnimationFrame (rAF)

The code below uses rAF to update the animation once ever 60th second.下面的代码使用 rAF 每 60 秒更新一次 animation。

  • rotateSpeed is how much to rotate each frame rotateSpeed是每帧旋转多少
  • Each frame this speed is reduced by the amount in dacc .每一帧,这个速度都会减少dacc中的数量。 If below some min minSpeed the rotation is stopped;如果低于某个 min minSpeed则停止旋转;
  • A click event can change the rate of deceleration by changing dacc点击事件可以通过改变dacc来改变减速率
  • rAF will stop when the rotate speed is below minSpeed.当转速低于 minSpeed 时,rAF 将停止。
  • To start the animation call startRotateAnim();启动 animation 调用startRotateAnim();

The values used are just an estimate of from your code.使用的值只是您的代码的估计值。 You will have to play with the values to get the animation to look how you want.您将不得不使用这些值来让 animation 看起来像您想要的那样。

const fr = 5;  
const minSpeed = 0.01;
var rotateSpeed = 0, dacc;

// click event for quicker slowdown 
myButtonElement.addEventListener("click",() => dacc = 0.8);

// function to start / restart animation
function startRotateAnim() { 
    const animRunning = rotateSpeed > minSpeed; // if animation running just change values   
    rotateSpeed = 1 * (1000/60) / fr; // rotate per frame
    dacc = 0.4;        // the bigger the number the quicker the slowdown
    if (!animRunning) {
        requestAnimationFrame(mainLoop); // start the animation.
    }
}

function mainLoop() {  // this is called 60 times a second
    if (rotateSpeed > minSpeed) {  rotateSpeed -= dacc }
    if (rotateSpeed > minSpeed) { 
        rotateCubeZ(rotateSpeed);
        requestAnimationFrame(mainLoop);
    }
}

You can't do that.你不能那样做。 You have to clear the timeout and set a new timeout.您必须清除超时并设置新的超时。 setTimeout retuns a unique identifier. setTimeout返回一个唯一标识符。

// timer holds the timer identifier.
let timer = setTimeout(function, 1000);

// clear it when you click the button
clearTimeout(timer);

// and set new timer with new value
timer = setTimeout(function, 2000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM