Vue Canvas实现电子签名

最近再做移动端电子签名,Vue+Canvas实现,移动端、PC端均可,也可以从github下载 。

我在做这个功能的时候参考了 这个代码,但是在移动端光标与实际划线有偏移,我在我的代码中修正了这个问题。

代码

<template>
      <section class="signature">
          <div class="signatureBox">
              <div class="canvasBox" ref="canvasHW">
                  <canvas ref="canvasF" @touchstart='touchStart' @touchmove='touchMove' @touchend='touchEnd' @mousedown="mouseDown" @mousemove="mouseMove" @mouseup="mouseUp"></canvas>
                  <div class="btnBox">
                      <div @click="overwrite">重写</div>
                      <div @click="commit">提交签名</div>
                  </div>   
              </div>
          </div>
          <img class="imgCanvas" :src="imgUrl">
      </section>    
</template>

JS

<script>
  export default {
    data() {
      return {
        stageInfo:'',
        imgUrl:'',
        client: {},
        points: [],
        canvasTxt: null,
        startX: 0,
        startY: 0,
        moveY: 0,
        moveX: 0,
        endY: 0,
        endX: 0,
        w: null,
        h: null,
        isDown: false,
        isViewAutograph: this.$route.query.isViews > 0,
        contractSuccess: this.$route.query.contractSuccess
      }
    },
    mounted() {
      let canvas = this.$refs.canvasF
      canvas.height = this.$refs.canvasHW.offsetHeight - 500
      canvas.width = this.$refs.canvasHW.offsetWidth - 50
      this.canvasTxt = canvas.getContext('2d')
      this.stageInfo = canvas.getBoundingClientRect()
    },
    methods: {
      //mobile
      touchStart(ev) {
        ev = ev || event
        ev.preventDefault()
        if (ev.touches.length == 1) {
          let obj = {
            x: ev.targetTouches[0].clienX,
            y: ev.targetTouches[0].clientY,
          }
          this.startX = obj.x
          this.startY = obj.y
          this.canvasTxt.beginPath()
          this.canvasTxt.moveTo(this.startX, this.startY)
          this.canvasTxt.lineTo(obj.x, obj.y)
          this.canvasTxt.stroke()
          this.canvasTxt.closePath()
          this.points.push(obj)
        }
      },
      touchMove(ev) {
        ev = ev || event
        ev.preventDefault()
        if (ev.touches.length == 1) {
          let obj = {
            x: ev.targetTouches[0].clientX - this.stageInfo.left,
            y: ev.targetTouches[0].clientY - this.stageInfo.top
          }
          this.moveY = obj.y
          this.moveX = obj.x
          this.canvasTxt.beginPath()
          this.canvasTxt.moveTo(this.startX, this.startY)
          this.canvasTxt.lineTo(obj.x, obj.y)
          this.canvasTxt.stroke()
          this.canvasTxt.closePath()
          this.startY = obj.y
          this.startX = obj.x
          this.points.push(obj)
        }
      },
      touchEnd(ev) {
        ev = ev || event
        ev.preventDefault()
        if (ev.touches.length == 1) {
          let obj = {
            x: ev.targetTouches[0].clientX - this.stageInfo.left,
            y: ev.targetTouches[0].clientY - this.stageInfo.top
          }
          this.canvasTxt.beginPath()
          this.canvasTxt.moveTo(this.startX, this.startY)
          this.canvasTxt.lineTo(obj.x, obj.y)
          this.canvasTxt.stroke()
          this.canvasTxt.closePath()
          this.points.push(obj)
        }
      },
      //pc
      mouseDown(ev) {
        ev = ev || event
        ev.preventDefault()
        if (1) {
          let obj = {
            x: ev.offsetX,
            y: ev.offsetY
          }
          this.startX = obj.x
          this.startY = obj.y
          this.canvasTxt.beginPath()
          this.canvasTxt.moveTo(this.startX, this.startY)
          this.canvasTxt.lineTo(obj.x, obj.y)
          this.canvasTxt.stroke()
          this.canvasTxt.closePath()
          this.points.push(obj)
          this.isDown = true
        }
      },
      mouseMove(ev) {
        ev = ev || event
        ev.preventDefault()
        if (this.isDown) {
          let obj = {
            x: ev.offsetX,
            y: ev.offsetY
          }
          this.moveY = obj.y
          this.moveX = obj.x
          this.canvasTxt.beginPath()
          this.canvasTxt.moveTo(this.startX, this.startY)
          this.canvasTxt.lineTo(obj.x, obj.y)
          this.canvasTxt.stroke()
          this.canvasTxt.closePath()
          this.startY = obj.y
          this.startX = obj.x
          this.points.push(obj)
        }
      },
      mouseUp(ev) {
        ev = ev || event
        ev.preventDefault()
        if (1) {
          let obj = {
            x: ev.offsetX,
            y: ev.offsetY
          }
          this.canvasTxt.beginPath()
          this.canvasTxt.moveTo(this.startX, this.startY)
          this.canvasTxt.lineTo(obj.x, obj.y)
          this.canvasTxt.stroke()
          this.canvasTxt.closePath()
          this.points.push(obj)
          this.points.push({x: -1, y: -1})
          this.isDown = false
        }
      },
      //重写
      overwrite() {
        this.canvasTxt.clearRect(0, 0, this.$refs.canvasF.width, this.$refs.canvasF.height)
        this.points = []
      },
      //提交签名
      commit() {
        this.imgUrl=this.$refs.canvasF.toDataURL();
        console.log(this.$refs.canvasF.toDataURL()) //签名img回传后台
      }
    }
  }
