微信小程序滑动标尺/刻度尺

1,699 阅读1分钟

lm-blood-slide

10厘米尺度

<template>
    
<!-- 标尺 -->
<view id="ruler">
    <view class="cur_val">
        <image class="cur_num_icon" src="../../static/images/icon/cut_num.png" @tap="handleCut"/>
        <view class="cur_val_box">
            <view class="cur_val_text">{{curVal}}</view>
            <view class="cur_val_unit">{{unit}}</view>
        </view>
        <image class="cur_num_icon" src="../../static/images/icon/add_num.png" @tap="handleAdd"/>
    </view>

    <view class="scroll_box">
        <text class="cursor"></text>
        <scroll-view 
            scroll-x="true" 
            throttle="false"
            :scroll-left="salNum" 
            scroll-with-animation='true' 
            @scroll="bindscroll" 
        >
            <view class="scroller" 
            :style="{width:scaleWidth}">
                <text 
					v-for="(item,index) in count" 
					:key="index" 
					:class="((item+min)*step)% bigStep == 0?'big':((item+min)*step) % middleStep == 0?'middle':''"
                >
                    <text v-if="(item+min)%10==0" class="scale_txt">{{item + min}}</text>
                </text>
            </view>
        </scroll-view>
    </view>
</view>

</template>

<script>
    export default {
        name:'lm-blood-slide',
        props: {
            min:{
                type: Number,
                value: 0
            },
            max:{
                type: Number,
                value: 100
            },
            def:{
                type: Number,
                value: 0
            },
            unit:{
                type: String,
                value: ''
            },
            slideId:[String,Number]
        },
        	/**
        * 组件的初始数据
        */
        data() {
			return {				
				curVal: 0,//当前值
				step: 1,//步长 每格代表的值
				middleStep: 5,
				bigStep: 10,
                cellW: 10,
                scaleWidth:'0px',
                salNum:0,//scroll-left 
                count:0,//一共多少格
			}
        },
       
        created: function(){
            //组件实例被创建,此时不能使用setData
        },
        mounted(){
            console.log('mounted-ready-slice');
            //初始化 页面加载完成之后 onReady
            let _this = this;
            //一共有多少格
            let count = Math.ceil((_this.max - _this.min) / _this.step) + 1;
			this.count = count;
			this.scaleWidth = (count * _this.cellW) + 'px';//尺子总长度
			this.salNum = (_this.def - _this.min) / _this.step *  _this.cellW;			
            //初始值
            if(_this.slideId)
                _this.setVal(_this.salNum);
        },
         methods:{
            bindscroll: function(e){
                // 移动距离
                let left = e.detail.scrollLeft;
                this.setVal(left);
            },
            setVal: function(left){
                let curVal = Math.round( left / this.cellW / this.step ) + this.min;
                // let curVal = left / this.cellW / this.step  + this.min;
                this.curVal = curVal > this.max ? this.max : (curVal < this.min ? this.min : curVal)
                this.$emit('slide',this.curVal)
            },
            setDefVal: function(){
                //初始值
                var _this = this;
				this.salNum = (_this.curVal - this.min) * this.cellW * this.step
            },
            handleCut(){
                if(this.curVal== this.min) return
                let curVal = Number(this.curVal) - 0.1;
                this.curVal = curVal.toFixed(1)
                this.$emit('slide',this.curVal)
            },
            handleAdd(){
                if(this.curVal==this.max) return
                let curVal = Number(this.curVal) + 0.1;
                this.curVal = curVal.toFixed(1)
                this.$emit('slide',this.curVal)
            }
        }
    }
</script>

<style lang="scss" scoped>
$main_color:#4670C2;
$orange_color:#E9B45B;
view,text{
    box-sizing: inherit;
}
scroll-view{
    height: 100%;
}
.cur_val {
    @include flexCenter();
    padding-top: 60rpx;
    .cur_num_icon{
        width: 80rpx;
        height: 80rpx;
    }

    .cur_val_box{
        text-align: center;
        margin: 0 80rpx;
    }

    .cur_val_text{
        color: $text_color1;
         font-weight: bold;
        font-size: 120rpx;
    }

    .cur_val_unit{
        font-size: 40rpx;
        color: $text_color9;;
       
    }

}
.scroll_box {
    width: 90%;
    height: 200rpx;
    margin:48rpx auto 20rpx auto;
    overflow: hidden;
    position: relative;
}
.cursor {
    position: absolute;
    top: 0rpx;
    left: 50%;
    width: 6rpx;
    height: 140rpx;
    background: #E9B45B;;
    transform: translate(-50%,0);
    z-index: 9
}
.wrapper {
    width: 100%;
    margin-top: 0rpx;
}
.scroller{
    /*width: 1500rpx;*/
    // padding: 40rpx 47% 40rpx 50%;
    padding:0 47.5%  0 50%;
    /*transition: all 1s;*/
}
.scroller>text{
    font-size: 24rpx;
    color: $text_color6;
    display: inline-block;
    width: 9px;
    height: 20rpx;
    border-left: 1px solid $gray_color2;
    border-top: 1px solid #A2B7E0;
    vertical-align: top;
    position: relative;
}
.scroller>text:last-of-type{
    border-top: 0rpx;
}
.scroller .scale_txt{
    font-size: 32rpx;
    font-style: normal;
    position: absolute;
    left: -16px;
    bottom: -64px;
}
.scroller .middle{
    height: 40rpx;
}
.scroller .big{
    height: 60rpx;
    border-left: 1px solid $text_color9;
}
</style>

1厘米尺度

<template>
    
