使音频进度条的过渡更平滑
使音频进度条的过渡更平滑
我为我的网站中的音频对象制作了一个简单的自定义进度条。进度条工作正常,但我注意到它非常卡顿。我还注意到在像Facebook和YouTube这样的网站上,它们的进度条过渡看起来异常流畅(观看任何视频,你就会知道我在说什么)。
我认为解决这个问题的一个方法可能是使用一些巧妙的JavaScript和CSS,但最后它看起来很俗气,CPU负荷很重,而且实际上与之前完全一样。(这是我想出来的方法):
setInterval(function(){ var rect = elapsedContainer.getBoundingClientRect(); var percentage = audio.currentTime / audio.duration; elapsed.style.width = (percentage * rect.width) + "px"; }, 33); // 30帧每秒
.elapsed-container{ width: 100%; height: 10px; background: grey; } .elapsed{ left: 0; height: 100%; background: red; transition: width 33ms linear; }
任何帮助都会很感激,谢谢。
在这段代码中,使用了requestAnimationFrame来代替简单的setInterval。这个方法能够优化浏览器的渲染能力和资源使用,因此看起来更加流畅。
问题的解决方法是将代码中的setInterval换成requestAnimationFrame,并修改了CSS动画中的属性。
具体的代码如下:
let duration = 20000; let startTime = Date.now(); const elapsedContainer2 = document.querySelector('#con-2'); const elapsed2 = document.querySelector('#el-2'); function animate() { var rect = elapsedContainer2.getBoundingClientRect(); let percentage = (Date.now()-startTime) / duration; elapsed2.style.width = (percentage * rect.width) + "px"; requestAnimationFrame(animate); } requestAnimationFrame(animate);
同时,将CSS动画的属性从`left 33ms`改成了`width 0.16s`,因为在代码中我们修改的是div的宽度,而不是left属性,所以在CSS动画中应该进行相应的修改。`0.16s`接近于每秒60帧,这正是requestAnimationFrame试图实现的目标。
下面是修改后的CSS代码:
.elapsed{ left: 0; height: 100%; background: red; transition: width 0.16s linear; }
你可以在这个链接中查看修改后的代码和原始代码之间的区别:[codepen链接](https://codepen.io/tamango/pen/OJLxZNG)。值得注意的是,你的机器负载越高,差异就越明显。
问题:如何使音频进度条过渡更加平滑?
原因:使用setTimeout()方法设置动画帧率时,由于必须匹配指定帧率,可能会导致跳帧和闪烁。CSS过渡也可能与使用requestAnimationFrame方法的动画混合,导致动画效果不理想。
解决方法:使用requestAnimationFrame()方法替代setTimeout()方法。requestAnimationFrame回调允许计算机尽可能接近60fps,但可以根据负载调整帧率,使其比setTimeout()更高效。此外,去除CSS过渡,因为requestAnimationFrame已经以每秒60帧的速度进行动画,CSS过渡在这种情况下有点多余。
代码参考:
// 将setTimeout更改为requestAnimationFrame function progress_animation() { var rect = container.getBoundingClientRect(); var percentage = audio.currentTime / audio.duration; elapsed.style.width = (percentage * rect.width) + "px"; window.requestAnimationFrame(progress_animation); }; // 仅在相关时运行动画 document.getElementById("play").onclick = function(){ window.requestAnimationFrame(progress_animation); audio.play(); }
以上方法可以在这个链接中查看效果:https://jsfiddle.net/4ymch2jg/
这个方法对我来说效果更加平滑。
这是一个聪明的想法。但在我看来,仍然有一些不连贯。对于使用requestAnimationFrame的想法给予+1。
问题的出现原因:用户在使用音频进度条时,希望能够让进度条的过渡更加平滑,但由于用户可以随时暂停歌曲,因此无法准确计算进度条的距离。
解决方法:可以通过在最后10%的滑动条上使用移动平均数来添加人为平滑。使用speed = distance / time
来计算滑动条最后10%的平均速度,并显示一个估计值。可以创建一个可工作的示例来演示这个方法。
以下是整理后的文章:
音频进度条过渡平滑的问题及解决方法
在使用音频进度条时,用户希望能够让进度条的过渡更加平滑。为了解决这个问题,可以通过在最后10%的滑动条上使用移动平均数来添加人为平滑。
移动平均数是一种用于平滑数据的方法,它可以计算一系列数据点的平均值。在这个问题中,我们可以使用移动平均数来计算滑动条最后10%的平均速度,从而实现进度条的平滑过渡。
具体做法是,首先计算滑动条最后10%的距离和时间,并将它们代入公式speed = distance / time
中,得到平均速度。然后,使用这个平均速度来显示进度条的过渡效果。
为了更好地理解这个方法,我们可以创建一个可工作的示例来演示它。然而,唯一的问题是,由于用户可以随时暂停歌曲,我们无法准确计算进度条的距离。
总结起来,通过使用移动平均数来计算滑动条最后10%的平均速度,并显示一个估计值,可以实现音频进度条的平滑过渡。然而,由于用户可以随时暂停歌曲,无法准确计算进度条的距离。如果能够创建一个可工作的示例来解决这个问题,将会更加完善。