蚂蚁论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 38|回复: 0

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

[复制链接]

1923

主题

1

好友

1591

积分

管理员

Rank: 64Rank: 64Rank: 64Rank: 64

  • TA的每日心情
    奋斗
    2016-1-22 16:23
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    荣誉管理 论坛元老 热心会员 活跃会员 最佳新人 灌水之王

    发表于 7 天前 |显示全部楼层
    微信小程序实现带刻度尺滑块功能
    摘要: 与自带的slider不同的是,它是通过手势滑动标尺得到取值,而不是通过滑动滑块本身。
    效果图

    场景
    当一屏显示不下,例如年龄体重选择,金额选择等大区间需要的选择器,相比自带的picker要直观一些。
    思路:
    先画一个scrollView 2 装进canvas
    lineTo画刻度线段,lineTo+fill画出三角形游标,fillText描绘文本标签
    通过bindscroll监听刻度尺触摸事件
    渲染取值到页面
    基本布局


    lt;scroll-view scroll-x="true" bindscroll="bindscroll"gt;
      lt;canvas canvas-id="canvas" id="canvas"gt;lt;/canvasgt;
    lt;/scroll-viewgt;

    实现bindscroll方法


    bindscroll: function (e) {
      // deltaX 水平位置偏移位,每次滑动一次触发一次,所以需要记录从第一次触发滑动起,一共滑动了多少距离
      deltaX += edetaildeltaX;
      consolelog(deltaX)
    }

    描绘刻度


    const context = wxcreateCanvasContext('canvas-ruler');
    // 移动到原点
    contextmoveTo(origionx, origiony);
    // 画线到刻度高度
    contextlineTo(origionx, origiony - heightDecimal);
    // 设置属性
    contextsetLineWidth(1);
    // 描线
    contextstroke();
    // 描绘文本标签
    contextsetFontSize(fontSize);
    contextfillText('0', origionx - fontSize / 2, fontSize);
    contextdraw();

    遍历刻度


    for (var i = 0; i lt;= maxValue; i++) {
      // 开始一个路径,这条非常重要,否则会重复绘制之前的刻度n次,效果表现为页面加载很卡,lineWidth得到的线很粗
      contextbeginPath();
      // 绘制同上,不再赘述
      
      // 关闭一个路径,它是可选的,调用过了beginPath,不关闭也没有影响,保险起见,加上它
      contextclosePath();
    }

    切记要调用contextbeginPath();
    描绘游标


    drawCursor: function () {
        /* 定义变量 */
        // 定义三角形顶点 TODO x
        var center = {x: appscreenWidth / 2, y: 5};
        // 定义三角形边长
        var length = 20;
        // 左端点
        var left = {x: centerx - length / 2, y: centery + length / 2 * Mathsqrt(3)};
        // 右端点
        var right = {x: centerx + length / 2, y: centery + length / 2 * Mathsqrt(3)};
        // 初始化context
        const context = wxcreateCanvasContext('canvas-cursor');
        contextmoveTo(centerx, centery);
        contextlineTo(leftx, lefty);
        contextlineTo(rightx, righty);
        // fill()填充而不是stroke()描边,于是省去手动回归原点,contextlineTo(centerx, centery);
        contextsetFillStyle('48c23d');
        contextfill();
        contextdraw();
      }

    画带一个绿色的正三角形作为游标,注意游标是悬浮不动的,所以另起一个cancas来装它。当然它不是必须的,偷个懒ps一张三角形的png代替也无妨,甚至刻度其实也可以用lt;view style="background: gray; width: 2px;"gt;加绝对定位来生成的。
    定义刻度默认初值


    thatsetData({
        scrollLeft: (currentValue - minValue) * ratio
    });
    lt;scroll-view scroll-x="true" bindscroll="bindscroll" scroll-left="{{scrollLeft}}"gt;

    绑定scroll-left参数,相当于iOS里了UIScrollView的contentOffset,手动让偏移到默认初值对应的坐标位置。
    适配最小值
    当业务场景需要做数据验证,例如金额要gt;0,年龄要大于18岁等,就得适配极值。


    thatsetData({
        amount: Mathfloor(- deltaX / 10 + minValue)
    });

    同时要修正刻度线的x轴坐标


    // 22 画刻度线
    contextmoveTo(origionx + (i - minValue) * ratio, origiony);
    // 画线到刻度高度,10的位数就加高
    contextlineTo(origionx + (i - minValue) * ratio, origiony - (i % ratio == 0 63; heightDecimal : heightDigit));
    // 23 描绘文本标签
    contextfillText(i == 0 63; ' ' + i : i, origionx + (i - minValue) * ratio - fontSize / 2, fontSize);

    最终js代码


    var that;
    var deltaX = 0;
    var minValue = 1;
    var app = getApp();
    Page({
      data: {
        value: 0,
        canvasHeight: 80
      },
      onLoad: function (options) {
        that = this;
        // 绘制标尺
        thatdrawRuler();
        // 绘制三角形游标
        thatdrawCursor();
      },
      drawRuler: function() {
        /* 1定义变量 */
        // 11 定义原点与终点,x轴方向起点与终点各留半屏空白
        var origion = {x: appscreenWidth / 2, y: thatdatacanvasHeight};
        var end = {x: appscreenWidth / 2, y: thatdatacanvasHeight};
        // 12 定义刻度线高度
        var heightDecimal = 50;
        var heightDigit = 25;
        // 13 定义文本标签字体大小
        var fontSize = 20;
        // 14 最小刻度值
        // 已经定义在全局,便于bindscroll访问
        // 15 总刻度值
        var maxValue = 200;
        // 16 当前刻度值
        var currentValue = 20;
        // 17 每个刻度所占位的px
        var ratio = 10;
        // 18 画布宽度
        var canvasWidth = maxValue * ratio + appscreenWidth - minValue * ratio;
        // 设定scroll-view初始偏移
        thatsetData({
          canvasWidth: canvasWidth,
          scrollLeft: (currentValue - minValue) * ratio
        });
        /* 2绘制 */
        // 21初始化context
        const context = wxcreateCanvasContext('canvas-ruler');
        // 遍历maxValue
        for (var i = 0; i lt;= maxValue; i++) {
          contextbeginPath();
          // 22 画刻度线
          contextmoveTo(origionx + (i - minValue) * ratio, origiony);
          // 画线到刻度高度,10的位数就加高
          contextlineTo(origionx + (i - minValue) * ratio, origiony - (i % ratio == 0 63; heightDecimal : heightDigit));
          // 设置属性
          contextsetLineWidth(2);
          // 10的位数就加深
          contextsetStrokeStyle(i % ratio == 0 63; 'gray' : 'darkgray');
          // 描线
          contextstroke();
          // 23 描绘文本标签
          contextsetFillStyle('gray');
          if (i % ratio == 0) {
            contextsetFontSize(fontSize);
            // 为零补一个空格,让它看起来2位数,页面更整齐
            contextfillText(i == 0 63; ' ' + i : i, origionx + (i - minValue) * ratio - fontSize / 2, fontSize);
          }
          contextclosePath();
        }
        // 24 绘制到context
        contextdraw();
      },
      drawCursor: function () {
        /* 定义变量 */
        // 定义三角形顶点 TODO x
        var center = {x: appscreenWidth / 2, y: 5};
        // 定义三角形边长
        var length = 20;
        // 左端点
        var left = {x: centerx - length / 2, y: centery + length / 2 * Mathsqrt(3)};
        // 右端点
        var right = {x: centerx + length / 2, y: centery + length / 2 * Mathsqrt(3)};
        // 初始化context
        const context = wxcreateCanvasContext('canvas-cursor');
        contextmoveTo(centerx, centery);
        contextlineTo(leftx, lefty);
        contextlineTo(rightx, righty);
        // fill()填充而不是stroke()描边,于是省去手动回归原点,contextlineTo(centerx, centery);
        contextsetFillStyle('48c23d');
        contextfill();
        contextdraw();
      },
      bindscroll: function (e) {
        // deltaX 水平位置偏移位,每次滑动一次触发一次,所以需要记录从第一次触发滑动起,一共滑动了多少距离
        deltaX += edetaildeltaX;
        // 数据绑定
        thatsetData({
          value: Mathfloor(- deltaX / 10 + minValue)
        });
        consolelog(deltaX)
      }
    });

    以上所述是小编给大家介绍的微信小程序实现带刻度尺滑块功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。
    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    蚂蚁站长论坛推荐上一条 /1 下一条

    QQ|Archiver|手机版|广告服务|蚂蚁站长-站长之家 ( 黔ICP备16008478号-1  

    GMT+8, 2017-10-19 07:40

    Powered by 站长论坛

    © 2007-2013 Jzant.com Inc.

    回顶部