<!-- 标尺 -->
<view id="ruler">
    <view class="cur_val">
        <image class="cur_num_icon" src="../../static/images/icon/cut_num.png" @tap="handleCut"/>
        <view class="cur_val_box">
            <view class="cur_val_text">{{curVal}}</view>
            <view class="cur_val_unit">{{unit}}</view>
        </view>
        <image class="cur_num_icon" src="../../static/images/icon/add_num.png" @tap="handleAdd"/>
    </view>

    <view class="scroll_box">
        <text class="cursor"></text>
        <scroll-view 
            scroll-x="true" 
            throttle="false"
            :scroll-left="salNum" 
            scroll-with-animation='true' 
            @scroll="bindscroll" 
        >
            <view class="scroller" 
            :style="{width:scaleWidth}">
                <text 
					v-for="(item,index) in count" 
					:key="index" 
					:class="((item+min)*step)% bigStep == 0?'big':((item+min)*step) % middleStep == 0?'middle':''"
                >
                    <text v-if="(item+min)%10==0" class="scale_txt">{{(item + min)/10}}</text>
                </text>
            </view>
        </scroll-view>
    </view>
</view>

</template>

<script>
    export default {
        name:'lm-blood-slide',
        props: {
            min:{
                type: Number,
                value: 0
            },
            max:{
                type: Number,
                value: 100
            },
            def:{
                type: Number,
                value: 0
            },
            unit:{
                type: String,
                value: ''
            },
            slideId:[String,Number]
        },
        	/**
        * 组件的初始数据
        */
        data() {
			return {				
				curVal: 0.0,//当前值
				step: 1,//步长 每格代表的值
				middleStep: 5,
				bigStep: 10,
                cellW: 10,
                scaleWidth:'0px',
                salNum:0,//scroll-left 
                count:0,//一共多少格
			}
        },
       
        created: function(){
            //组件实例被创建,此时不能使用setData
        },
        mounted(){
            //初始化 页面加载完成之后 onReady
            let _this = this;
            //一共有多少格
            let count = Math.ceil((_this.max - _this.min) / _this.step) + 1;
            this.count = count;
			this.scaleWidth = (count * _this.cellW) + 'px';//尺子总长度
            this.salNum = (_this.def - _this.min) / _this.step *  _this.cellW;			
            //初始值
            _this.setVal(_this.salNum);
        },
         methods:{
            bindscroll: function(e){
                // 移动距离
                let left = e.detail.scrollLeft;
                this.setVal(left);
            },
            setVal: function(left){
                // let curVal = Math.round( left / this.cellW / this.step ) + this.min;
                let curVal = left / this.cellW / 10 / this.step  + this.min;
                curVal = Number(Number(curVal).toFixed(1));
                this.curVal = curVal > this.max / 10 ? Number(Number(this.max).toFixed(1)) : (curVal < this.min ? Number(Number(this.min).toFixed(1)) : curVal)
                this.$emit('slide',this.curVal)
            },
            setDefVal: function(){
                //初始值
                var _this = this;
				this.salNum = (_this.curVal - this.min) * this.cellW * this.step
            },
            handleCut(){
                if(this.curVal == this.min) return
                let curVal = Number(this.curVal) - 0.1;
                this.curVal = curVal.toFixed(1)
                this.$emit('slide',this.curVal)
            },
            handleAdd(){
                if(this.curVal == this.max/10) return
                let curVal = Number(this.curVal) + 0.1;
                this.curVal = curVal.toFixed(1)
                this.$emit('slide',this.curVal)
            }
        }
    }
</script>

<style lang="scss" scoped>
$main_color:#4670C2;
$orange_color:#E9B45B;
view,text{
    box-sizing: inherit;
}
scroll-view{
    height: 100%;
}
.cur_val {
   display: flex;
   justify-content:center;
    padding-top: 60rpx;
    .cur_num_icon{
        width: 80rpx;
        height: 80rpx;
        padding-top: 50rpx;
    }

    .cur_val_box{
        text-align: center;
        width: 360rpx;
    }

    .cur_val_text{
        color: $text_color1;
         font-weight: bold;
        font-size: 120rpx;
    }

    .cur_val_unit{
        font-size: 40rpx;
        color: $text_color9;;
       
    }

}
.scroll_box {
    width: 90%;
    height: 200rpx;
    margin:48rpx auto 20rpx auto;
    overflow: hidden;
    position: relative;
}
.cursor {
    position: absolute;
    top: 0rpx;
    left: 50%;
    width: 6rpx;
    height: 140rpx;
    background: #E9B45B;;
    transform: translate(-50%,0);
    z-index: 9
}
.wrapper {
    width: 100%;
    margin-top: 0rpx;
}
.scroller{
    /*width: 1500rpx;*/
    // padding: 40rpx 47% 40rpx 50%;
    padding:0 47%  0 50%;
    /*transition: all 1s;*/
}
.scroller>text{
    font-size: 24rpx;
    color: $text_color6;
    display: inline-block;
    width: 9px;
    height: 20rpx;
    border-left: 1px solid $gray_color2;
    border-top: 1px solid #A2B7E0;
    vertical-align: top;
    position: relative;
}
.scroller>text:last-of-type{
    border-top: 0rpx;
}
.scroller .scale_txt{
    font-size: 32rpx;
    font-style: normal;
    position: absolute;
    // top: -30rpx;
    left: -6rpx;
    bottom: -64rpx;
}
.scroller .middle{
    // height: 32rpx;
    height: 40rpx;
}
.scroller .big{
    height: 60rpx;
    border-left: 1px solid $text_color9;
}
</style>
<lm-blood-slide 
    id="rule" 
    :slideId="id"
    :min="0" :max="330"
    :def="parmas.bloodSugar" 
    unit="mmol/L"
    name="bloodSugar"
    @slide="(val)=>setParmas(val,'bloodSugar')"
  ></lm-blood-slide>