Изменить задержку в setTimeout нажатием кнопки - PullRequest
1 голос
/ 08 ноября 2019

Я работаю над созданием трехмерного вращающегося куба на холсте HTML. Мой код выглядит примерно так:

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

Здесь dacc - это коэффициент замедления, который замедляет вращение. Мне нужно создать трение кнопки, которое еще больше замедлит замедление на коэффициент х. Как изменить коэффициент замедления, пока setTimeout все еще выполняется? Я попытался обновить значение dacc с помощью функции onclick, но это не работает. Или есть другой способ вызвать вышеуказанную функцию, которая может помочь в этом?

Спасибо за помощь.

1 Ответ

2 голосов
/ 08 ноября 2019

Не используйте таймеры для изменения скорости. Скорость отображения устройства установлена ​​на уровне 60 кадров в секунду. Вы должны анимировать синхронно с этой скоростью. Используйте requestAnimationFrame (rAF)

Приведенный ниже код использует rAF для обновления анимации раз в 60 секунд.

  • rotateSpeed - это сколько поворачивается каждый кадр
  • Каждый кадр этой скорости уменьшается на величину в dacc. Если ниже некоторого минимума minSpeed вращение останавливается;
  • Событие щелчка может изменить скорость замедления путем изменения dacc
  • rAF остановится, когда скорость вращения станет меньше minSpeed.
  • Для запуска анимации вызовите startRotateAnim();

Используемые значения являются лишь оценкой вашего кода. Вам нужно будет поиграть со значениями, чтобы анимация выглядела так, как вы хотите.

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);
    }
}
...