前端实现滑动刻度尺效果,左右滑动刻度尺,对应的数据会发生改变,效果如下:
实现思路:使用vue2,进行数据绑定,即保证上方的数据实时更新,向右滑动刻度尺数值增加,向左减少。
1.写一个大的div盒子给固定宽度和高度;
2、在外层的div里嵌套一个div,设置超出父级div盒子的宽度,制作一张刻度尺的png图片作为子盒子的背景图,同时给父级设置scroll-y:auto;实现左至右滑动
3,写一个小的div即作为参照物的蓝色指针,通过父相自绝定位至中间、
4,js方法通过监听父级盒子左右滑动的滚动条并将至赋给视图中的数字,即可实现滑动刻度修改数值
具体代码实现如下:
<template>
<div class="loginTwo">
<div class="head">
<van-nav-bar title="完善信息" />
</div>
<div class="main">
<div class="form">
<p class="title">你的身高</p>
<div class="box">
<div class="text textA">{{ height }}</div>
<div class="outBox" ref="h_out" @scroll="handleHeight">
<div class="liningBox" ref="h_lin"></div>
</div>
<!-- 基准线 -->
<div class="vertical"></div>
</div>
<p class="title">你的体重</p>
<div class="box2">
<div class="text textB"> {{ weight }}</div>
<div class="outBox" ref="out" @scroll="handleWeight">
<div class="liningBox" ref="lin"></div>
</div>
<!-- 基准线 -->
<div class="vertical2"></div>
</div>
<div class="btn">下一步</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
w_scroll: 0,
h_scroll: 0,
}
},
mounted() {
this.$refs.out.scrollLeft = 300;
this.$refs.out.addEventListener('scroll', this.handleScroll, { passive: true });
this.$refs.h_out.scrollLeft = 300;
this.$refs.h_out.addEventListener('scroll', this.handleScroll, { passive: true });
},
computed: {
weight() {
if (this.w_scroll <= 30) {
return 30
} else {
return this.w_scroll
}
},
height() {
if (this.h_scroll <= 30) {
return 30
} else {
return this.h_scroll
}
}
},
methods: {
handleWeight() {
const scrollLeft = this.$refs.out.scrollLeft;
const w_distance = this.getFractionalScroll(scrollLeft, 1) * 200;
this.w_scroll = w_distance.toFixed(1)
},
handleHeight() {
const scrollLeft = this.$refs.h_out.scrollLeft;
const h_distance = this.getFractionalScroll(scrollLeft) * 300;
this.h_scroll = Math.round(h_distance)
},
getFractionalScroll(scrollLeft, val) {
if (val == 1) {
const scrollWidth = this.$refs.out.scrollWidth - this.$refs.out.clientWidth;
const fractionalScroll = scrollLeft / scrollWidth;
// return fractionalScroll.toFixed(3); // 设置小数点位数
return fractionalScroll; // 设置小数点位数
} else {
const scrollWidth = this.$refs.h_out.scrollWidth - this.$refs.h_out.clientWidth;
const fractionalScroll = scrollLeft / scrollWidth;
return fractionalScroll; // 设置小数点位数
}
},
},
}
</script>
<style lang="scss" scoped>
.head {
// padding-top: 20px;
height: 150px;
width: 100%;
background-color: #5B74FF;
}
.head::v-deep .van-nav-bar {
background-color: transparent;
}
::v-deep .van-nav-bar__title {
color: #ffffff;
font-weight: bold;
font-size: 18px;
}
::v-deep.van-hairline--bottom::after {
border-bottom-width: 0,
}
.main {
height: calc(100vh - 90px);
background-color: #ffffff;
position: relative;
}
.form {
position: absolute;
border-radius: 0 50px 0 0;
background-color: #ffffff;
top: -8%;
height: 100%;
width: 100%;
padding: 32px 18px 0;
}
.title {
font-size: 18px;
font-weight: 800;
color: #2A2A2A;
margin-bottom: 23px;
}
.outBox {
height: 35px;
overflow-x: scroll;
position: relative;
}
.liningBox {
width: 800px;
height: 35px;
background: url(../../assets/images/ruler.png)repeat-x;
}
.vertical {
position: absolute;
display: block;
width: 2px;
height: 40px;
background-color: #5B74FF;
left: 48%;
top: 37.2%;
}
.vertical2 {
position: absolute;
display: block;
width: 2px;
height: 40px;
background-color: #5B74FF;
left: 48%;
top: 37.2%;
}
.outBox::-webkit-scrollbar {
display: none;
}
.box {
padding: 32px 36px 90px;
text-align: center;
position: relative;
}
.box2 {
padding: 32px 36px 90px;
text-align: center;
position: relative;
}
.text {
font-size: 29px;
font-weight: 800;
color: #5B74FF;
margin-bottom: 6px;
}
.textA::after {
content: 'cm';
font-size: 12px;
font-weight: lighter;
color: #5B74FF;
}
.textB::after {
content: 'kg';
font-size: 12px;
font-weight: lighter;
color: #5B74FF;
}
.btn {
width: 300px;
height: 42px;
line-height: 42px;
background: #5B74FF;
border-radius: 21px;
text-align: center;
color: #ffffff;
font-size: 15px;
margin: 0 auto 12px;
}
</style>