adultDeviceApp/components/slider-common/slider_common.vue

207 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="main">
<movable-area class="showValue" :style="{background: sliderAreaBg}">
<view class="up" :style="{width: `${upButtonwidth}px`,background: `linear-gradient(90deg, ${sliderStartColor} 0%, ${sliderEndColor} 100%)` }"></view>
<movable-view class="sliderView" :out-of-bounds="false" :animation="animation" :x="sliderLength" @change="sliding" direction="horizontal" >
<view class="buttonPointer" :style="{backgroundColor: sliderButtonColor}"></view>
</movable-view>
</movable-area>
</view>
</template>
<script>
export default {
props: {
// 滑动条的背景颜色
sliderAreaBg: {
default: "#E9EDF5"
},
// 滑动条开始颜色
sliderStartColor: {
default: "#537DFC"
},
// 滑动条结束颜色
sliderEndColor: {
default: "#5DBEF2"
},
// 滑动托柄颜色
sliderButtonColor: {
default: "#ffffff"
},
// 定义滑动条分成几部分,类似于设置步长的效果
partsCount: {
default: 5
}
},
data() {
return {
bgOffset: 30,
sliderLength: 0,
animation: true,
showValue: 0,
sliderAreaWidth: 360 // 为了确保获取数据正常,设置默认值(适配一般移动端手机)
}
},
watch: {
sliderLength(newValue) {
this.sliderLength = newValue
this.showValue = this.getSliderCurrentPart()
}
},
computed: {
upButtonwidth() {
return this.sliderLength + this.bgOffset
}
},
methods: {
/**
* 滑动条进行滑动时执行
* @param {Object} item
*/
sliding(item) {
this.sliderLength = item.target.x
},
/**
* 获取滑动条的宽度信息; 为了适配不同页面长度,调用该函数会自动适配宽度
*/
getClientInfoBySelector() {
uni.createSelectorQuery().in(this).select('.showValue').boundingClientRect((rect) => {
this.sliderAreaWidth = rect.right - rect.left
this.showValue = this.getSliderCurrentPart()
}).exec()
uni.createSelectorQuery().in(this).select('.sliderView').boundingClientRect((rect2) => {
this.bgOffset = rect2.right - rect2.left
}).exec()
},
/**
* 设置滑动条的值
* @param {Object} sliderNewValue
*/
setSliderValue(sliderNewValue) {
this.animation = false
if(sliderNewValue > this.sliderAreaWidth) {
this.sliderLength = this.sliderAreaWidth
} else if (sliderNewValue < 0) {
this.sliderLength = 0
} else {
this.sliderLength = sliderNewValue
}
this.$nextTick(() => {
setTimeout(() => {
this.animation = true
}, 250)
})
},
/**
* 根据百分值设置进度条的值
* @param {Object} percentageValue 滑动条的百分值
*/
setSliderValueByPercentage(percentageValue) {
const decimalValue = parseInt(percentageValue) / 100
const newValue = (this.sliderAreaWidth * decimalValue).toFixed(2)
this.setSliderValue(parseFloat(newValue))
},
/**
* 根据 part 设置滑动条的长度同下区域的索引从0开始
*/
setSliderValueByPart(part) {
if(this.partsCount <= 0) return false
const onePatrWidth = Math.ceil(this.sliderAreaWidth / this.partsCount)
let setValue = onePatrWidth * part
// 优化选择两边的区域时,滑动条留空的问题
if((part + 1) == this.partsCount) {
setValue = this.sliderAreaWidth
} else if (part === 0) {
setValue = 0
} else {
setValue += onePatrWidth / 2
}
this.setSliderValue(setValue > this.sliderAreaWidth ? this.sliderAreaWidth : setValue)
},
/**
* 获取当前滑动到那个区域,根据 partsCount 的值表示第几个区域第一个区域返回0
*/
getSliderCurrentPart() {
if(this.partsCount <= 0) return false
const onePatrWidth = Math.ceil(this.sliderAreaWidth / this.partsCount)
let currentPart = 0
for (let i = 0; i < this.partsCount; i++) {
if(onePatrWidth * i <= this.sliderLength && this.sliderLength <= (i+1) * onePatrWidth) {
currentPart = i
break
}
}
return currentPart
},
/**
* 获取当前进度条移动距离
*/
getSliderWidth() {
return this.sliderLength
}
}
}
</script>
<style lang="scss" scoped>
.main {
width: 100%;
.showValue {
width: 100%;
height: 43rpx;
border-radius: 40rpx;
position: relative;
overflow: hidden;
margin: 0 auto;
.up {
width: 0%;
height: 100%;
position: absolute;
top: 0;
border-radius: 50rpx;
// background: linear-gradient(90deg, #537DFC 0%, #5DBEF2 100%);
}
.sliderView {
width: 35rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 0 12rpx;
}
.buttonPointer {
width: 35rpx;
height: 35rpx;
// background-color: white;
border-radius: 20rpx;
position: absolute;
}
}
}
</style>