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

对于,程序,canvas,某些,情况,touchmove,不能,连续,触发,导致,签名,替代,方案 · 浏览次数 : 34

小编点评

**问题描述:** 在企业微信中签名时,canvas的touchmove触发问题,无法正常绘制线段。 **解决方案:** 1. 通过使用 `touchstart` 和 `touchend` 事件来监听手指划过的轨迹,并绘制线段。 2. 通过判断手指是否连续滑动来处理不同滑动速度。 3. 通过在 `touchmove` 事件中阻止滚动来确保线段完整绘制。 **代码:** ```javascript export default { name: 'DomCanvasSignature', data () { return { // ...其他数据 isPcStart: false, previousPoint: { x: 0, y: 0 }, }; }, methods: { // ...其他方法 touchstart () { this.isPcStart = true; console.log('====start'); // zdz-log }, touchend () { this.isPcStart = false; console.log('====end'); // zdz-log }, touchmove (e) { // ...处理手指划过的轨迹 }, }, created () { // ...其他方法 }, destroyed () { // ...其他方法 }, mounted () { // ...其他方法 }, }; ``` **注意:** 1. 该代码需要使用 `canvas` 元素来绘制线段。 2. `signatureWrapper` 是一个用来存放工具箱的 div 元素。 3. `diffLarge` 用于判断是否在滑动中绘制完一个线段后松手再次滑动。

正文

1.问题

image
微信开放社区链接

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

2.解决方案

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

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

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

没有采取通过touchstart与touchend做一个判断是因为touchmove并不是固定一直在start与end事件中间触发
直接点击触发事件顺序

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>


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

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

1.问题 微信开放社区链接 尝试过新版canvas,在企业微信中签名依然是依然断触,有问题的手机是iphoe15,系统版本以及企微版本微信版本均与签名正常的手机一致,但是那个手机就是无法正常签字,在微信中无论新旧canvas均能正常签字 2.解决方案 既然canvas的touchmove触发有问题,

开发一个题库系统App和小程序的心得

序言 对于一名开发者来说,独自开发一款小程序与App,也许总会有一些疑问: 1. 需要掌握哪些技术? 答:java、vue、及常规Linux命令 2. 需要多少成本? 答:服务器购买,云服务器新人50多三年; 域名购买,10块的域名够用,后续每年30左右的续期费用; 短信套餐购买,50块钱,够用很久

一文帮你搞定H5、小程序、Taro长列表曝光埋点

对于各种类型的埋点来说,曝光埋点往往最为复杂、需要用到的技术也最全面、如果实现方式不合理可能造成的影响也最大,因此本文将重点介绍曝光埋点尤其是长列表(或滚动视图)内元素曝光埋点的实现思路及避坑技巧

对于Vue3和Ts的心得和思考

Vue3已经正式发布了一段时间了,各种生态已经成熟。最近使用taro+vue3重构冷链的小程序,经过了一段时间的开发和使用,有了一些自己的思考。

万物皆可集成系列:低代码对接微信小程序

本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 近年来,微信小程序的开发如火如荼,很多移动端应用为了更方便被大家所使用的,都步入了小程序的行列 那么对于低代码平台开发的移动端应用是否可以和小程序集成呢?这里我以微信小

试试用Markdown来设计表单

相信很多后端开发。对于前端知识是比较零碎的,所以很多时候写表单这样的工作,一般就是复制黏贴,然后改改字段。对于HTML格式,一直觉得比较杂乱,不够简洁。 最近TJ发现了一个有趣的小工具:Create HTML Form。 看看上面它的Slogan,是不是很有意思?居然可以通过Markdown来编写H

京东小程序数据中心架构设计与最佳实践

小程序平台是怎么保证商家业务的稳定、健康发展,服务好这些外部商家的呢?这里面非常重要的是我们平台对小程序基本流量的运营与监控。如何不让业务的小程序在线上裸奔?如何帮助业务对自身小程序流量的冲高回落有一种直观的把握和监测?如何基于海量数据指导业务去进行一个精细化的运营?实际上,京东小程序数据中心就扮演了一个这样的小程序数据问题终结者的角色,充分利用各类数据手段,解决这些痛点问题。

【炫丽】从0开始做一个WPF+Blazor对话小程序

大家好,我是沙漠尽头的狼。 .NET是免费,跨平台,开源,用于构建所有应用的开发人员平台。 本文演示如何在WPF中使用Blazor开发漂亮的UI,为客户端开发注入新活力。 注 要使WPF支持Blazor,.NET版本必须是 6.0 或更高版本,本文所有示例使用的.NET 7.0,版本要求见链接,截图

低代码助力微信小程序对接,提升开发效率

本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 微信小程序相信大家都用过,相较于APP,微信小程序的优势在于其便捷性,只需要下载一个微信就可以访问所有的小程序,因此许多开发者也逐渐将自己开发的系统部署到微信小程序上以供

京东小程序接入ARVR的技术方案和性能调优

京东小程序是一个开放技术平台,正在被越来越多的头部品牌选择,用于站内私域流量的营销和运营。诸如各种日化、奢侈品等品牌对ARVR有较多的诉求,希望京东小程序引擎提供一些底层能力,叠加品牌自主的个性化开发和定制,以支持更加丰富的场景和玩法,比如AR试妆、试戴等。