对于小程序canvas在某些情况下touchmove 不能连续触发导致的签名不连续替代方案(企微)

1.问题

对于小程序canvas在某些情况下touchmove 不能连续触发导致的签名不连续替代方案(企微)
微信开放社区链接

尝试过新版canvas,在企业微信中签名依然是依然断触,有问题的手机是iphoe15,系统版本以及企微版本微信版本均与签名正常的手机一致,但是那个手机就是无法正常签字,在微信中无论新旧canvas均能正常签字

2.解决方案

既然canvas的touchmove触发有问题,那么就可以通过替代canvas的touchmove来实现,通过在canvas上覆盖一层dom,通过这层dom的touchmove来获取手指划过的轨迹即可,此文章中并没有小程序实际代码只是使用了h5验证可行性的代码

2.1 注意点
  • 要区别手指是否连续滑动,由于点击事件触发存在如下情况

区别手指是否连续滑动采用时间间隔判断
触发事件间隔小于80ms 主要用于判断是否松开手指再次滑动,正常手速来说80ms,人很难在画完一个线段后,松手再次画一个线段,如果无这个处理会出现滑动一个线段之后,再次点击另一个点会把线段和新点位连接起来

没有采取通过touchstart与touchend做一个判断是因为touchmove并不是固定一直在start与end事件中间触发
对于小程序canvas在某些情况下touchmove 不能连续触发导致的签名不连续替代方案(企微)

2.2 移动端浏览器体验地址
2.2 vue2代码
<template>   <div class="DomCanvasSignature">     <div :style="{ height: height + 'px', width: width + 'px' }" class="signatureWrapper" id="signatureWrapper"       draggable="false" @mousedown="touchstart" @mouseup="touchend" @touchstart="touchstart" @touchend="touchend"       @touchmove="touchmove" @mousemove="touchmove">       <canvas canvas-id="999" :height="height" :width="width - 3" class="canvas" />     </div>   </div> </template> <script> export default {   name: 'DomCanvasSignature',   data () {     return {       height: 302,       width: 302,        mycanvas: null,       previousPoint: {         x: 0,         y: 0       },       isPcStart: false,       removeLisner: () => { }     }   },     methods: {     initSize () {       this.width = window.innerWidth       this.height = window.innerHeight - 300     },     lisner () {       this.initSize()       window.addEventListener('resize', this.initSize)       return () => {         window.removeEventListener('resize', this.initSize)       }     },     touchstart () {       this.isPcStart = true       console.log('====start') // zdz-log     },     touchend () {       this.isPcStart = false       console.log('====end') // zdz-log      },     touchmove (e) {       console.log('move', e) // zdz-log       // 阻止滚动       e.preventDefault()       if (e.type === 'mousemove' && !this.isPcStart) {         return       }       // 合并处理 pc 与移动端       const changeObj = e.changedTouches && e.changedTouches[0] || e       const current = { x: changeObj.clientX, y: changeObj.clientY, timeStamp: e.timeStamp }        // 1.获取元素       // 2.获取上下文,绘制工具箱       let ctx = this.mycanvas.getContext('2d')       // 3.移动画笔       const currentY = (current.y) - signatureWrapper.offsetTop       // todo 改为touchstart 与end判断 无法实现 因为move 执行存在在 start end事件之后       let diffLarge = false       console.log(current.timeStamp - this.previousPoint.timeStamp) // zdz-log       // 判断是否松手重新绘制       if (this.previousPoint.timeStamp) {         const timeDiff = current.timeStamp - this.previousPoint.timeStamp > 80         if (timeDiff) {           diffLarge = true         }       }        const preY = diffLarge ? current.y - signatureWrapper.offsetTop : (this.previousPoint.y || current.y) - signatureWrapper.offsetTop       const moveX = diffLarge ? current.x : this.previousPoint.x || current.x       ctx.moveTo(moveX, preY < 0 ? 0 : preY)       // 4.绘制直线(轨迹,绘制路径)       ctx.lineTo(current.x, currentY < 0 ? 0 : currentY)       // 5.描边       ctx.stroke()        this.previousPoint = current      },     },   created () {     this.removeLisner = this.lisner()   },   destroyed () {     this.removeLisner()   },   mounted () {     this.mycanvas = document.querySelector('canvas')     this.signatureWrapper = document.getElementById('signatureWrapper')   },  } </script>  <style scoped> .canvas {   border: 1px solid red; }  .signatureWrapper {   display: flex;   align-items: center;   justify-content: center;   border: 1px solid black;   background-color: transparent; } </style>   

发表评论

相关文章