Для демонстрации проблемы, пожалуйста, смотрите здесь:
https://gyazo.com/06e423d07afecfa2fbdb06a6da77f66a
Я получаю прыжковое поведение при приостановке уведомления.Это также зависит от того, как долго мышь остается в уведомлении, и насколько близок прогресс до конца.
Я пробовал так много вещей, я больше не уверен, действительно ли проблема в setTimeout.
Это похоже на то, как если бы с момента вычисления this.timerFinishesAt до первой итерации requestAnimationFrame скачок прогресса происходил из-за ожидания времени процессора?Но опять же, почему на это влияют время зависания и прогресс.
Как смягчить поведение при прыжке?
Я прочитал / попытался внедрить исправление из следующих ресурсов среди поисковна другие вопросы stackoverflow:
https://gist.github.com/tanepiper/4215634
Как создать точный таймер в javascript?
В чем причина JavaScript setTimeoutтак неточно?
https://www.sitepoint.com/creating-accurate-timers-in-javascript/
https://codepen.io/sayes2x/embed/GYdLqL?default-tabs=js%2Cresult&height=600&host=https%3A%2F%2Fcodepen.io&referrer=https%3A%2F%2Fmedium.com%2Fmedia%2Fb90251c55fe9ac7717ae8451081f6366%3FpostId%3D255f3f5cf50c&slug-hash=GYdLqL
https://github.com/Falc/Tock.js/tree/master
https://github.com/philipyoungg/timer
https://github.com/Aaronik/accurate_timer
https://github.com/husa/timer.js
timerStart(){
// new future date = future date + elapsed time since pausing
this.timerFinishesAt = new Date( this.timerFinishesAt.getTime() + (Date.now() - this.timerPausedAt.getTime()) );
// set new timeout
this.timerId = window.setTimeout(this.toggleVisibility, (this.timerFinishesAt.getTime() - Date.now()));
// animation start
this.progressId = requestAnimationFrame(this.progressBar);
},
timerPause(){
// stop notification from closing
window.clearTimeout(this.timerId);
// set to null so animation won't stay in a loop
this.timerId = null;
// stop loader animation from progressing
cancelAnimationFrame(this.progressId);
this.progressId = null;
this.timerPausedAt = new Date();
},
progressBar(){
if (this.progress < 100) {
let elapsed = Date.now() - this.timerStarted.getTime();
let wholeTime = this.timerFinishesAt.getTime() - this.timerStarted.getTime();
this.progress = Math.ceil((elapsed / wholeTime) * 100);
if (this.timerId) {
this.progressId = requestAnimationFrame(this.progressBar);
}
} else {
this.progressId = cancelAnimationFrame(this.progressId);
}
}