乐趣区

关于javascript:小程序实现手写签名

在微信小程序上实现手写签名,获取 canvascontext 新版本和旧版本有点坑,新版本在获取 canvas 后如果页面有滑动,则签名坐标出现异常 (在微信开发者工具上会呈现 2022-2-17),然而在真机上即便滑动也不会出现异常,为了防止出现问题,临时应用旧版本获取 canvascontext

1. 效果图

2. 相干代码

  • 1.canvas 代码

    • 新版 2d canvas
    <canvas
      id="canvas"
      class="canvas"
      canvas-id="canvas"
      type="2d"
      :disable-scroll="true"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
      @touchcancel="handleTouchCancel"
    ></canvas>
    • 旧版 canvas
    <canvas
      class="canvas"
      canvas-id="canvas"
      :disable-scroll="true"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
      @touchcancel="handleTouchCancel"
    ></canvas>
  • 2.js 相干

    • 获取新版 2d canvas 对象
    const query = uni.createSelectorQuery().in(this);
    query.select('.canvas').node(res => {
      const {
          _width,
          _height
      } = res.node;
      
      /* 获取 canvas wxml 节点 */
      this.canvas = res.node;
      this.canvasWidth = _width;
      this.canvasHeight = _height;
      /* 获取 canvas 2dcontext */
      this.canvasContext= this.canvas.getContext('2d');
      
      /* 缩放设置 canvas 画布大小,避免笔迹错位 */
      const ratio = wx.getSystemInfoSync().pixelRatio;
      this.canvas.width = this.canvasWidth * ratio;
      this.canvas.height = this.canvasHeight * ratio;
      this.canvasContext.scale(ratio, ratio);
      
      /* 设置线条色彩 */
      this.canvasContext.strokeStyle = '#2A2A2A';
      /* 设置线条粗细 */
      this.canvasContext.lineWidth = 4;
      /* 设置线条的完结端点款式 */
      this.canvasContext.lineCap = 'round';
    }).exec()
    • 缩放设置 canvas 画布大小,避免笔迹错位,这点和页面滑动没有关系,不设置也会导致坐标错位
    const ratio = wx.getSystemInfoSync().pixelRatio;
    this.canvas.width = this.canvasWidth * ratio;
    this.canvas.height = this.canvasHeight * ratio;
    this.canvasContext.scale(ratio, ratio);
  • 旧版本获取 canvas

    this.canvasContext = uni.createCanvasContext('canvas', this);
    /* 设置线条色彩 */
    this.canvasContext.setStrokeStyle('#2A2A2A');
    /* 设置线条粗细 */
    this.canvasContext.setLineWidth(4);
    /* 设置线条的完结端点款式 */
    this.canvasContext.setLineCap('round');
  • 签名 js 办法,新版本和旧版本只有一个 draw 的区别,新版本不须要应用 draw 办法

    /* 触摸开始 */
    handleTouchStart(e) {this.drawStartX = e.changedTouches[0].x;
      this.drawStartY = e.changedTouches[0].y;
        this.canvasContext.beginPath();},
    /* 触摸挪动 */
    handleTouchMove(e) {
        /* 记录以后地位 */
        const tempX = e.changedTouches[0].x;
        const tempY = e.changedTouches[0].y;
    
        /* 画线 */
        this.canvasContext.moveTo(this.drawStartX, this.drawStartY);
        this.canvasContext.lineTo(tempX, tempY);
        this.canvasContext.stroke();
    
        /* 旧版 draw 办法,新版本不须要 draw */
        this.canvasContext.draw(true);
    
        /* 从新记录起始地位 */
        this.drawStartX = tempX;
        this.drawStartY = tempY;
    },
    /* 触摸完结 */
    handleTouchEnd(e) {this.canvasContext.save();
    },
    /* 触摸勾销 */
    handleTouchCancel(e) {this.canvasContext.save();
    },
    /* 清空画布 */
    clearCanvas() {this.canvasContext.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
    },
  • canvas 生成本地图片 (我这里封装了组件,须要传入 this 避免 this 指向异样)

    /* 生成签名图片 */
    generateSignImage() {return new Promise((resolve, reject) => {
            uni.canvasToTempFilePath({
              x: 0,
              y: 0,
              // canvas: this.canvas, // 新版
              canvasId: 'canvas', // 旧版应用 id
              width: this.canvasWidth,
              height: this.canvasHeight,
              destWidth: this.canvasWidth,
              destHeight: this.canvasHeight,
              fileType: 'png',
              quality: 1,
              success: res => {resolve(res.tempFilePath)
              },
              fail: err => {reject(err);
              }
            }, this)
        })
    },

    新版本的 canvas 次要是 canvas wxml 节点和 canvas context 中做了辨别,旧版则只有一个 canvas context 就能够做全副的操作,在生成图片时,新版本是传入 wxml 对象,旧版本则是传入惟一 canvasId,新版本 canvas 勾销了 draw 办法

正在努力学习中,若对你的学习有帮忙,留下你的印记呗(点个赞咯 ^_^)

  • 往期举荐:

    • 实现单行及多行文字超出后加省略号
    • 判断 iOS 和 Android 及 PC 端
    • 应用 vue 开发挪动端治理后盾
    • 画三角形
    • 微信小程序应用车牌号输入法
退出移动版