adultDeviceApp/components/slider-common/slider_common.vue

207 lines
4.8 KiB
Vue
Raw Normal View History

2024-06-25 11:08:20 +08:00
<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>