进度条不顺滑

相信大多前端同学都自己写过音频、视频播放器,实现并不复杂。最近在小程序里,做了一个类似微博刷视频的需求。其中有一部分功能需要实现自定义进度条,在做完第一版之后发现进度条不顺滑,而后想查查网上看有没有什么好的方案,但最终没找到合适的。于是想看看微信小程序里的“微博”进度条如何,结果也是很生硬的动画,下面放了一个GIF,大家也可以自己搜索微信小程序的微博,找个视频看看效果。

常规方案

最终决定还是优化一下这个问题,先来捋一捋我们现有常规方案。

  • 监听TimeUpdate事件
  • 获取到当前播放时间,通过总时间计算进度百分比(currentTime / duration * 100)
  • 进度条width属性设置进度百分比

现有的方案是依赖事件获取当前播放时间,而这个事件大概在100~350毫秒触发一次,下面是我记录的小程序的事件对象队列。

[
{"detail":{"currentTime":0.10509,"duration":5.83}},
{"detail":{"currentTime":0.364527,"duration":5.83}},
{"detail":{"currentTime":0.613648,"duration":5.83}},
]

目前的问题在于,每次获取到事件,就会更新进度条,没有过度动画效果,非常的生硬,下面是一个5s总时长的进度条变化过程:

核心代码:

const onProgress = (e, $dom) => {
const updateFunc = (percent) => {
$dom.style.width = percent+'%'
}
let percent = ((e.detail.currentTime / e.detail.duration) * 100).toFixed(1)
updateFunc(percent)
}

transition

我们能很快想到用CSS的动画属性来做优化,想要灵活的控制,我选择使用 transition。transition可以定义动画执行时长,当我们改变width时,transition就会在规定时间内用动画的方式改变进度条宽度。首先动画执行时长一定要固定,并且在上一个执行时长结束之前最好不要再对width做改动,否则会导致冲突,动画会变得很奇怪。

  • 选择一个合理的transition执行时间:0.5s
  • 根据当前总时长,求出0.5s在进度条中所属百分比(100/duration/2)
  • 第一次TimeUpdate事件,就执行width改变,把进度条设置到0.5s的位置:width = 100/duration/2
  • 非第一次TimeUpdate事件,每当currentTime超过上一次进度条位置,就更新当前进度条百分比

听起来有点不好理解,我们画个图:

  1. 当第一次触发TimeUpdate事件,0.1336秒的时候(当然这个值随机的,可能是0.1~0.3之间),我们就设置width到0.5s的位置,这样进度条就和视频同步在运动,和真实的进度相差微弱的0.1秒。在动画执行的0.5s之间,UpdateTime也会有多次触发,
  2. 当某次UpdateTime的currentTime(0.7123s,这个值也是随机的)值大于上次执行的0.5s时,这个时候进度条的位置大概也在0.5s周围,我们再次触发下一个0.5s动画,也就是把width设置为1s的进度条位置
  3. 而后下个迭代currentTime>1s,width设置为1.5s,这样循环下去。

核心代码:

const playControl = {
percent: 0,
time: 0,
duration: 0,
first: true
}
const onProgress = (e, $dom) => {
const updateFunc = (percent) => {
playControl.percent = percent
playControl.time = e.detail.currentTime
$dom.style.width = percent+'%'
}
//当前视频进度第一次更新
if (playControl.first) {
playControl.duration = e.detail.duration
playControl.first = false
updateFunc(100 / e.detail.duration / 2)
} else {
let percent = ((e.detail.currentTime / e.detail.duration) * 100).toFixed(1)
if (percent - playControl.percent > 0 || e.detail.currentTime >= e.detail.duration) {
updateFunc(percent)
}
}
}

最终效果对比(PS:gif图效果有折损)

60s版本看起来和普通版差不多?把另一个60s挡住,来回对比,会发现还是有些区别。

解释起来还是有点费劲,还是没看明白?直接去看github仓库代码,代码可直接运行:https://github.com/zimv/smooth-progress

此方案在部分场景下会有短暂延迟,比如暂停、拖动等,​个人总体觉得利大于弊。

