You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
4.8 KiB
214 lines
4.8 KiB
<template>
|
|
<div class="slider flex" id="slider" :style="{ width: `${width}px` }" ref="slider">
|
|
<div class="slider-left flex" :style="{ width: `${leftWidth}px` }" @touchend.stop="sliderTouch">
|
|
<div class="left" :style="{backgroundColor:backgroundColor}"></div>
|
|
</div>
|
|
<div class="slider-right flex" @touchend.stop="sliderTouch" :style="{ width: `${currentWidth-leftWidth}px` }">
|
|
<div class="right"></div>
|
|
</div>
|
|
<div class="block flex" :style="{backgroundColor:touch?blockOuterColor:'rgba(0,0,0,0)', left: `${leftWidth}px`}"
|
|
@click.stop="">
|
|
<div class="block-inner flex" :style="{backgroundColor:blockBackgroundColor}" @touchmove.stop.prevent="blockTouchMove" @touchend="blockTouchEnd" @touchstart="blockTouchStart">
|
|
<div class="block-inner-inner" :style="{backgroundColor:blockColor}">
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default{
|
|
props:{
|
|
min:{
|
|
type:Number,
|
|
default:0
|
|
},
|
|
max:{
|
|
type:Number,
|
|
default:0
|
|
},
|
|
value:{
|
|
type:Number,
|
|
default:0
|
|
},
|
|
width:{
|
|
type:Number,
|
|
default:0
|
|
},
|
|
ratio:{
|
|
type:Number,
|
|
default:1
|
|
},
|
|
direction:{
|
|
type:String,
|
|
default:'screenX'
|
|
},
|
|
backgroundColor:{ //滑块右侧背景条的颜色
|
|
type:String,
|
|
default:'#e9e9e9'
|
|
},
|
|
blockColor:{ //滑块颜色
|
|
type:String,
|
|
default:'#ffffff'
|
|
},
|
|
screenLeft:{ //slider距离左边距离
|
|
type:Number,
|
|
default:0
|
|
},
|
|
iosDirection:{
|
|
type:Number,
|
|
default:1
|
|
}
|
|
},
|
|
data(){
|
|
return{
|
|
oldToucesX:0,
|
|
leftWidth:0,
|
|
oldLeftWidth:0,
|
|
touch:false
|
|
}
|
|
},
|
|
mounted() {
|
|
|
|
|
|
},
|
|
methods:{
|
|
sliderTouch(e){
|
|
console.log(e)
|
|
let touches = e.changedTouches[0]
|
|
this.leftWidth = (touches[this.direction]||touches['clientX'])*this.ratio-this.screenLeft
|
|
this.leftWidth = this.leftWidth > this.currentWidth? this.currentWidth : this.leftWidth
|
|
this.leftWidth = this.leftWidth < 0? 0 : this.leftWidth
|
|
this.blockTouchEnd()
|
|
|
|
},
|
|
// 触摸开始
|
|
blockTouchStart(e) {
|
|
this.touch = true
|
|
this.oldLeftWidth = this.leftWidth
|
|
this.oldToucesX = e.changedTouches[0][this.direction]||e.changedTouches[0]['clientX'];
|
|
},
|
|
// 计算方向
|
|
blockTouchMove(e) {
|
|
let newToucesX
|
|
|
|
newToucesX= e.changedTouches[0][this.direction]||e.changedTouches[0]['clientX'];
|
|
|
|
this.leftWidth = this.iosDirection*(newToucesX - this.oldToucesX)*this.ratio+ this.oldLeftWidth
|
|
this.leftWidth = this.leftWidth > this.currentWidth? this.currentWidth : this.leftWidth
|
|
this.leftWidth = this.leftWidth < 0? 0 : this.leftWidth
|
|
|
|
},
|
|
// 结束触摸
|
|
blockTouchEnd(e) {
|
|
let current = this.leftWidth / this.currentWidth *this.max
|
|
const event = {detail:{value:current}}
|
|
this.$emit('change',event)
|
|
this.touch = false
|
|
},
|
|
colorRgb(string,opacity){
|
|
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
|
|
var sColor = string.toLowerCase();
|
|
if(sColor && reg.test(sColor)){
|
|
if(sColor.length === 4){
|
|
var sColorNew = "#";
|
|
for(var i=1; i<4; i+=1){
|
|
sColorNew += sColor.slice(i,i+1).concat(sColor.slice(i,i+1));
|
|
}
|
|
sColor = sColorNew;
|
|
}
|
|
//处理六位的颜色值
|
|
var sColorChange = [];
|
|
for(var i=1; i<7; i+=2){
|
|
sColorChange.push(parseInt("0x"+sColor.slice(i,i+2)));
|
|
}
|
|
return "rgba(" + sColorChange.join(",") +`,${opacity}`+")";
|
|
}else{
|
|
return sColor;
|
|
}
|
|
}
|
|
},
|
|
computed:{
|
|
blockOuterColor(){
|
|
return this.colorRgb(this.blockColor,0.4)
|
|
},
|
|
blockBackgroundColor(){
|
|
return this.colorRgb(this.blockColor,0.5)
|
|
},
|
|
currentWidth(){
|
|
return this.width - 40
|
|
}
|
|
},
|
|
watch:{
|
|
value:{
|
|
immediate:true,
|
|
handler(newVal,oldVal){
|
|
if(this.touch) return
|
|
|
|
this.leftWidth = newVal/this.max * this.currentWidth
|
|
this.leftWidth = this.leftWidth > this.currentWidth? this.currentWidth : this.leftWidth
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.flex{
|
|
/* #ifndef APP-NVUE */
|
|
display: flex;
|
|
/* #endif */
|
|
|
|
}
|
|
.slider{
|
|
position: relative;
|
|
flex-direction: row;
|
|
height: 40px;
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
}
|
|
.slider-left{
|
|
height: 40px;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
}
|
|
.left{
|
|
flex: 1;
|
|
height: 3px;
|
|
}
|
|
.slider-right{
|
|
height: 40px;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
}
|
|
.right{
|
|
height: 3px;
|
|
background-color: rgba(0,0,0,0.3);
|
|
flex: 1;
|
|
}
|
|
.block{
|
|
position: absolute;
|
|
height: 40px;
|
|
width: 40px;
|
|
border-radius: 20px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 999999;
|
|
}
|
|
.block-inner{
|
|
height: 20px;
|
|
width: 20px;
|
|
border-radius: 10px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
.block-inner-inner{
|
|
height: 10px;
|
|
width: 10px;
|
|
border-radius: 5px;
|
|
|
|
}
|
|
</style>
|
|
|