本来吧,像这种身高、体重的选择,我感觉一个数字滚轮就很不错,奈何UI给我出难题非要做一个刻度尺。
思路
这刻度尺不就是一堆竖杠,每个竖杠直接间隔相同,并且间隔和数值匹配起来嘛。这样想实现起来就容易了,利用微信小程序scroll-view组件实现滑动效果,竖杠用for循环,我这里对身高体重的精度是直接到整数的,所以间隔每个竖杠直接间隔的数值是1,间距可以自己订。
但是。。。。。
做到一半发现还有一个刻度指针,这才是重点,要让指针指向的刻度值和数值匹配,这就需要你上边设置的刻度间隔必须准确
直接上代码
wxml:
<view class="flex-col self-center section_8 space-y-8">
<view class="flex-col section_9 space-y-8">
<view class="flex-row justify-evenly items-center self-center section_10">
<text class="font_2">身高:</text>
<text class="font_4 text_6">{{basicInfo.height}}</text>
<text class="font_5 text_7">cm</text>
</view>
<view class=" section_11 space-y-4" style="height: 150rpx">
<view class="cur">
<view class="cur_val" style="margin-left: 155px;"></view>
</view>
<scroll-view scroll-x="true" scroll-left="{{heightSalNum}}" scroll-with-animation='true' catchscroll="bindscroll" throttle="{{false}}">
<view style="background: white; justify-content: center; align-items: flex-start; display: inline-flex">
<view class="{{index%10 == 0 ? 'cursor_lang' : 'cursor'}}" wx:for="{{300}}" wx:key="index">
<view wx:if="{{(index)%10==0}}" class="cursor_text">{{index}}</view>
</view>
</view>
</scroll-view>
</view>
</view>
cur是指针容器,因为我给他规定了宽度是310px,所以给他的子元素也就是指针给了一个距离左边155px,让他居中,当然你也可以用简单点的方式,比如flex
scroll-view是刻度容器,scroll-left指定起始位置,里边使用for循环做了300个刻度,没10个显示刻度值
css:
.flex-col {
display: flex;
flex-direction: column;
}
.flex-row {
display: flex;
flex-direction: row;
}
.justify-evenly {
justify-content: space-evenly;
}
.items-center {
align-items: center;
}
.self-center {
align-self: center;
}
.section_9 {
width: 310px;
padding-top: 16.67rpx;
background-color: #ffffff;
overflow: hidden;
border-top: solid 2.08rpx #d4d4d4;
}
.space-y-8>view:not(:first-child),
.space-y-8>text:not(:first-child),
.space-y-8>image:not(:first-child) {
margin-top: 16.67rpx;
}
.section_10 {
padding: 8.33rpx 0;
background-color: #ffffff;
overflow: hidden;
width: 197.92rpx;
}
.font_2 {
font-size: 29.17rpx;
font-family: HarmonyOS Sans SC;
line-height: 27.08rpx;
color: #000000e6;
}
.font_4 {
font-size: 37.5rpx;
font-family: HarmonyOS Sans Condensed;
line-height: 27.08rpx;
color: #22c1b1;
}
.text_6 {
line-height: 28.13rpx;
}
.font_5 {
font-size: 33.33rpx;
font-family: HarmonyOS Sans SC;
line-height: 18.75rpx;
color: #000000e6;
}
.text_7 {
line-height: 17.71rpx;
}
.section_11 {
background-color: #ffffff;
overflow: hidden;
position: relative;
}
.space-y-4>view:not(:first-child),
.space-y-4>text:not(:first-child),
.space-y-4>image:not(:first-child) {
margin-top: 8.33rpx;
}
.cur {
position: absolute;
width: 310px;
height: 38px;
z-index: 10;
display: flex;
/* justify-content: center; */
pointer-events:none;
}
.cur_val {
width: 0px;
border: 0.50px #22c1b1 solid;
}
.cursor {
width: 10px;
height: 24px;
border-left: 1px #D9D9D9 solid
}
.cursor_lang {
width: 10px;
height: 32px;
border-left: 2px #D9D9D9 solid
}
.cursor_text {
color: #B3B3B3;
font-size: 12px;
font-family: HarmonyOS Sans SC;
font-weight: 400;
line-height: 12px;
word-wrap: break-word;
display: flex;
justify-content: center;
margin-top: 80rpx;
width: 80rpx;
margin-left: -40rpx;
}
js:
this.setData({
heightSalNum: height * 10 - 155,
})
这里计算其实位置:
height是你后台穿过来的身高,因为我每个刻度间隔设置的是10px并且指针的位置在距离左侧155px的位置,所以得出公式 height * 10 - 155
像这样
scroll-view的起始位置,移动距离等等都是基于像素,也就是你得到的值都是像素
比如当我们的值是177时,scroll-view的起始位置(像素)就因该是177*10(我们设置的每个空的像素),也就是起始位置是1770px
此时得到了scroll-view的起始位置,但是由于scroll-view的起始位置参照的是元素最左侧和位于元素中间的指针位置差了155px,起始位置为1770px的时候指针位置就成了1770px + 155px,指针指向的刻度也成了(1770px + 155px)/10
所以在这我们需要从起始位置减去指针和起始位置的间距
最后就得出了上边的公式:height * 10 - 155
//身高卡尺
bindscroll: function (e) {
// 移动距离
let left = e.detail.scrollLeft;
let curVal = Math.round((left + 155) / 10);
this.setData({
['basicInfo.height']: curVal
})
},
道理和上边一样,上边是从值变为像素,这里需要从像素变成值。
left是移动距离(像素),移动距离的参照同样是最左边,所以对齐刻度要在这加上155,此时就是指针指定刻度在这个scrollview中的所在像素
使用这个像素除以10,得到的就是身高的值
扩展:
我的理解按这样计算每个空格间隔是10px,代表1cm,是不是没1px就代表0.1cm,那么不进行取整,保留一位小数的话,能不能得出精确到一位小数的身高?
本来想做成组件的,由于不想写了就不做了,想做的小伙伴可以试着写一下