<template>
<view class="container">
<view class="dialog-box">
<view class="active-box">
<view class="num">
<text>{{ num }}</text>
</view>
</view>
<div
class="scroll-view"
@touchstart="touchtStarEvent"
@touchmove="touchMoveEvent"
@touchend="touchEndEvent"
>
<view class="box" :style="'left:' + scrollLeft + 'px'">
<view
v-for="(item, index) in selectorNum"
:key="index"
class="seize-seat"
:style="{ width: boxRpx + 'rpx' }"
>
<text
:style="{ width: boxRpx + 'rpx', left: -boxRpx / 2 + 'rpx' }"
>{{ item + 1 }}</text
>
</view>
</view>
<view class="active"></view>
</div>
</view>
</view>
</template>
<script>
export default {
data() {
return {
selectorNum: 30,
num: 6,
scrollLeft: 0,
touchtStart: 0,
boxRpx: 50,
boxWidth: 0,
throttleStatus: false,
};
},
created() {
const screenWidth = 750 / uni.getSystemInfoSync().screenWidth;
const boxWidth = (this.boxWidth = parseInt(this.boxRpx / screenWidth));
this.scrollLeft = -(this.num - 1) * boxWidth;
},
methods: {
touchtStarEvent(e) {
this.touchtStart = e.changedTouches[0].clientX;
},
touchMoveEvent(e) {
const clientX = e.changedTouches[0].clientX;
const w = clientX - this.touchtStart;
this.throttle(() => {
this.scrollLeft += w;
this.touchtStart = clientX;
});
},
touchEndEvent() {
const { scrollLeft, boxWidth, selectorNum } = this;
const diff = Math.abs(scrollLeft) % boxWidth;
if (diff > boxWidth / 2) {
this.scrollLeft = scrollLeft - (boxWidth - diff);
} else {
this.scrollLeft = scrollLeft + diff;
}
if (this.scrollLeft > 0) {
this.scrollLeft = 0;
}
if (this.scrollLeft < -(selectorNum - 1) * boxWidth) {
this.scrollLeft = -(selectorNum - 1) * boxWidth;
}
this.num = Math.ceil(Math.abs(this.scrollLeft / boxWidth) + 1);
},
throttle(fn, t = 10) {
if (this.throttleStatus) return;
this.throttleStatus = true;
fn();
setTimeout(() => {
this.throttleStatus = false;
}, t);
},
},
};
</script>
<style scoped lang="scss">
.container {
position: fixed;
z-index: 9999;
left: 0;
top: 20%;
.dialog-box {
position: relative;
padding: 28rpx 56rpx;
background-color: #fff;
border-radius: 20rpx;
.active-box {
.num {
line-height: 120rpx;
color: #6672fc;
font-size: 24rpx;
width: 100%;
text-align: center;
}
}
.scroll-view {
position: relative;
width: 600rpx;
height: 200rpx;
white-space: nowrap;
overflow: hidden;
.active {
position: absolute;
z-index: 9;
top: 20rpx;
left: calc(300rpx - 2rpx);
width: 8rpx;
height: 56rpx;
border-radius: 5rpx;
background-color: #6672fc;
}
.box {
position: absolute;
z-index: 1;
top: 43rpx;
left: 0;
padding: 0 300rpx;
}
.seize-seat {
position: relative;
display: inline-block;
border-left: 4rpx solid #eee;
border-top: 4rpx solid #eee;
height: 30rpx;
box-sizing: border-box;
text {
position: absolute;
top: 43rpx;
font-size: 20rpx;
text-align: center;
color: rgba(0, 0, 0, 0.4);
}
&:last-child {
border-top: none;
}
}
}
}
}
</style>