当前位置:   article > 正文

微信小程序画布canvas(新版)实现签名功能_微信开发工具原生canvas新版手写签名

微信开发工具原生canvas新版手写签名

wxml文件:

 <!-- 签名画布 -->
   <canvas class="canvas" id="signature-board" disable-scroll="true" bindtouchstart="canvasStart"
     bindtouchmove="canvasMove" bindtouchend="canvasEnd" touchcancel="canvasEnd" type="2d">
   </canvas>
  • 1
  • 2
  • 3
  • 4

新版使用id获取canvas组件即可,旧版需要使用canvas-id。

wxss文件:

/* pages/signature/signature.wxss */
.container {
  padding: 20rpx;
  height: 100vh;
  width: 100vw;
  overflow: hidden; 
  display: flex;
  align-items:  center;
  /* background: radial-gradient(#fff, #000); */
  background-repeat: no-repeat;
  background-size: cover;
}
.block {
  height: calc(calc(100vw - 60rpx - 40rpx) / 2);
  /* max-height: 100%; */
  width: 100%;
  border-radius: 5rpx;
  overflow: hidden;
  display: flex;
  align-items:  center;
  background: rgba(255,255,255,.5);
  box-shadow: 0 0 30rpx 0 rgba(0,0,0,.3);
}
.drawarea {
  flex-grow: 2;
  height: 100%;
  width: 100%;
  position: relative;
}
.sign-hint {
  position: absolute;
  top: 0;
  left: 10rpx;
  right: 0;
  bottom: 0;
  z-index: 0;
  margin: auto;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  font-size: 40rpx;
  letter-spacing: .2em;
  color: rgba(0,0,0,.2);
  word-break: keep-all;
  white-space: pre-line;
}
.canvas {
  flex-grow: 2;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
} 
.button-box {
  flex-grow: 0;
  flex-shrink: 0;
  height: 100%;
  width: 40rpx;
  padding: 30rpx 10rpx 30rpx 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.cu-btn {
  width: 100%!important;
  height: 50%!important;
  padding: 0 2.5rpx 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 15rpx;
}
.cu-btn:first-of-type {
  margin: 0 0 30rpx 0;
}
.btn-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  writing-mode: vertical-rl;
  color: #fff;
  font-size: 14px;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

json文件:

{
    "usingComponents": {},
    "pageOrientation": "landscape"
}
  • 1
  • 2
  • 3
  • 4

js文件:

const MAX_V = 1; // 最大书写速度
const MIN_V = 0; // 最小书写速度
const MAX_LINE_WIDTH = 16; // 最大笔画宽度
const MIN_LINE_WIDTH = 4; // 最小笔画宽度
const MAX_LINE_DIFF = .03; // 两点之间笔画宽度最大差异
let context = null; // canvas上下文
let lastPoint = null; // 包含上一点笔画信息的对象
Page({
  data: {
    drawn: false,
  },
  onShow: function (options) {
    this.canvasInit();
  },
  canvasInit: function () {
    wx.createSelectorQuery() 
    .select('#signature-board') // 在 WXML 中填入的 id
    .fields({ node: true, size: true })
    .exec((res) => {
      res[0].node.width = res[0].width;
      res[0].node.height = res[0].height;
        context = res[0].node.getContext("2d")
    })

  },
  canvasMove: function (e) {
    this.setData({
      drawn: true
    })
    let currPoint = {
      x: e.changedTouches[0].x, // X坐标
      y: e.changedTouches[0].y, // Y坐标
      t: new Date().getTime(), // 当前时间
      w: (MAX_LINE_WIDTH + MIN_LINE_WIDTH) / 2 /*默认宽度 */
    };
    if (lastPoint) {
      currPoint.w = this.calcLineWidth(currPoint); // 重新赋值宽度,覆盖默认值 
      context.beginPath();
      context.strokeStyle = '#000';
      context.lineCap = 'round';
      context.lineJoin = 'round';
      context.lineWidth = currPoint.w;
      context.moveTo(lastPoint.x, lastPoint.y);
      context.lineTo(currPoint.x, currPoint.y);
      context.stroke();
    }
    lastPoint = currPoint; // 结束前保存当前点为上一点
  },
  // 计算当前点的宽度,书写速度越快,笔画宽度越小,呈现出笔锋的感觉(笑)
  calcLineWidth: function (currPoint) {
    let consuming = currPoint.t - lastPoint.t; // 两点之间耗时
    if (!consuming) return lastPoint.w; // 如果当前点用时为0,返回上点的宽度。
    let maxWidth = Math.min(MAX_LINE_WIDTH, lastPoint.w * (1 + MAX_LINE_DIFF)); // 当前点的最大宽度
    let minWidth = Math.max(MIN_LINE_WIDTH, lastPoint.w * (1 - MAX_LINE_DIFF * 3)); // 当前点的最小宽度,变细时速度快所以宽度变化要稍快
    let distance = Math.sqrt(Math.pow(currPoint.x - lastPoint.x, 2) + Math.pow(currPoint.y - lastPoint.y, 2)); // 两点之间距离
    let speed = Math.max(Math.min(distance / consuming, MAX_V), MIN_V); /*当前点速度*/
    let lineWidth = Math.max(Math.min(MAX_LINE_WIDTH * (1 - speed / MAX_V), maxWidth), minWidth); /* 当前点宽度 */
    return lineWidth;
  },
  canvasEnd: function (e) {
    lastPoint = null; // 每笔画完清除缓存
  },
  canvasClear: function () {
    this.setData({
      drawn: false
    })
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);
    // context.draw(false);
  },
  canvasOut: function () {
    wx.navigateBack({
      delta: 1,
    })
  },
  finish: function () {
    if (!this.data.drawn) {
      return;
    }
	//由于新版的canvas的wx.canvasToTempFilePath方法一直报错,只能通过以下方式来获取签名图片
    const res = context.canvas.toDataURL("image/png");
    const fsm = wx.getFileSystemManager();
    const FILE_BASE_NAME = "tmp_base64src_" + new Date().getTime();
    const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.png`;
    fsm.writeFile({
      filePath,
      data: res.replace(/^data:image\/\w+;base64,/, ""),
      encoding: "base64",
      success: () => {
          this.getOpenerEventChannel().emit('signature', filePath); //传签名图片的临时路径回上一页
          wx.navigateBack();
      },
      fail() {
        wx.showToast({ title: "生成签名失败", icon: "none" });
      },
    });
  },
})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

签名效果:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/955075
推荐阅读
相关标签
  

闽ICP备14008679号