小程序video虽然有自己的进度条,可是样式不好自定义,大多情况下会选择用slider组件来实现进度条功能,但slider组件同样存在样式不好自定义的问题,这里介绍一个使用movable-area + movable-view实现进度条的方法。
-
首先是wxml
<movable-area catchtouchmove="voidMethod" catchtap="tap"
class="progress-box" style="width:{{width}}px;height:10px">
<view class="bg-box">
<view style="width:{{value}}%" class="inner"></view>
</view>
<movable-view class="progress-dot" wx:if="{{showDot}}" x="{{value*width/100}}" bindtouchmove="touchmove" bindtouchend="touchend" direction="horizontal" bindchange="getCgh">
<view class="dot"></view>
</movable-view>
</movable-area>
movable-area的catchtouchmove绑定一个空函数,内部的滑动不会影响到外部,设置宽度为容器宽度,高度10像素的区域。内部bg-box的区域为了已播放部分深色显示。
movable-view则是内部滑块区域,里面的view是滑块的可见部分(为什么要把可拖动范围设置大点:因为滑块太小要手指刚好触到可见滑块才能滑动,被领导要求了),通过wxss定义好样式
.progress-box{
position: absolute;
/* background: #232; */
}
.progress-dot{
background: #ffffff00;
width: 70px;
height:40px;
display: flex;
justify-content: center;
align-items: center;
top: -15px;
z-index: 10;
left: -30px;
}
.dot{
background: #ffffff;
width: 8px;
height:8px;
border-radius: 100px;
}
.bg-box{
position: absolute;
width: 100%;
height: 2px;
top: 4px;
background-color: #ffffff22;
}
.bg-box .inner{
background:linear-gradient(to bottom,#ffffff,#666);
height: 100%;
}
.dot才是滑块的真正可见部分,完成后的滑块大概这个样子
滑块的if属性是为了控制视频暂停时才显示滑块,视频播放时不显示滑块。
然后是关键的js部分。这里进度条是作为组件使用的,所以播放进度和是否暂停需要由父组件传入
properties: {
value:{
type:Number,
value:0,
observer:function observe(){
var newVal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
}
},
showDot:{
type:Boolean,
value:false
}
},
定义下data
data: {
width: wx.getSystemInfoSync().windowWidth,
currX:0,
touch:false,
timer:0
},
这里需要注意一点,bindchange触发频率太高,没有状态,所以并不适合在bindchange中来控制视频进度,这里只在bindchange中记录进度条位置
//这是bindchange触发的函数
getCgh(e){
let {x}=e.detail
let {width}=this.data
let pecent=x/width*100
this.data.currX=pecent
},
真正实现视频进度拖动的是touchmove
tap(e){//点击区域的某处直接跳到那个进度
let {x}=e.detail
let {width}=this.data
let pecent=x/width*100
this.data.currX=pecent
this.triggerEvent('change',{value:pecent})
},
voidMethod(){
},
touchmove(e){
this.triggerEvent('changing',{value: this.data.currX})
// console.log(this.data.currX)
},
touchend(e){
this.triggerEvent('change',{value: this.data.currX})
},
先看下父组件如何调用的
<progress value="{{progress}}" bindchanging="showTime" showDot="{{isstop}}" bindchange="changeProgress" ></progress>
value就是视频当前进度,showDot是视频是否播放, bindchanging就是拖动进度条,bindchange是拖动结束。 这里showTime是在拖动进度条过程中显示时长的函数,等拖动结束再触发视频的进度改变。
在进度条组件json中配置一下,然后在父组件的usingComponents中配置一下,就可以在父组件使用了
{
"component": true,
"usingComponents": {}
}