Reputation: 101
I am working on creating a 3D rotating cube in HTML canvas. 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. I need to create button friction which will further slow down the de-acceleration by factor x. How do I change the de-acceleration factor while setTimeout is still in progress? I tried updating the value of dacc with an onclick function but that doesn't work. Or is there any other way to call the above function that can help in this ?
Thanks for the help.
Upvotes: 1
Views: 173
Reputation: 54026
Do not use timers to change speed. The display rate of the device is fixed at 60 frames a second. You should animate in sync with this rate. Use requestAnimationFrame (rAF)
The code below uses rAF to update the animation once ever 60th second.
rotateSpeed
is how much to rotate each framedacc
. If below some min minSpeed
the rotation is stopped;dacc
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.
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);
}
}
Upvotes: 2