天天看点

H5移动端项目实现手写签名功能 vue实现手写签名

vue 移动端实现手写签名效果,功能很完美,保存时保存为base64格式。

base64转file文件格式 vue中将base64转file文件格式

刚好项目用到此功能,就网上找了一下,清理了无用代码,简单方便,因为项目中多个地方需要使用,所以我将它整理为组件,通过ref和传值控制,下面代码我单独整理出来,可自行封装组件(只支持移动端,不支持pc端)。

代码中,css自行修改一下宽高,背景之类即可。

代码如下

<template>

  <!-- 手写签名组件 -->

  <div class="page sign-page">

    <div class="content">

      <div class="sign-wrap" id="signWrap">

        <canvas id="myCanvas" width="100%" height="100%"></canvas>

      </div>

    </div>

    <div class="con-btn">

      <span class="staging-btn size14" @click="clearArea()">清除签名</span>

      <span class="submit-btn size14" @click="saveSign()">确认签名</span>

    </div>

  </div>

</template>

<script>

export default {

  name: "signature",

  data() {

    return {

      image: "",

      mousePressed: false,

      c: "",

      ctx: "",

      lastX: 0,

      lastY: 0,

    };

  },

  mounted() {

    this.image = "";

    this.mousePressed = false;

    var lastX, lastY;

    this.ctx = document.getElementById("myCanvas").getContext("2d");

    this.c = document.getElementById("myCanvas");

    var signWrap = document.getElementById("signWrap");

    this.c.width = signWrap.clientWidth; // 设置宽度

    this.c.height = signWrap.clientHeight; // 设置高度

    // 监听touchstart事件,touchmove事件,touchend事件等事件

    this.InitThis();

  },

  methods: {

    InitThis() {

      // 触摸屏

      var that = this;

      this.c.addEventListener(

        "touchstart",

        function (event) {

          if (event.targetTouches.length == 1) {

            event.preventDefault(); // 阻止浏览器默认事件,重要

            var touch = event.targetTouches[0];

            this.mousePressed = true;

            that.Draw(

              touch.pageX - this.offsetLeft,

              touch.pageY - this.offsetTop,

              false

            );

          }

        },

        false

      );

      this.c.addEventListener(

        "touchmove",

        function (event) {

          if (event.targetTouches.length == 1) {

            event.preventDefault(); // 阻止浏览器默认事件,重要

            var touch = event.targetTouches[0];

            if (this.mousePressed) {

              that.Draw(

                touch.pageX - this.offsetLeft,

                touch.pageY - this.offsetTop,

                true

              );

            }

          }

        },

        false

      );

      this.c.addEventListener(

        "touchend",

        function (event) {

          if (event.targetTouches.length == 1) {

            event.preventDefault(); // 阻止浏览器默认事件,防止手写的时候拖动屏幕,重要

            this.mousePressed = false;

          }

        },

        false

      );

      // 鼠标

      this.c.onmousedown = function (event) {

        this.mousePressed = true;

        that.Draw(

          event.pageX - this.offsetLeft,

          event.pageY - this.offsetTop,

          false

        );

      };

      this.c.onmousemove = function (event) {

        if (this.mousePressed) {

          that.Draw(

            event.pageX - this.offsetLeft,

            event.pageY - this.offsetTop,

            true

          );

        }

      };

      this.c.onmouseup = function (event) {

        this.mousePressed = false;

      };

    },

    Draw(x, y, isDown) {

      if (isDown) {

        this.ctx.beginPath();

        this.ctx.strokeStyle = "#000"; // 颜色

        this.ctx.lineWidth = 3; // 线宽

        this.ctx.lineJoin = "round";

        this.ctx.lineMax = 10; // 设置画笔最大线宽

        this.ctx.lineMin = 3; // 设置画笔最小线宽

        this.ctx.linePressure = 1.2; // 设置画笔笔触压力

        this.ctx.smoothness = 30; // 设置画笔笔触大小变化的平滑度

        this.ctx.moveTo(this.lastX, this.lastY);

        this.ctx.lineTo(x, y);

        this.ctx.closePath();

        this.ctx.stroke();

      }

      this.lastX = x;

      this.lastY = y;

    },

    // 清空画板

    clearArea() {

      this.ctx.setTransform(1, 0, 0, 1, 0, 0);

      this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);

    },

    // 提交签名

    saveSign() {

      this.checkEmpty(); // 调用 表单非空验证

    },

    checkEmpty() {

      var c = document.getElementById("myCanvas"); // 获取html的canvas对象,我这个id="myCanvas"

      if (this.isCanvasBlank(c)) {

        alert("请在签名区域签名后再次确认");

        return;

      } else {

        var image = this.c.toDataURL("image/png"); // 得到生成后的签名base64位  url 地址

        console.log(image); // 打印图片base64 url

      }

    },

    // 验证canvas画布是否为空函数

    isCanvasBlank(canvas) {

      var blank = document.createElement("canvas"); // 系统获取一个空canvas对象

      blank.width = canvas.width;

      blank.height = canvas.height;

      return canvas.toDataURL() == blank.toDataURL(); // 比较值相等则为空

    },

  },

};

</script>

<style scoped>

.page {

  width: 100%;

  .content {

    width: 100%;

    height: 1.7rem;

    background: url(../assets/img/photo_qmq.png) no-repeat;

    background-size: 100% 100%;

    background-position: center center;

    .sign-wrap {

      width: 100%;

      height: 100%;

    }

  }

  .con-btn {

    width: 100%;

    display: flex;

    align-content: center;

    justify-content: space-between;

    opacity: 0.75;

    span {

      font-size: 0.14rem;

      width: 100%;

      height: 0.48rem;

      display: flex;

      align-items: center;

      justify-content: center;

    }

    .staging-btn {

      color: #4154ff;

      background: #fff;

    }

    .submit-btn {

      color: #fff;

      background: #4154ff;

    }

  }

}

</style>

欢迎访问 http://www.lqzhan.cn/