• 技术文章 >web前端 >Vue.js

    vue如何实现一个电子签名组件?

    青灯夜游青灯夜游2020-10-20 17:28:55转载515

    在生活中我们使用到电子签名最多的地方可能就是银行了,每次都会让你留下大名。今天我们就要用vue实现一个电子签名的面板

    想要绘制图形,第一步想到的就是使用canvas标签,在之前的文章里我们使用canvas实现了一个前端生成图形验证码的组件,被吐槽不够安全,那么这个电子签名组件想必不会被吐槽了吧~

    canvas

    <canvas> 标签是 HTML 5 中的新标签。<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。

    canvas标签本身是没有绘图能力的,所有的绘制工作必须在 JavaScript 内部完成。

    使用canvas绘图有几个必要的步骤:

    1. 获取canvas元素
    2. 通过canvas元素创建context对象
    3. 通过context对象来绘制图形

    在当前电子签名需求中,由于签名其实是由一条条线组成的,因此我们会用到以下几个方法:

    1. beginPath() :开始一条路径或重置当前的路径
    2. moveTo():把路径移动到画布中的指定点,不创建线条
    3. lineTo():添加一个新点,然后在画布中创建从该点到最后指定点的线条
    4. stroke():绘制已定义的路径
    5. closePath():创建从当前点回到起始点的路径

    事件

    想要在canvas中绘图,还需要绑定几个特定的事件,而这些事件在pc端和手机端不尽相同

    pc端事件

    手机端事件

    核心代码

    初始化canvas标签并绑定事件

    <canvas
            @touchstart="touchStart"
            @touchmove="touchMove"
            @touchend="touchEnd"
            ref="canvasF"
            @mousedown="mouseDown"
            @mousemove="mouseMove"
            @mouseup="mouseUp"
          ></canvas>

    获取画笔

    mounted生命周期初始化

    mounted() {
        let canvas = this.$refs.canvasF;
        canvas.height = this.$refs.canvasHW.offsetHeight - 100;
        canvas.width = this.$refs.canvasHW.offsetWidth - 10;
        this.canvasTxt = canvas.getContext("2d");
        this.canvasTxt.strokeStyle = this.color;
        this.canvasTxt.lineWidth = this.linewidth;
      }

    事件处理

    mouseDown

    //电脑设备事件
        mouseDown(ev) {
          ev = ev || event;
          ev.preventDefault();
    
          let obj = {
            x: ev.offsetX,
            y: ev.offsetY
          };
          this.startX = obj.x;
          this.startY = obj.y;
          this.canvasTxt.beginPath();//开始作画
          this.points.push(obj);//记录点
          this.isDown = true;
        },

    touchStart

    //移动设备事件
    touchStart(ev) {
    ev = ev || event;
    ev.preventDefault();
      if (ev.touches.length == 1) {
        this.isDraw = true; //签名标记
        let obj = {
          x: ev.targetTouches[0].clientX,
          y:
            ev.targetTouches[0].clientY -
            (document.body.offsetHeight * 0.5 +
              this.$refs.canvasHW.offsetHeight * 0.1)
        }; 
        //y的计算值中:document.body.offsetHeight*0.5代表的是除了整个画板signatureBox剩余的高,
        //this.$refs.canvasHW.offsetHeight*0.1是画板中标题的高
        this.startX = obj.x;
        this.startY = obj.y;
        this.canvasTxt.beginPath();//开始作画
        this.points.push(obj);//记录点
      }
    },

    mouseMove

    //电脑设备事件
        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.moveTo(this.startX, this.startY);//移动画笔
            this.canvasTxt.lineTo(obj.x, obj.y);//创建线条
            this.canvasTxt.stroke();//画线
            this.startY = obj.y;
            this.startX = obj.x;
            this.points.push(obj);//记录点
          }
        },

    touchMove

    //移动设备事件
        touchMove(ev) {
          ev = ev || event;
          ev.preventDefault();
          if (ev.touches.length == 1) {
            let obj = {
              x: ev.targetTouches[0].clientX,
              y:
                ev.targetTouches[0].clientY -
                (document.body.offsetHeight * 0.5 +
                  this.$refs.canvasHW.offsetHeight * 0.1)
            };
            this.moveY = obj.y;
            this.moveX = obj.x;
            this.canvasTxt.moveTo(this.startX, this.startY);//移动画笔
            this.canvasTxt.lineTo(obj.x, obj.y);//创建线条
            this.canvasTxt.stroke();//画线
            this.startY = obj.y;
            this.startX = obj.x;
            this.points.push(obj);//记录点
          }
        },

    mouseUp

    //电脑设备事件
        mouseUp(ev) {
          ev = ev || event;
          ev.preventDefault();
          if (1) {
            let obj = {
              x: ev.offsetX,
              y: ev.offsetY
            };
            this.canvasTxt.closePath();//收笔
            this.points.push(obj);//记录点
            this.points.push({ x: -1, y: -1 });
            this.isDown = false;
          }
        },

    touchEnd

    //移动设备事件
        touchEnd(ev) {
          ev = ev || event;
          ev.preventDefault();
          if (ev.touches.length == 1) {
            let obj = {
              x: ev.targetTouches[0].clientX,
              y:
                ev.targetTouches[0].clientY -
                (document.body.offsetHeight * 0.5 +
                  this.$refs.canvasHW.offsetHeight * 0.1)
            };
            this.canvasTxt.closePath();//收笔
            this.points.push(obj);//记录点
            this.points.push({ x: -1, y: -1 });//记录点
          }
        },

    重写

    发现自己写错字了,擦掉画板重新写过

    //重写
        overwrite() {
          this.canvasTxt.clearRect(
            0,
            0,
            this.$refs.canvasF.width,
            this.$refs.canvasF.height
          );
          this.points = [];
          this.isDraw = false; //签名标记
        },

    用到的data

    data() {
        return {
          points: [],
          canvasTxt: null,
          startX: 0,
          startY: 0,
          moveY: 0,
          moveX: 0,
          endY: 0,
          endX: 0,
          w: null,
          h: null,
          isDown: false,
          color: "#000",
          linewidth: 3,
          isDraw: false //签名标记
        };
      },

    1.jpg

    相关推荐:

    2020年前端vue面试题大汇总(附答案)

    vue教程推荐:2020最新的5个vue.js视频教程精选

    更多编程相关知识,请访问:编程入门!!

    以上就是vue如何实现一个电子签名组件?的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:segmentfault,如有侵犯,请联系admin@php.cn删除
    专题推荐:vue
    上一篇:浅谈vue.js中的Props(单向数据流) 下一篇:详解vue.js中watch的使用
    线上培训班

    相关文章推荐

    • Vue.js 学习记录之一:学习规划和了解 Vue.js• 深入理解vue响应式原理• Vue.js 学习之三:与服务器的数据交互• 详解Vue中的无渲染行为插槽• 了解一下Vue中的插槽• 使用Vue开发Chrome扩展程序的方法

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网