canvas签名,并将签名保存在合同上vue,合同和签名合成一张图传给后台

子组建(将签名做成组建放在页面中)。**这里有一个问题****this.cxt.lineTo();**这个方法要根据合同的高度计算起点否则可能会出现名字写不出来的问题

<template>
  <div>
    <div
      id="canvas"
      ref="canvas"
    >
      <div
        class="layer"
        v-if="disPlay"
      >
      <!--原来这里做了一个功能toucheMove的时候遮罩层消失,需求想一出是一出,最后不要了六个路口以防万一-->
        <!-- <div @click="disPlay=false">请在此区域签名</div> -->
        <div>请在此区域签名</div>
      </div>
      <p
        id="clearCanvas"
        ref="clearCanvas"
      >清除</p>
      <p
        id="saveCanvas"
        ref="saveCanvas"
      >保存</p>
    </div>
    <div
      class="mySign"
      v-show="(isSign = false)"
    >
      <img
        :src="signSrc"
        alt=""
      />
    </div>
  </div>
</template>

<script>
export default {
  props: {
    imgHeight: {
      type: Number,
      default() {
        return 300;
      },
    },
  },
  data() {
    return {
      isSign: false,
      signSrc: "",
      disPlay: true,
      isDraw: false,
    };
  },
  created() {},
  mounted() {
    // console.log(this.imgHeight);
    this.$refs.canvas.focus();
    this.lineCanvas({
      el: this.$refs.canvas, //绘制canvas的父级div
      clearEl: this.$refs.clearCanvas, //清除按钮
      saveEl: this.$refs.saveCanvas, //保存按钮
    });
    this.$refs.canvas.addEventListener("touchmove", this.getStop);
  },
  methods: {
    getStop() {
      document.body.style.overflow = "hidden";
      // sessionStorage.removeItem('base64')
    },
    lineCanvas(obj) {
      this.linewidth = 2;
      this.color = "#000000";
      this.background = "#fff";
      for (var i in obj) {
        this[i] = obj[i];
      }
      // console.log(this.el)
      this.canvas = document.createElement("canvas");
      this.el.appendChild(this.canvas);
      this.cxt = this.canvas.getContext("2d");
      this.canvas.width = this.el.clientWidth;
      this.canvas.height = this.el.clientHeight;
      this.cxt.fillStyle = this.background;
      this.cxt.fillRect(0, 0, this.canvas.width, this.canvas.width);
      this.cxt.strokeStyle = this.color;
      this.cxt.lineWidth = this.linewidth;
      this.cxt.lineCap = "round";
      //开始绘制
      this.canvas.addEventListener(
        "touchstart",
        function (e) {
          // console.log(e);
          this.cxt.beginPath();
          this.cxt.moveTo(
            e.changedTouches[0].pageX,
            e.changedTouches[0].pageY - this.imgHeight
          );
        }.bind(this),
        false
      );
      //绘制中
      this.canvas.addEventListener(
        "touchmove",
        function (e) {
          // 设置一个变量判断是否进行签名
          this.isDraw = true;
          this.cxt.lineTo(
            e.changedTouches[0].pageX,
            e.changedTouches[0].pageY - this.imgHeight
          );
          this.cxt.stroke();
        }.bind(this),
        false
      );
      //结束绘制
      this.canvas.addEventListener(
        "touchend",
        function () {
          this.cxt.closePath();
          let imgBase64 = this.canvas.toDataURL();
          //console.log(imgBase64);
          this.signSrc = imgBase64;
          this.isSign = true;
        }.bind(this),
        false
      );
      //清除画布
      this.clearEl.addEventListener(
        "click",
        function () {
          // 画布被清除变量修改
          this.isDraw = false;
          this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
        }.bind(this),
        false
      );
      //保存图片,直接转base64
      this.saveEl.addEventListener(
        "click",
        function () {
          if (this.isDraw) {
            document.body.style.overflow = "scroll";
            let imgBase64 = this.canvas.toDataURL();
            // console.log(imgBase64);
            this.signSrc = imgBase64;
            // sessionStorage.setItem("base64", imgBase64);
            this.isSign = true;
            this.addComment();
          } else {
            this.$dialog.alert({ title: "温馨提示", message: "请签名" });
            return;
          }
        }.bind(this),
        false
      );
    },
    addComment() {
    //将base64的data传给父组建进行展示,为合同和签名合成作准备
      this.$emit("addComment", this.signSrc);
    },
  },
  destroyed() {
    document.body.style.overflow = "scroll";
  },
};
</script>
<style scoped>
.layer {
  width: 100%;
  position: absolute;
  bottom: 25%;
  pointer-events: none;
}
.layer > div:nth-of-type(1) {
  width: 95%;
  height: 13rem;
  margin: 0 auto;
  border: 1px dashed rgb(170, 170, 170);
  line-height: 13rem;
  font-size: 1rem;
  font-weight: 500;
  color: #a2a2a2;
}
</style>
<style scoped lang="less">
#canvas {
  width: 100%;
  height: 300px;
  position: relative;
  // canvas {
  //  position: absolute;
  //  z-index: 10;
  // }
  #clearCanvas {
    width: 50%;
    height: 40px;
    line-height: 40px;
    text-align: center;
    position: absolute;
    bottom: 0;
    left: 0;
    border: 1px solid #dedede;
    z-index: 1;
  }
  #saveCanvas {
    width: 50%;
    height: 40px;
    line-height: 40px;
    text-align: center;
    position: absolute;
    bottom: 0;
    right: 0;
    border: 1px solid #dedede;
    z-index: 1;
  }
}
.mySign {
  width: 100%;
  height: 300px;
  img {
    width: 100%;
    height: 300px;
  }
}
.test {
  width: 100%;
  height: 200px;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
}
</style>