</script>

CSS

<style scoped>
  .signatureBox {
    width: 100%;
    height: calc(100% - 50px);
    box-sizing: border-box;
    overflow: hidden;
    background: #fff;
    z-index: 100;
    display: flex;
    flex-direction: column;
  }
  .canvasBox {
    box-sizing: border-box;
    flex: 1;
  }
  canvas {
    border: 1px solid #7d7d7d;
  }
  .btnBox {
    padding: 10px;
    text-align: center;
  }
  .btnBox button:first-of-type {
    background: transparent;
    border-radius: 4px;
    height: 40px;
    width: 80px;
    font-size: 14px;
  }
  .btnBox button:last-of-type {
    background: #71b900;
    color: #fff;
    border-radius: 4px;
    height: 40px;
    width: 80px;
    font-size: 14px;
  }
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • VUE解决微信签名及SPA微信invalid signature问题(完美处理)

    前端小菜鸟,因为项目要对接微信的jssdk,对接就需要签名认证,但是无奈安卓和IOS各有各的坑,本篇文章只讨论签名,和一个分享的坑,希望大家有所收获,能够解决问题,如果解决不到,请麻烦在评论区留言,本文综合了所有的回答,才调试出来坑 需求: 使用微信的功能 原因: 1. 项目基于vue,在微信上的web应用 2. 要使用上传功能(不同系统的兼容真的很多BUG,最后只能使用微信方案),支付功能,定位.... 3. 签名一直存在bug和问题,那么后面的功能都会唤不起(偶尔也可以) 签名 1. 流程详

  • 基于canvas实现手写签名(vue)

    最近一直在研究canvas的东西,正好之前对手写签名这块有点兴趣.就自己基于vue写了一个简易的手写签名demo. 其中原理比较简单,先生成一个canvas画布,并对canvas进行touchstart和touchmove事件进行监听.当监听touchstart事件被触发时,我们开始触发canvas里的beginPath事件并且设置moveTo原始点.当监听touchmove事件则去不断去触发lineTo事件,最后stroke(). demo里还有清除签名和保存签名的功能,分别对应了clearR

  • 详解IOS微信上Vue单页面应用JSSDK签名失败解决方案

    背景 手机型号: 型号:iphone 7 / iphone xs max 版本:ios 10.3.1 / ios 12.1 微信版本:WeChat 6.7.3 问题还原: Vue应用(vue-router)上使用history模式,在某个页面内调用微信JSSDK相关API,如扫码.分享等,使用当前页面URL总会出现签名错误(invalid signature),导致API调用失败. 问题根源 Vue-Router进行路由切换的时候,总是会操作浏览器的历史记录,从而响应页面URL变化. 在JSSD

  • vue+canvas实现移动端手写签名

    本文实例为大家分享了vue+canvas实现移动端手写签名的具体代码,供大家参考,具体内容如下 <template> <div class="sign"> <div class="header"> <i class="el-icon-arrow-left backImg" @click="goBack"></i> <span class="title&

  • 使用vue实现手写签名功能

     个人实现截图: 安装: npm install vue-esign --save 使用: 1.在main.js中引入 import vueEsign from 'vue-esign' Vue.use(vueEsign) 2.在页面中引用 <vue-esign ref="esign" :width="800" :height="300" :isCrop="isCrop" :lineWidth="lineWidt

  • 详解Vue开发微信H5微信分享签名失败问题解决方案

    关于Vue中路由使用history模式,开发微信H5页面分享时在安卓上签名有效成功,但是在IOS设备上一直报错签名失效问题 问题描述:在Vue开发过程中,路由使用History模式下,在使用微信分享时,在微信开发者工具上一切正常.在安卓上一切正常. 但是!!!在IOS上反复报签名错误. 以下是真机测试截图,划掉黑线的是我个人IOS设备分享出来一直是服务号,接着下面分享出来自定义内容是安卓分享正常,话不多说上图!!!! 我的代码: 需求描述:需要从首页进入活动详情页,然后在详情页分享详情页面内容.

  • vue移动端使用canvas签名的实现

    效果 canvas画板移动端 .gif 需求   在一些项目业务中,经常会使用到画板,让用户自己去写/画一些东西做标示,比如说在线签电子合约.签名等,如果不用插件,那么如何使用h5的canvas画布来实现这一需求呢? [本篇只讨论移动端,PC端请看上篇] 分析   很明显,我们需要一个canvas,关于canvas的一些基本操作可以在w3school或者别的一些平台上熟悉一下,其实本例也是基础操作.本案例在vue中完成.(脱离vue也一样.) 首先,需要一个canvas画布 其次,考虑逻辑 把逻

  • vue+element加入签名效果(移动端可用)

    下面介绍为了方便就把项目的文件叫作父组件,然后签名的那个组件叫作子组件 ! 如有不太明白的地方,多看看代码注释.为细节地方 1. 首先根据element ui 在父组件中设置好diglog弹框,并且在全局样式下,自定义样式 <div class="canva" @click="centerDialogVisible = true"> // click绑定的方法是element提供的 centerDialogVisibe=true 是点击时弹框出现 <

  • vue 使用 canvas 实现手写电子签名

    功能 兼容 PC 和 Mobile: 画布自适应屏幕大小变化(窗口缩放.屏幕旋转时画布无需重置,自动校正坐标偏移): 自定义画布尺寸(导出图尺寸),画笔粗细.颜色,画布背景色: 支持裁剪 (针对需求:有的签字需要裁剪掉四周空白). 导出图片格式为 base64 : 示例demo 安装 npm install vue-esign --save 使用 main.js 中引入 import vueEsign from 'vue-esign' Vue.use(vueEsign) 页面中使用 必须设置 r

  • 使用vue实现一个电子签名组件的示例代码

    在生活中我们使用到电子签名最多的地方可能就是银行了,每次都会让你留下大名.今天我们就要用vue实现一个电子签名的面板 想要绘制图形,第一步想到的就是使用canvas标签,在之前的文章里我们使用canvas实现了一个前端生成图形验证码的组件,被吐槽不够安全,那么这个电子签名组件想必不会被吐槽了吧~ canvas <canvas> 标签是 HTML 5 中的新标签. <canvas> 标签只是图形容器,您必须使用脚本来绘制图形. canvas标签本身是没有绘图能力的,所有的绘制工作必须

随机推荐