美文网首页微信小程序微信小程序开发微信小程序开发者
【微信小程序canvas】实现小程序手写板用户签名(附代码)

【微信小程序canvas】实现小程序手写板用户签名(附代码)

作者: 老夫很性感 | 来源:发表于2018-09-18 16:35 被阅读17次

    【微信小程序canvas】实现小程序手写板用户签名(附代码)

    工作中公司业务需要的微信小程序用户签字功能

    先看效果图:


    demo

    wxml

    <view class="wrapper">
      <view class="handBtn">
        <button catchtap="retDraw" class="delBtn">重写</button>
        <button catchtap="subCanvas" class="subBtn">完成</button> 
      </view>
      <view class="handCenter">
        <canvas class="handWriting" disable-scroll="true" bindtouchstart="uploadScaleStart" bindtouchmove="uploadScaleMove"
          bindtouchend="uploadScaleEnd" bindtap="mouseDown" canvas-id="handWriting">
        </canvas>
      </view>
      <view class="handRight">
        <view class="handTitle">手写板</view>
      </view>
    </view>
    

    js

    data

    page({
        data: {
            canvasName: 'handWriting',
            ctx: '',
            canvasWidth: 0,
            canvasHeight: 0,
            transparent: 1, // 透明度
            selectColor: 'black',
            lineColor: '#1A1A1A', // 颜色
            lineSize: 1.5,  // 笔记倍数
            lineMin: 0.5,   // 最小笔画半径
            lineMax: 4,     // 最大笔画半径
            pressure: 1,     // 默认压力
            smoothness: 60,  //顺滑度,用60的距离来计算速度
            currentPoint: {},
            currentLine: [],  // 当前线条
            firstTouch: true, // 第一次触发
            radius: 1, //画圆的半径
            cutArea: { top: 0, right: 0, bottom: 0, left: 0 }, //裁剪区域
            bethelPoint: [],  //保存所有线条 生成的贝塞尔点;
            lastPoint: 0,
            chirography: [], //笔迹
            currentChirography: {}, //当前笔迹
            linePrack: [], //划线轨迹 , 生成线条的实际点
        }
    })
    

    初始化

    page({
      onLoad () {
        let canvasName = this.data.canvasName
        let ctx = wx.createCanvasContext(canvasName)
        this.setData({
          ctx: ctx
        })
        var query = wx.createSelectorQuery();
            query.select('.handCenter').boundingClientRect(rect => {query.select('.handCenter').boundingClientRect(rect => {
              this.setData({this.setData({
                canvasWidth: rect.width,canvasWidth: rect.width,
                canvasHeight: rect.heightcanvasHeight: rect.height
              })})
            }).exec(); }).exec();
          }, },
    })
    

    事件函数

    笔迹开始

    // 笔迹开始
      uploadScaleStart (e) {
        if (e.type != 'touchstart') return false;
        let ctx = this.data.ctx;
        ctx.setFillStyle(this.data.lineColor);  // 初始线条设置颜色
        ctx.setGlobalAlpha(this.data.transparent);  // 设置半透明
        let currentPoint = {
          x: e.touches[0].x,
          y: e.touches[0].y
        }
        let currentLine = this.data.currentLine;
        currentLine.unshift({
          time: new Date().getTime(),
          dis: 0,
          x: currentPoint.x,
          y: currentPoint.y
        })
        this.setData({
          currentPoint,
          // currentLine
        })
        if (this.data.firstTouch) {
          this.setData({
            cutArea: { top: currentPoint.y, right: currentPoint.x, bottom: currentPoint.y, left: currentPoint.x },
            firstTouch: false
          })
        }
        this.pointToLine(currentLine);
      },
    

    笔迹移动

    // 笔迹移动
      uploadScaleMove (e) {
        if (e.type != 'touchmove') return false;
        if (e.cancelable) {
          // 判断默认行为是否已经被禁用
          if (!e.defaultPrevented) {
            e.preventDefault();
          }
        }
        let point = {
          x: e.touches[0].x,
          y: e.touches[0].y
        }
    
        //测试裁剪
        if (point.y < this.data.cutArea.top) {
          this.data.cutArea.top = point.y;
        }
        if (point.y < 0) this.data.cutArea.top = 0;
    
        if (point.x > this.data.cutArea.right) {
          this.data.cutArea.right = point.x;
        }
        if (this.data.canvasWidth - point.x <= 0) {
          this.data.cutArea.right = this.data.canvasWidth;
        }
        if (point.y > this.data.cutArea.bottom) {
          this.data.cutArea.bottom = point.y;
        }
        if (this.data.canvasHeight - point.y <= 0) {
          this.data.cutArea.bottom = this.data.canvasHeight;
        }
        if (point.x < this.data.cutArea.left) {
          this.data.cutArea.left = point.x;
        }
        if (point.x < 0) this.data.cutArea.left = 0;
    
        this.setData({
          lastPoint: this.data.currentPoint,
          currentPoint: point
        })
        let currentLine = this.data.currentLine
        currentLine.unshift({
          time: new Date().getTime(),
          dis: this.distance(this.data.currentPoint, this.data.lastPoint),
          x: point.x,
          y: point.y
        })
        // this.setData({
        //   currentLine
        // })
        this.pointToLine(currentLine);
      },
    

    笔迹结束

    // 笔迹结束
      uploadScaleEnd (e) {
        if (e.type != 'touchend') return 0;
        let point = {
          x: e.changedTouches[0].x,
          y: e.changedTouches[0].y
        }
        this.setData({
          lastPoint: this.data.currentPoint,
          currentPoint: point
        })
        let currentLine = this.data.currentLine
        currentLine.unshift({
          time: new Date().getTime(),
          dis: this.distance(this.data.currentPoint, this.data.lastPoint),
          x: point.x,
          y: point.y
        })
        // this.setData({
        //   currentLine
        // })
        if (currentLine.length > 2) {
          var info = (currentLine[0].time - currentLine[currentLine.length - 1].time) / currentLine.length;
          //$("#info").text(info.toFixed(2));
        }
        //一笔结束,保存笔迹的坐标点,清空,当前笔迹
        //增加判断是否在手写区域;
        this.pointToLine(currentLine);
        var currentChirography = {
          lineSize: this.data.lineSize,
          lineColor: this.data.lineColor
        };
        var chirography = this.data.chirography
        chirography.unshift(currentChirography);
        this.setData({
          chirography
        })
        var linePrack = this.data.linePrack
        linePrack.unshift(this.data.currentLine);
        this.setData({
          linePrack,
          currentLine: []
        })
      },
    

    wxss

    page {
      background: #fbfbfb;
      height: auto;
      overflow: hidden;
    }
    
    .wrapper {
      width: 100%;
      height: 95vh;
      margin: 30rpx 0;
      overflow: hidden;
      display: flex;
      align-content: center;
      flex-direction: row;
      justify-content: center;
      font-size: 28rpx;
    }
    
    .handWriting {
      background: #fff;
      width: 100%;
      height: 95vh;
    }
    
    .handRight {
      display: inline-flex;
      align-items: center;
    }
    
    .handCenter {
      border: 4rpx dashed #e9e9e9;
      flex: 5;
      overflow: hidden;
      box-sizing: border-box;
    }
    
    .handTitle {
      transform: rotate(90deg);
      flex: 1;
      color: #666;
    }
    
    .handBtn button {
      font-size: 28rpx;
    }
    
    .handBtn {
      height: 95vh;
      display: inline-flex;
      flex-direction: column;
      justify-content: space-between;
      align-content: space-between;
      flex: 1;
    }
    
    .delBtn {
      position: absolute;
      top: 550rpx;
      left: 0rpx;
      transform: rotate(90deg);
      color: #666;
    }
    
    .delBtn image {
      position: absolute;
      top: 13rpx;
      left: 25rpx;
    }
    

    结语

    详细项目代码handwriting-weapp(微信小程序原生canvas用户签字手写板,后续更新计划组件化、优化渲染逻辑、增加功能,欢迎start 和 PR)

    相关文章

      网友评论

      • 5624cbe3875a:请问一下楼主,我签字之后生成的图片不完整,有一半看不到,这个是什么原因
        5624cbe3875a:是我自己生成图片时候宽度配置粗了,已经解决了

      本文标题:【微信小程序canvas】实现小程序手写板用户签名(附代码)

      本文链接:https://www.haomeiwen.com/subject/mdbpnftx.html