父组建

<template>
  <div class="gzs">
    <div
      class="outs"
      ref="table"
    >
    <!--合同图片替换成你自己的-->
      <img
        ref='img'
        src="../assets/img/gzs.png"
      />
      <div
        v-if="ysShow==false"
        class="sigimg"
      >
        <img
          ref='img2'
          :src="imgUrl"
        >
      </div>
    </div>
    <signature
      v-if="ysShow"
      :imgHeight="imgHeight"
      @addComment="addComment"
    ></signature>
    <div
      class="btn"
      v-if="ysShow==false"
    >
      <div @click="submit">提交</div>
    </div>
    <!-- <img
      :src="jietuimg"
      alt=""
    > -->
  </div>
</template>

<script>
import signature from "@/components/signature";
import html2canvas from "html2canvas";
const imageConversion = require("image-conversion");

export default {
  components: { signature },
  data() {
    return {
      imgHeight: 0,
      ysShow: true,
      imgUrl: "",
      jietuimg: "",
    };
  },
  mounted() {
    this.$refs.img.onload = (e) => {
      this.imgHeight = Number(this.$refs.img.height);
    };
    this.$refs.table.addEventListener("touchmove", this.getStart);
  },
  methods: {
    getStart() {
      document.body.style.overflow = "scroll";
    },
    addComment(data) {
      this.imgUrl = data;
      this.ysShow = false;
    },
    submit() {
      this.$toast.loading({
        mask: true,
        duration: 0,
        message: "上传中",
      });
      html2canvas(this.$refs.table, {
        useCORS: true,
        backgroundColor: null,
      }).then((canvas) => {
        const dataUrl = canvas.toDataURL("images/jpg");
        this.jietuimg = dataUrl;
        // console.log(dataUrl)
        // 第一步:将dataUrl转换成Blob
        var fd = new FormData();
        var blob = this.dataURItoBlob(dataUrl);
        //fd.append("file", blob, Date.now() + ".jpg");
        // 第二步:上传分享图
        this.updateImg(blob);
      });
    },
    //上传图片
    updateImg(file) {
      // 若文件为图片则压缩
      let formData = new FormData();
      imageConversion.compressAccurately(file, 500).then((res) => {
        let resFile = new window.File(
          [res],
          "file" + Math.round(Math.random() * 10000) + ".png",
          { type: "image/jpeg" }
        );
        //formData里插入给后台传的参数,根据
        formData.append("MODULE_CODE", 10);
        formData.append("FILE_TYPR", "image");
        formData.append("CUST_ID", this.$route.query.CUST_ID);
        formData.append("CUST_TYPE", this.$route.query.CUST_TYPE);
        formData.append(
          "CUST_NAME",
          encodeURIComponent(this.$route.query.CUST_NAME)
        );
        formData.append("ID_CARD", this.$route.query.ID_CARD);
        let data = this.$base.getSecDataNoEn({
          MODULE_CODE: 10,
          FILE_TYPR: "image",
          CUST_ID: this.$route.query.CUST_ID,
          CUST_TYPE: this.$route.query.CUST_TYPE,
          CUST_NAME: encodeURIComponent(this.$route.query.CUST_NAME),
          ID_CARD: this.$route.query.ID_CARD,
        });
        formData.append("v", data.v);
        formData.append("timestamp", data.timestamp);
        formData.append("app_key", data.app_key);
        formData.append("sign", data.sign);
        formData.append("file", resFile);
        this.$api.getLivenessByFlow(formData).then((res) => {
          this.$toast.clear();
          if (res.data.RESULT_CODE == 0) {
            this.$toast("上传成功,为您跳转下一页面");
              if (this.$route.query.sode == 2) {
                let sode = localStorage.getItem("HT_WAY");
                if (sode == 1) {
                  this.$router.push({
                    name: "kk",
                    query: {
                      CUST_ID: this.$route.query.CUST_ID,
                      CUST_TYPE: this.$route.query.CUST_TYPE,
                      CUST_NAME: this.$route.query.CUST_NAME,
                      ID_CARD: this.$route.query.ID_CARD,
                    },
                  });
                } else if (sode == 2) {
                  this.$router.push({
                    name: "Step",
                    query: {
                      CUST_ID: this.$route.query.CUST_ID,
                      CUST_TYPE: this.$route.query.CUST_TYPE,
                      CUST_NAME: this.$route.query.CUST_NAME,
                      ID_CARD: this.$route.query.ID_CARD,
                      RZ_CODE: res.data.RESULT_OBJECT.RZ_CODE,
                    },
                  });
                } else if (sode == 3) {
                  this.$router.push({
                    name: "Economy",
                    query: {
                      CUST_ID: this.$route.query.CUST_ID,
                      CUST_TYPE: this.$route.query.CUST_TYPE,
                      CUST_NAME: this.$route.query.CUST_NAME,
                      ID_CARD: this.$route.query.ID_CARD,
                    },
                  });
                }
              } else {
                this.$router.push({
                  name: "kk",
                  query: {
                    CUST_ID: this.$route.query.CUST_ID,
                    CUST_TYPE: this.$route.query.CUST_TYPE,
                    CUST_NAME: this.$route.query.CUST_NAME,
                    ID_CARD: this.$route.query.ID_CARD,
                  },
                });
              }
          } else {
            this.$dialog
              .alert({
                title: "温馨提示",
                message: "res.data.RESULT_MESSAGE",
              })
              .then(() => {});
          }
        });
      });
    },
    dataURItoBlob(dataURI) {
      // base64转buffer
      var byteString = atob(dataURI.split(",")[1]);
      var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
      var ab = new ArrayBuffer(byteString.length);
      var ia = new Uint8Array(ab);
      for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new Blob([ab], { type: mimeString });
    },
    // createImg() {
    //   var image = new Image();
    //   var canvas = document.getElementById("main");
    //   image.src = canvas.toDataURL("image/png");
    //   console.log("图片内容===>", image.src);
    // },
  },
};
</script>
<style scoped>
.outs {
  position: relative;
}
.outs > img:nth-of-type(1) {
  width: 100%;
}
.sig {
  width: 100%;
  line-height: 3rem;
  font-size: 1rem;
}
.sigimg {
  width: 25%;
  position: absolute;
  bottom: 0;
  right: 0;
}
.sigimg > img {
  width: 100%;
}
.btn {
  width: 100%;
}
.btn > div {
  width: 6.6rem;
  height: 2.8rem;
  line-height: 2.8rem;
  color: #fff;
  background: #eb8f34;
  margin: 0 auto;
  margin-top: 2.3rem;
  margin-bottom: 1rem;
  font-size: 1rem;
  border-radius: 0.7rem;
}
</style>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值