有一个需求类似刻度尺,平时都是用组件,发现组件没有合适的,然后自己撸了一个,实现效果如下图:
代码如下:
<template>
<view class="ruler-container">
<view class="control">
<text class="temp-text">设定温度</text>
<view class="show-temp">
<view class="btn" @click="decrease">
<u-icon name="arrow-left" size="30"></u-icon>
</view>
<view class="value">{{ currentValue }}℃</view>
<view class="btn" @click="increase">
<u-icon name="arrow-right" size="30"></u-icon>
</view>
</view>
</view>
<view class="ruler-wrapper">
<scroll-view class="scroll-view" :scroll-x="true">
<view class="ruler">
<view
class="tick"
v-for="(item, index) in totalTicks"
:key="item"
:style="{
height: `${index % 10 === 0 ? longTickHeight : shortTickHeight}rpx`,
backgroundColor: `${currentValue + 1 > index ? activeTickColor : inactiveTickColor}`,
}"
>
<text
v-if="index % 10 === 0"
class="tick-value"
:style="{
color: `${currentValue >= index ? activeTickColor : inactiveTickColor}`,
right: `${index > 0 ? '8rpx' : ''}`
}"
>
{{ index }}
</text>
</view>
</view>
<!-- 将 pointer-wrapper 放置到 ruler 内部 -->
<view class="pointer-wrapper" :style="{ left: pointerPosition }">
<view class="pointer"></view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
currentValue: 0, // 当前刻度值
totalTicks: 101, // 总刻度数
longTickHeight: 40, // 长刻度线高度
shortTickHeight: 20, // 短刻度线高度
activeTickColor: "#fcb13c", // 激活刻度线颜色
inactiveTickColor: "#ddd", // 未激活刻度线颜色
scale: 10, // 刻度尺缩放比例 (每个刻度代表的像素值)
}
},
computed: {
// 计算指针位置
pointerPosition() {
return `calc(${(this.currentValue * this.scale) / 1.7}rpx)`
},
},
methods: {
increase() {
this.currentValue = Math.min(this.currentValue + 1, this.totalTicks - 1)
},
decrease() {
this.currentValue = Math.max(this.currentValue - 1, 0)
},
},
}
</script>
<style lang="scss" scoped>
.ruler-container {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
.control {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 40rpx;
gap: 40rpx;
.temp-text {
font-size: 38rpx;
}
.show-temp {
display: flex;
align-items: center;
.value {
font-size: 60rpx;
}
.btn {
font-size: 48rpx;
margin: 0 60rpx;
cursor: pointer;
}
}
}
.ruler-wrapper {
width: 600rpx;
position: relative;
height: 80rpx; // 调整高度,为刻度值预留空间
.scroll-view {
width: 100%;
height: 100%;
}
/deep/ .uni-scroll-view {
overflow: visible !important;
}
.ruler {
display: flex;
position: relative;
align-items: flex-end;
height: 100%;
.tick {
width: 10rpx; // 将 tick 宽度与 scale 一致
// height: 50rpx;
background-color: red;
margin-right: 5rpx; // tick 之间的间距
.tick-value {
font-size: 26rpx;
position: relative;
top: 40rpx; // 将刻度值显示在刻度线下方
transform: translateX(-50%);
}
}
}
.pointer-wrapper {
position: absolute;
top: 0;
// left: 50%;
// transform: translateX(-50%);
width: 10rpx;
height: 100%;
display: flex;
justify-content: center;
.pointer {
width: 0;
height: 0;
border-left: 16rpx solid transparent;
border-right: 16rpx solid transparent;
border-top: 24rpx solid #fcb13c;
}
}
}
}
</style>