H5实现在线签名,解决页面滑动的问题

5 篇文章 0 订阅

原理

实现在线签名功能,主要是依托canvas技术。
首先生成画布、初始画笔对象,然后为画布添加touch事件监听,通过事件触发绘制文字。保存时通过canvas的toDataURL方法生成base64图片文件进行下一步操作。

基于vue的demo实现

<template>
  <div class="page-content">
    <header title="用户需求签名">
      <button slot="right" @click="handelClearEl()" type="danger">清除</button>
      <button slot="right" @click="saveImage()" type="danger">保存</button>
    </header>
    <div class="sign-content">
      <div class="div_canvas_container">
        <canvas id="signCanvas"></canvas>
      </div>
    </div>
  </div>
</template>
<style lang="less" scoped>
	body {
	  position: initial;
	  height: auto;
	}
	.div_canvas_container {
	  width: 100vw;
	  height: 80vh;
	  overflow: hidden;
	}
	#signCanvas {
	  width: 100%;
	  height: 100%;
	  background: #fff;
	  border: none;
	  box-sizing: border-box;
	  overflow: hidden;
	}
</style>
<script>
	export default {
	  //数字签名
	  name: 'digitaSign',
	  data() {
	    return {
	      imgsrc: '',
	    }
	  },
	  mounted() {
	    let vm = this
	    vm.digitaSignType = vm.$route.query.type
	    this.$nextTick(() => {
	      setTimeout(() => {
	        vm.initCanvas()
	      }, 100)
	    })
	  },
	  methods: {
	    initCanvas() {
	      let rate = 1
	      let oCanvas = document.getElementById('signCanvas')
	      oCanvas.width = oCanvas.offsetWidth * rate
	      oCanvas.height = oCanvas.offsetHeight * rate
	      let cxt = oCanvas.getContext('2d')
	      cxt.fillStyle = '#fff'
	      cxt.fillRect(0, 0, oCanvas.width, oCanvas.height)
	      cxt.lineWidth = 2 * rate
	      cxt.strokeStyle = '#101010'
	      let posX = 0 //x坐标
	      let posY = 0 //y坐标
	      let position = null
	      let parentPosintin = oCanvas.getBoundingClientRect()
	
	      //手指触摸屏幕可记录此时的位置作为起点
	      oCanvas.addEventListener('touchstart', function (event) {
	        posX = event.changedTouches[0].clientX
	        posY = event.changedTouches[0].clientY - parentPosintin.top + 0.5
	        cxt.beginPath()
	        cxt.moveTo(posX * rate, posY * rate)
	      })
	      //手指屏滑动画线
	      oCanvas.addEventListener('touchmove', function (event) {
	        optimizedMove(event)
	      })
	      let requestAnimationFrame = window.requestAnimationFrame
	      let optimizedMove = requestAnimationFrame
	        ? function (e) {
	            requestAnimationFrame(function () {
	              move(e)
	            })
	          }
	        : move
	      function move(event) {
	        posX = event.changedTouches[0].clientX + 0.5
	        posY = event.changedTouches[0].clientY - parentPosintin.top + 0.5
	        cxt.lineTo(posX * rate, posY * rate)
	        cxt.stroke()
	      }
	    },
	    // 清除画板
	    handelClearEl() {
	      console.log(111)
	      let oCanvas = document.getElementById('signCanvas')
	      let cxt = oCanvas.getContext('2d')
	      cxt.clearRect(0, 0, oCanvas.width, oCanvas.height)
	    },
	    //保存为图片
	    saveImage() {
	      let oCanvas = document.getElementById('signCanvas')
	      let imgBase64 = oCanvas.toDataURL()
	      this.imgsrc = imgBase64
	      console.log(imgBase64)
	      if (this.digitaSignType == 'partyA') {
	        this.$store.commit('SET_PAERT_A_IMG', imgBase64)
	      } else {
	        this.$store.commit('SET_PAERT_B_IMG', imgBase64)
	      }
	    },
	  },
	}
</script>

在PC端运行这段代码基本上没有问题了,但在真正完成功能部署后你会发现,在微信公众号打开或是其他移动端浏览器打开时都会出现和浏览器原生滑动事件冲突的现象,例如微信公众号里写‘丨’的时候会造成浏览器页面下拉,所写笔画会出现中断,严重影响用户体验,那么你需要添加如下代码:

<script>
  document.body.addEventListener('touchmove', function (e) {
    e.preventDefault();
  }, { passive: false });
</script>

以上代码阻止了touchmove事件的默认行为,从而防止了浏览器页面的滑动。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值