JS进度条顺滑版实现的更多相关文章

  1. js进度条源码下载—js进度条代码

    现在很多网站会用到进入网站特效,到网页没有加载完成的时候,会有一个loding特效,加载完了之后才能看到页面,今天就带着做一个js进度条效果,今天要做的效果是纯js进度条加载,没有用到框架,方便大家进 ...

  2. YprogressBar,html5进度条样式,js进度条插件

    简介 YprogressBar是一款基于HTML5的进度条插件. YprogressBar是一款轻量级进度条插件,使用方便,资源占用少,模仿好压的解压界面,带有数字显示,同时支持在描述中增加参数,以动 ...

  3. 简易js进度条

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 在vue项目中使用Nprogress.js进度条

    NProgress是一款在网页顶部添加细长进度条的工具,非常轻巧,使用起来也非常便捷,灵感来源于Google, YouTube. 1.安装 $ npm install --save nprogress ...

  5. js进度条实现

    1.先设置CSS样式(可自定义) /*#region 进度条 */ .progbar { background-color: #e1e1e1; width:auto; color: #222; hei ...

  6. 《C/C++实现Console下的加载进度条模拟[美观版]》

    前言   有时候我们会遇到在CMD或DOS控制台上出现的加载进度条,虽然不是如网页和软件写的美观.但确确实实也有着自己的特色.而且,一个好看的加载进度条也能增加用户使用控制台程序的体验!所以,拿来研究 ...

  7. js 进度条效果

    <!DOCTYPE html><html><head><meta charset="utf-8"><title>< ...

  8. js 进度条,可实现结束和重新开始

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  9. js进度条插件pace.js

    主要用到themes文件夹和pace.js文件

随机推荐

  1. MySQL 页完全指南——浅入深出页的原理

    之前写了一些关于 MySQL 的 InnoDB 存储引擎的文章,里面好几次都提到了页(Pages)这个概念,但是都只是简要的提了一下.例如之前在聊 InnoDB内存结构 时提到过,但当时的重点是内存架 ...

  2. Paxos 图解 (秒懂)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  3. Vue(11)组件化的基本使用

    前言 有时候有一组html结构的代码,并且这个上面可能还绑定了事件.然后这段代码可能有多个地方都被使用到了,如果都是拷贝来拷贝去,很多代码都是重复的,包括事件部分的代码都是重复的.那么这时候我们就可以 ...

  4. 学Java,找对圈子,跟对人

    我大学学的是机械专业,到大四才决定要学Java,以后当一名程序员. 到现在,十几年过去了,我现在已经是一家上市公司的技术总监了,管理的技术团队有100多人.很庆幸当初了选择了学Java. 还记得当初学 ...

  5. Docker入门与进阶(下)

    Docker入门与进阶(下) 作者 刘畅 时间 2020-11-12 实验主机配置 系统centos7.5 主机名 ip 配置 应用 harbor-master 172.16.1.71 2核4G/60 ...

  6. js 动态设置 div 背景图片 并滚动显示

    var imgs =["../img/index/bgstyle/style1/index_top_bg2.jpg", "../img/index/bgstyle/sty ...

  7. css题库(含答案)

    tip:<为< 单选题 1.页面上的div标签,其HTML结构如下: <div id="father"> <p class="son&quo ...

  8. POJ 3126 Prime Path 简单广搜(BFS)

    题意:一个四位数的质数,每次只能变换一个数字,而且变换后的数也要为质数.给出两个四位数的质数,输出第一个数变换为第二个数的最少步骤. 利用广搜就能很快解决问题了.还有一个要注意的地方,千位要大于0.例 ...

  9. 【玩转 WordPress】基于 Serverless 搭建个人博客图文教程,学生党首选!

    以下内容来自「玩转腾讯云」用户原创文章,已获得授权. 01. 什么是 Serverless? 1. Serverless 官方定义 Serverless 中的 Server是服务器的意思,less 是 ...

  10. CentOS-Docker安装RabbitMQ(单点)

    这里注意获取镜像的时候要获取management版本的,不要获取last版本的,management版本的才带有管理界面. 获取镜像 $ docker pull rabbitmq:management ...