在微信小程序上实现手写签名,获取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开发挪动端治理后盾
    • 画三角形
    • 微信小程序应用车牌号输入法