vue移动端签名

141 阅读1分钟
<template>
  <div class="signature-box">
    <canvas
      id="canvas"
      ref="canvasW"
      :width="width"
      :height="height"
      style="border: 1px solid black"
      >签名</canvas
    >
   <div class="signature-button">
        <div class="button-item button-item-clear hover-class" @click="clear()">
          重写
        </div>
        <div class="button-item hover-class" @click="save()">保存签名</div>
      </div>
  </div>
</template>
<script>
var draw, canvasWidth, canvasHeight;
var preHandler = function (e) {
  if (typeof e.preventDefault === "function") {
    e.preventDefault();
  }
};
class Draw {
  constructor(el) {
    this.el = el;
    this.canvas = document.getElementById(this.el);
    this.cxt = this.canvas.getContext("2d");
    this.stage_info = canvas.getBoundingClientRect();
    this.path = {
      beginX: 0,
      beginY: 0,
      endX: 0,
      endY: 0,
    };
  }
  init(btn) {
    var that = this;
    //初始化生成
    this.canvas.addEventListener(
      "touchstart",
      function (event) {
        document.addEventListener("touchstart", preHandler, { passive: false });
        that.drawBegin(event);
      },
      { passive: false }
    );
    this.canvas.addEventListener(
      "touchend",
      function (event) {
        document.addEventListener("touchend", preHandler, { passive: false });
        that.drawEnd();
      },
      { passive: false }
    );
    this.clear(btn);
  }
  drawBegin(e) {
    var that = this;
    window.getSelection()
      ? window.getSelection().removeAllRanges()
      : document.selection.empty();

    this.cxt.strokeStyle = "#000";
    this.cxt.beginPath();
    this.cxt.moveTo(
      e.changedTouches[0].clientX - this.stage_info.left,
      e.changedTouches[0].clientY - this.stage_info.top
    );
    this.path.beginX = e.changedTouches[0].clientX - this.stage_info.left;
    this.path.beginY = e.changedTouches[0].clientY - this.stage_info.top;
    canvas.addEventListener(
      "touchmove",
      function (ev) {
        ev.preventDefault();
        that.drawing(event);
      },
      { passive: false }
    );
  }
  drawing(e) {
    this.cxt.lineTo(
      e.changedTouches[0].clientX - this.stage_info.left,
      e.changedTouches[0].clientY - this.stage_info.top
    );
    this.path.endX = e.changedTouches[0].clientX - this.stage_info.left;
    this.path.endY = e.changedTouches[0].clientY - this.stage_info.top;
    this.cxt.stroke();
  }
  drawEnd() {
    document.removeEventListener("touchstart", preHandler, false);
    document.removeEventListener("touchend", preHandler, false);
    document.removeEventListener("touchmove", preHandler, false);
  }
  clear() {
    this.cxt.clearRect(0, 0, canvasWidth, canvasHeight);
    // this.cxt.clearRect(0, 0, 373, 200)
  }
  save() {
    return canvas.toDataURL("image/png");
    console.log(canvas.toDataURL("image/png"));
  }
}

export default {
  data() {
    return {
      url: "",
      width: 0,
      height: 0,
    };
  },

  beforeDestroy() {
    window.removeEventListener("resize", this.updateWindowDimensions);
  },
  mounted() {
    this.updateWindowDimensions();
    window.addEventListener("resize", this.updateWindowDimensions);
    draw = new Draw("canvas");
    draw.init();
  },
  methods: {
    updateWindowDimensions() {
      canvasWidth = this.width = window.innerWidth - 4;
      canvasHeight = this.height = window.innerHeight - 100;
    },
    clear: function () {
      draw.clear();
      // 用于点击清除画布时,同时清除上次保存的图片
      this.save();
    },
    save: function () {
      var data = draw.save();
      console.log("data", data);
      this.url = data;
      // 生成图片的base64数据流
    },
  },
};
</script>  
<style scoped lang="less">
.signature-box {
  height: 100%;
  width: 100%;
  font-size: 0;
  #canvas {
    cursor: default;
  }

  .signature-button {
    width: 100%;
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    box-sizing: border-box;
    padding: 0 40px;
  }
  .button-item {
    width: 100px;
    height: 40px;
    border-radius: 30px;
    background: rgb(26, 148, 255);
    font-size: 16px;
    color: #fff;
    font-weight: bold;
    text-align: center;
    line-height: 40px;
  }
  .button-item-clear {
    border: 1px solid #333;
    color: #333;
    background: #fff;
  }
}
</style>