微信小程序 实现带刻尺度滑块

实现带刻度滑尺

wxml 布局

<view>
    <view class="value">{{value}}</view>
    <scroll-view scroll-x="true" bindscroll="bindscroll" scroll-left="{{scrollLeft}}">
        <canvas canvas-id="canvas-ruler" id="canvas-ruler"
                style="height: {{canvasHeight}}px; width: {{canvasWidth}}px;"></canvas>
    </scroll-view>
    <canvas canvas-id="canvas-cursor" id="canvas-cursor"></canvas>
</view>

wxss 样式

page {
    display: flex;
    flex-direction: column;
}

/* value */
.value {
    color: #48c23d;
    font-size: 100rpx;
    text-align: center;
    line-height: 140rpx;
}

/* value单位 */
.value:after {
    font-size: 16px;
    color: gray;
    content: 'mmhg';
    margin-left: 5px;
}

/* 画布 */
#canvas-ruler {
    width: 1000px;
    /*height: 80px;*/
    /*border: 1px solid #ccc;*/
}

/* 游标 */
#canvas-cursor {
    width: 100%;
    height: 40px;
    /*border: 1px solid #cc1;*/
}

js

var that;
var deltaX = 0;
var minValue = 1;
var app = getApp();
Page({
    data: {
        value: 0,
        canvasHeight: 80
    },

    onLoad: function (options) {
        that = this;
        // 绘制标尺
        that.drawRuler();
        // 绘制三角形游标
        that.drawCursor();
    },

    drawRuler: function() {

        /* 1.定义变量 */

        // 1.1 定义原点与终点,x轴方向起点与终点各留半屏空白
        var origion = {x: app.screenWidth / 2, y: that.data.canvasHeight};
        var end = {x: app.screenWidth / 2, y: that.data.canvasHeight};
        // 1.2 定义刻度线高度
        var heightDecimal = 50;
        var heightDigit = 25;
        // 1.3 定义文本标签字体大小
        var fontSize = 20;
        // 1.4 最小刻度值
        // 已经定义在全局,便于bindscroll访问
        // 1.5 总刻度值
        var maxValue = 200;
        // 1.6 当前刻度值
        var currentValue = 20;
        // 1.7 每个刻度所占位的px
        var ratio = 10;
        // 1.8 画布宽度
        var canvasWidth = maxValue * ratio + app.screenWidth - minValue * ratio;
        // 设定scroll-view初始偏移
        that.setData({
            canvasWidth: canvasWidth,
            scrollLeft: (currentValue - minValue) * ratio
        });

        /* 2.绘制 */

        // 2.1初始化context
        const context = wx.createCanvasContext('canvas-ruler');
        // 遍历maxValue
        for (var i = 0; i <= maxValue; i++) {
            context.beginPath();
            // 2.2 画刻度线
            context.moveTo(origion.x + (i - minValue) * ratio, origion.y);
            // 画线到刻度高度,10的位数就加高
            context.lineTo(origion.x + (i - minValue) * ratio, origion.y - (i % ratio == 0 ? heightDecimal : heightDigit));
            // 设置属性
            context.setLineWidth(2);
            // 10的位数就加深
            context.setStrokeStyle(i % ratio == 0 ? 'gray' : 'darkgray');
            // 描线
            context.stroke();
            // 2.3 描绘文本标签
            context.setFillStyle('gray');
            if (i % ratio == 0) {
                context.setFontSize(fontSize);
                // 为零补一个空格,让它看起来2位数,页面更整齐
                context.fillText(i == 0 ? ' ' + i : i, origion.x + (i - minValue) * ratio - fontSize / 2, fontSize);
            }
            context.closePath();
        }

        // 2.4 绘制到context
        context.draw();
    },

    drawCursor: function () {
        /* 定义变量 */
        // 定义三角形顶点 TODO x
        var center = {x: app.screenWidth / 2, y: 5};
        // 定义三角形边长
        var length = 20;
        // 左端点
        var left = {x: center.x - length / 2, y: center.y + length / 2 * Math.sqrt(3)};
        // 右端点
        var right = {x: center.x + length / 2, y: center.y + length / 2 * Math.sqrt(3)};
        // 初始化context
        const context = wx.createCanvasContext('canvas-cursor');
        context.moveTo(center.x, center.y);
        context.lineTo(left.x, left.y);
        context.lineTo(right.x, right.y);
        // fill()填充而不是stroke()描边,于是省去手动回归原点,context.lineTo(center.x, center.y);
        context.setFillStyle('#48c23d');
        context.fill();
        context.draw();
    },

    bindscroll: function (e) {
        // deltaX 水平位置偏移位,每次滑动一次触发一次,所以需要记录从第一次触发滑动起,一共滑动了多少距离
        deltaX += e.detail.deltaX;
        var value = (- deltaX / 10 + minValue).toFixed(1)
        if (value < 0.01) {
            value = 0;
        } else if (value >= 200.0) {
            value = 200.0;
        }

        // 数据绑定
        that.setData({
            value: value
        });
        // console.log(deltaX)
    },
});

转载至 https://my.oschina.net/huangxiujie/blog/865634

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值