vue实现进度条,vue 进度条
这篇文章主要介绍了某视频剪辑软件歌曲进度条演示,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
注意这个不是脚手架创建的项目是一个引用vue。j写的超文本标记语言文件,直接粘到一个超文本标记语言文件就能用了,我的音乐链接隔一段时间会失效,需要自己准备音乐
有拖动和点击切换播放进度的功能
演示图片
代码
!声明文档类型
html lang=en
头
meta charset=UTF-8
meta http-equiv= X-UA-Compatible content= IE=edge
meta name= viewport content= width=device-width,initial-scale=1.0
标题文档/标题
/头
身体
div id=应用程序
audio ref= audio ref autoplay @ can play= can play @ time update= update /audio
按钮@click=播放播放/按钮
按钮@click=暂停暂停/按钮
div class=进度包装
span class= time time-l { format time(当前时间)} }/span
div class=进度条包装
cpn:进步=进步
@ progress-changing= onProgressChanging
@ progress-changed= progress changed
/cpn
/div
span class= time time-l“{ format time(duration)} }/span
/div
/div
!-子组件-
模板id=myCpn
div class=进度栏
!-后面黑色的一条-
div class= bar-inner @ click=单击进度
!-已经播放的区域-
div class= progress :style= progress style ref= progress
/div
!- btn -
div class= progress-BTN-wrapper :style= BTN风格 @触摸开始。防止默认= onTouchStart
@触摸移动。防止default= onTouchMove @ touch end。防止默认= onTouchEnd
div class=progress-btn/div
/div
/div
/div
/模板
脚本src=././js/vue.js/script
脚本
audioEl=null
const progressBtnWidth=16
//子组件
const cpn={
模板:" #myCpn ",
道具:{
进度:{
类型:数量,
默认值:0
}
},
data() {
返回{
偏移量:0
}
},
已安装(){
},
已创建(){
this.touch={}
},
计算值:{
progressStyle() {
返回“宽度:${this.offset}px”
},
btnStyle() {
//控制台。日志( FDS );
return ` transform:translate 3d($ { this。offset } px,0,0)`
},
},
观察:{
进度(新进度){
//进度条宽度
常量栏宽=这个.$ El。客户端宽度-进度btnwidth
这个。偏移量=条形宽度*新进度
}
},
方法:{
onTouchStart(e) {
//控制台。日志(e);
这个。触摸。x1=e .更改的触摸次数[0].clientX
//黄色进度条初始宽度
this.touch.beginWidth=this .$refs.progress.clientWidth
控制台。日志(这个。触摸);
},
onTouchMove(e) {
//控制台。日志(e);
//x偏移量
const delta=e.changedTouches[0].clientX - this.touch.x1
//之前的宽度这次拖动增加的偏移量=应有的黄条长度
const temp宽度=this。触摸。开始宽度增量
//再拿到酒吧宽度
常量栏宽=这个.$ El。客户端宽度-进度btnwidth
//黄条长度/barwidth=进度现在应该有的进度
常数进度=临时宽度/条形宽度
this.offset=条宽*进度
这个$emit(进度更改,进度)
//console.log(tempWidth ,临时宽度);
//console.log(barWidth ,条宽);
//console.log(progress ,进度);
},
onTouchEnd(e) {
//控制台。日志(e);
常量栏宽=这个.$ El。客户端宽度-进度btnwidth
常数进度=这个.$参考文献。进步。客户宽度/条形宽度
这个$emit(进度-已更改,进度)
},
//点击进度条
单击进度(五)
//控制台。日志( FDS );
控制台。log( getBoundingClientRect),this .$ El。getboundingclientrect());
const rect=this .$el.getBoundingClientRect()
//黄条应有的宽度
const offsetWidth=e . pagex-rect。x
常量栏宽=这个.$ El。客户端宽度-进度btnwidth
常数进度=偏移宽度/条形宽度
这个$emit(进度-已更改,进度)
console.log(offsetWidth)
}
},
}
const app=new Vue({
埃尔: #app ,
数据:{
内容:"美国食品和药物管理局",
src: https://music . 163 . com/song/media/outer/URL?id=1463165983.mp3 ,
当前时间:0,
持续时间:0,
isplay:假的,
progressChanging : false
},
组件:{
时空系统咨询委员会主网(CCSDS原理网的缩写)
},
已安装(){
这个. nextTick(()={
audioEl=this .$refs.audioRef
audioEl.src=this.src
//默认暂停
audioEl.pause()
})
},
计算值:{
进度(){
返回这.当前时间/这.持续时间
console.log(progress ,this。当前时间/这个。持续时间);
},
},
方法:{
播放(){
audioEl.play()
this.isplay=true
},
暂停(){
audioEl.pause()
this.isplay=false
//控制台。log();
},
canplay(e) {
//控制台。日志(123456);
控制台。日志(e);
这个持续时间=e .目标持续时间
},
更新(e) {
如果(!this.progressChanging){
这个。当前时间=e .目标。当前
}
},
onProgressChanging(e) {
//控制台。log( onProgressChanging ,e);
this.progressChanging=true
//实时修改当前时间值
这个。当前时间=这个。持续时间*
},
progressChanged(e){
//控制台。日志(e);
this.progressChanging=false
音频El。当前时间=这个。当前时间=这个。持续时间*
如果(!this.isplay){
控制台。日志(-);
audioEl.play()
}
},
格式时间(间隔){
//间隔向下取整
间隔=间隔 0
//不足两位的话就向前填充一个0
设分钟=((interval/60 0) )
让秒=((间隔% 60 0) )
设len=分钟。长度
for(;镜头2;len ) {
分钟=0 分钟
}
len=秒。长度
for(;镜头2;len ) {
秒=0 秒
}
返回“${分钟}:${秒钟}”
},
},
})
/脚本
/body
风格
#app {
宽度:100%;
}。进度包装器{
显示器:flex
宽度:80%;
填充:10px 0;
对齐-项目:居中;
边距:0自动;
}。时间{
宽度:40px
flex:0 0 40px;
字体大小:8px
边距:0自动;
填充:0 8px
}。时间我{
文本对齐:左对齐;
}。时间我{
文本对齐:右对齐;
}。进度栏包装器{
flex:1;
}
/* 子组件样式*/。进度栏{
高度:30px
}。内部酒吧{
位置:相对;
top:11px;
高度:8px
背景色:rgba(87,82,82,0.062);
边框半径:5px
}。进度{
位置:绝对;
身高:100%;
背景色:rgb(238,238,136);
}。进度BTN包装器{
位置:绝对;
左:-8px;
top:-11px;
宽度:30px
高度:30px
}。进度-btn {
位置:相对;
top:7px;
左:7px
框大小:边框-框;
宽度:16px
高度:16px
边框:3px纯色rgb(189,189,218);
边界半径:50%;
背景:rgb(123,192,212);
}
/风格
/html
解说
https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent
中间的进度条是进度条组件,黑色背景是进度的总长度,左边的黄色条是当前播放进度,中间的滑块可以左右拖动,进度条可以手动更改。在播放的过程中,进度条会变长,滑块向右偏移,可以左右拖动滑块。拖动也会改变播放进度,左边的时间也会改变。
实现播放的过程,进度条也会播放组件的状态。如何决定?可以通过进度来决定,组件的任何状态都可以根据进度来决定。父组件以数字形式传递进度。
根据进度计算btn的位置和进度黄色条的宽度。宽度可以用一个数据偏移量来表示(定义一个数据),然后听进度。
https://cn.vuejs.org/v2/api/#vm-el
知识获取根DOM元素
观察:{
进度(新进度){
//进度条宽度
常量栏宽=this。$ El . client width-progress btnwidth
//偏移量
this . offset=bar width * new progress
}
}
当然可以用computed的知识,但是要注意一开始用computed是得不到el的宽度的。computed一上来就计算一次,模板渲染的时候就访问offset,然后计算一次el的宽度。此时组件没有挂载,所以无法获取;如果你看的话,进度实际上在变化的时候已经渲染好了,所以clientWidth可以得到。另外,因为后面要处理一些逻辑,所以更倾向于写逻辑,要用watch来实现。
偏移后,我们必须映射dom,并为黄色进度条和btn设置动态样式。
两者的样式都是根据偏移量计算的,
计算值:{
progressStyle(){
return `width: ${this.offset}px
},
btnStyle() {
return ` transform:translate 3d($ { this . offset } px,0,0)`
}
},
现在根据偏移量计算它的样式。我们接受进步的特性。当外部进度发生变化时,根据进度计算其偏移量。有了偏移,样式可以改变。
怀疑flex 0 0 40px和width的效果差不多,但是在某些情况下,flex布局会被挤压或者折叠,导致宽度被挤压,所以设置width可以保证我们的宽度不会改变。
这是为了监控canplay事件。
父组件计算属性播放进度:播放时间/总时间。总时间已经获得,播放时间可以通过一个事件来监控:timeupdate。
目前的效果
你可以看到这是秒数。您需要格式化时间并定义一个工具函数。
中断的功能代码化https://www.jianshu.com/p/2975c25e4d71生活:自动执行的功能代码化
和位操作,https://www.jianshu.com/p/a3202bc3f7a4.
一个问题:为什么xxx.yyy0等于xxx?OR运算符为什么可以有四舍五入的功能?
知识的Padstart方法
格式时间函数
格式时间(间隔){
//间隔向下舍入
间隔=间隔 0
//如果少于两位数,则向前填充一个0。
const minute=((interval/60 0) )。padstart(2,“0”)
const second=((interval % 60 0) )。padstart(2,“0”)
return “{ minute }:{ second }”
}
但是不能用来识别这个padstart方法。
所以我得自己写。
格式时间(间隔){
//间隔向下舍入
间隔=间隔 0
//如果少于两位数,则向前填充一个0。
设分钟=((interval/60 0) )
让second=((interval % 60 0) )
设len=分钟.长度
for(;len2len ){
分钟=0 分钟
}
len=秒.长度
for(;len2len ){
秒=0 秒
}
return “{ minute }:{ second }”
}
接下来,写进度条的交互逻辑。
支持拖动和单击
在移动端,常见的是OntouchStart OntouchMove Ontouchend
https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent
知识阻止修改器
向滑块添加三个事件。
方法:{
onTouchStart(e) {
console . log(e);
},
onTouchMove(e) {
console . log(e);
},
onTouchEnd(e) {
console . log(e);
}
},
你需要两条信息,一是知道它点击了哪里,也就是说知道它的横坐标是什么。以及左侧进度条的宽度(偏移量)。
[screenX clientX pageX概念
因为执行touchmove时也需要获取横坐标的位置,所以可以将数据绑定到一个可以共享的对象上,在创建的hook函数中定义一个对象。
已创建(){
this.touch={}
},
给了黄条一个裁判之后
onTouchStart(e) {
//console . log(e);
this . touch . x1=e . changed touches[0]。clientX
//黄色进度条的初始宽度
this.touch.beginWidth=this。$refs.progress.clientWidth
console . log(this . touch);
},
onTouchStart(e) {
//console . log(e);
this . touch . x1=e . changed touches[0]。clientX
//黄色进度条的初始宽度
this.touch.beginWidth=this。$refs.progress.clientWidth
console . log(this . touch);
},
onTouchMove(e) {
//console . log(e);
//x偏移
const delta=e.changedTouches[0]。clientX-this.touch.x1
//上一个宽度此拖动增加的偏移量=黄色条的长度。
const temp width=this . touch . begin width delta
//再次获取barWidth
常量栏宽=this。$ El . client width-progress btnwidth
//黄条长度/条宽=进度现在应该有进度了。
常数进度=tempWidth/barWidth
this.offset=条宽*进度
//console.log(tempWidth ,temp width);
//console.log(barWidth ,bar width);
//console.log(progress ,进度);
},
我们来整理一下。最终目的是得到offset,offset,由进度和barWidth决定。这里怎么算进度?你需要得到当前黄色条的宽度除以总宽度。黄色条的宽度是初始宽度,也就是这张幻灯片的X距离。那么barWidth的获取就简单了,然后就可以计算了。
你觉得没必要吗?黄色条的原始宽度正好是这张幻灯片的长度。为什么要算进步?因为要让外界知道歌曲的进度变了,只需要让它们对应起来就可以了。最后,有必要修改音频。这是用父组件做的,现在只是拖动,所以需要发送事件。这里有两个自定义事件。进度改变事件表示手指仍在拖动,没有离开。当手指离开时,将分发一个进度变化来传播新的进度。
实时修改currentTime的值
这是拖动时修改currentTIme的时间,修改音乐的时间是松开手的时候。
但是暂停的时候发现可以拖,玩的时候发现拖是有问题的。
优化:换的时候,如果是暂停效果就让他放。这时候就需要定义一个isplay在点击播放暂停时翻转。
现在,让我们改变错误。玩的时候拖进度会有问题。为什么?我们通过监控进程变化来修改当前时间。这个currentTime一旦改变,progress会根据currentTime进行新的计算,然后发送给子组件,子组件就进入这个逻辑。
Offset将再次进行计算,
最后,它将在这里介绍
你应该在更新的时候做一些控制,在改变的过程中加一个标志位。
也就是说,在更新函数中,如果改变是拖动,就不要修改currentTime。在改变的过程中,认为进度条发生了变化。他修改进度条的优先级高,自己玩造成的更改currentTime的优先级相对低。
没关系。
除了拖动,我们还想点击它跳到相应的位置,
webapi - getBoundingClientRect方法返回元素的大小及其相对于视口的位置(获取短的一个)。
用pagex(页面x)获取长的那一条
单击鼠标按钮[
//console.log(fds ):
控制台。log( getboundingclientrect ,this).$ El。getboundingclientrect());
const rect=此. el.getBoundingClientRect()
//黄条应有的宽度
常数偏移宽度=e . pagex-rect。x
const barWidth=this .$ El。客户端宽度-进度BTN wdh-客户端宽度-进度
常数进度=偏移宽度/条形宽度
这一点. emit(progress-changed ,进度)
控制台。日志(偏移宽度)
}
到此这篇关于视图(视图)歌曲进度条演示文稿的文章就介绍到这了,更多相关视图(视图)歌曲进度条内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。