likes
comments
collection
share

视频滑块和进度条不匹配

作者站长头像
站长
· 阅读数 20

✊不积跬步,无以至千里;不积小流,无以成江海

之前忙着实习忙着毕业,一转眼都三个月没更新博客了,中间无数次想着每周push自己写一篇还是因为各种接踵而来的事情耽误了。

感觉真的种下一棵树,不是十年前就是现在。博客的好习惯还是要坚持下来,水滴石穿。

这篇文章就分享实习期遇见的一个傻傻的bug,困扰了我将近两天,最后用非常简单的办法解决的。

bug描述

遇见的bug展示如下面这个视频,当视频长度过短时(比如10s),在大屏上(大于1920*1080)展示时,会出现滑钮跳转速度大于进度条这个bug。bug的原因,是因为滑钮是按1s计位跳动,进度条是逐步前进的。

解决bug后如下面这个视频,滑钮和进度条保持了一致的速度。

解决bug中的失败尝试

尝试的方法包括但不限于:

  • currentTimeduration的更新不同步:尝试在同一个set函数调用中同时更新这两个值,以确保它们总是在同一时间更新。
set((state) => ({
  currentTime: newCurrentTime,
  duration: newDuration,
}));
  • 浏览器的渲染延迟:减少不必要的渲染和状态更新。例如,使用React.memo或者useMemo来避免不必要的渲染。

  • setTimeline函数的异步性:你可以尝试使用 Zustand 的 getState 方法来立即获取最新的状态,而不是使用 get 方法。getState 方法会同步返回当前的状态,而不是返回一个函数。

const setTimeline = (value: number) => {
  const videoRef = get().videoRef;
  if (videoRef.current) {
    videoRef.current.currentTime = value;
    set((state) => ({
      currentTime: value,
      progressPercentage: (value / state.duration) * 100,
    }));
  }
};
  • 在css中分别修改滑块和进度条的动画,试图将两者动画保持一致

    1. 检查CSS样式:仔细检查与时间条相关的CSS样式是否正确,特别是对于input[type="range"]元素的样式。
    2. 更新 linear-gradient 样式:在 updateBackground 函数中已经设置了样式,但是这个更新可能没有覆盖所有浏览器的默认样式。
    3. 确保style应用正确:在React组件中直接使用样式对象时,检查样式没有被其他样式所覆盖。
    4. 确保进度条背景的是在更新的
  • 自己写一个按钮(取消掉原有样式并且覆盖掉)

首先,使用一个div容器来包裹整个组件,这样可以更方便地管理和应用样式。同时,通过CSS样式使按钮浮动在进度条的渐变颜色末端,使UI更加直观和易于操作。

为了实现这一效果,可以利用CSS的transition属性来控制背景颜色的渐变。具体来说,可以设置transition: background 0.1ms ease;,让渐变的step(每一步的变化)小于进度条的时间(以毫秒为单位)。这样可以在视觉上无缝展示视频播放的过程,提升视觉效果。

然而,这种方法也有其不足之处。由于按钮是使用div元素创建的,而进度条是通过<input>元素实现的,当用户拖动按钮时,交互体验可能并不是特别丝滑。这主要是因为divinput元素在拖动交互上的表现有所不同,可能会导致拖动时的跳动或卡顿,影响整体的操作体验。

  • 使用两个<input>标签

一个常见的思路是使用两个<input>标签,其中一个隐藏式进度条和一个隐藏式按钮。通过这种方式,理论上可以更好地将进度条和按钮进行分离管理,从而提升操作的精准度和视觉效果。然而,实际操作中我们发现这种方法会引入一些冗余。

具体来说,使用两个<input>标签虽然可以更细致地控制每个部分的样式和行为,但由于这两个标签实际上是重复的元素,反而增加了代码的复杂性和维护成本。每当视频进度发生变化时,需要同步更新这两个<input>标签的状态,确保它们显示的进度一致。这无形中增加了代码的臃肿程度和可能出现的同步问题。


在尝试用上面这个方法解决问题时,我发现一个有趣的现象:通过细致地控制动画时间的精度,可以有效地调节动画的变化速度。这个发现引导我进一步思考,其他的HTML元素是否也存在类似的精度控制机制。于是,我开始留意了input标签的相关特性。

该bug解决办法

令人惊喜的是,input标签确实提供了精度控制的属性。这种精度控制不仅限于时间,还可以应用于数值类型的输入。例如,使用step属性可以设置输入值的步进��允许开发者更精细地控制用户可以输入的数值范围和增量。

在input中添加step,控制精度为0.001,就可以让滑块前进单位为0.001s。测试后即使1s的视频放在大屏上,也不会出现滑块和进度条分离的情况了。

结语

谁能想到困扰一天多的代码,最后试遍了所有方法,居然是用一行代码解决的。

得到结论:还是要好好看文档。然后尽量尝试去分析问题到底出现在哪里,从文档中看是否能够解决这个问题。

(虽然很难通过文档就能够分析出来啦,经验base此刻占领了高地)

转载自:https://juejin.cn/post/7391703710487805987
评论
请登录