当前位置: 首页 > 工具软件 > Signature_Pad > 使用案例 >

vue项目 signature_pad实现签名手写板功能 ,base64转Blob

高嘉熙
2023-12-01

安装 signature_pad 插件

 npm install --save signature_pad

根据api文档封装一个Sign组件

<template>
  <div v-safeHeaderTop class="page">
    <Header :isBack="false" title="手写签名"> </Header>
    <canvas ref="signaturePadCanvas" class="canvas"></canvas>
    <div v-safeBottom class="button-view">
      <div v-for="(x, i) in ['取消', '重写', '确认']" :key="i" class="item" @click="itemClick(i)">{{ x }}</div>
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import SignaturePad from "signature_pad";
import { uploadFile } from "@api/home/index";
import { getToken } from "@/utils/auth";

@Component({
  name: "Sign",
})
export default class Sign extends Vue {
  signaturePad: any = null;
  mounted() {
    // 屏幕旋转
    if (this.$API) {
      this.$API.setScreenOrientation({
        orientation: "landscape_left",
      });
    }
    // 初始化写字板
    const canvas = this.$refs.signaturePadCanvas;
    this.signaturePad = new SignaturePad(canvas as any);
    window.addEventListener("resize", this.resizeCanvas);
    this.resizeCanvas();
  }
  destroyed() {
    if (this.$API) {
      this.$API.setScreenOrientation({
        orientation: "auto",
      });
    }
  }
  itemClick(i: number) {
    switch (i) {
      case 0:
        this.signaturePad.clear();
        this.$emit("cancel");
        break;
      case 1:
        this.signaturePad.clear();
        break;
      case 2:
        if (this.signaturePad.isEmpty()) {
          console.log("签名为空");
          return;
        }
        var data = this.signaturePad.toDataURL();
        var fd = new FormData();
        var blob = this.dataURItoBlob(data);
        fd.append("file", blob);
        fd.append("token", getToken() || "");
        this.uploadFile(fd);
        break;
    }
  }
  // 上传生成的签名图片
  async uploadFile(fd: any) {
    const { order_id } = this.$route.query;
    const loading = this.$toast.loading("生成中...");
    const { data } = await uploadFile(fd, {
      params: {
        ext: "png",
        type: 1,
        order_uid: order_id,
      },
    });
    const url = data.file_path;
    this.$emit("confirm", url);
    loading.clear();
  }
  // base64转Blob
  dataURItoBlob(dataURI: string) {
    var byteString = window.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 });
  }
  // 重置写字板
  resizeCanvas() {
    const canvas: any = this.$refs.signaturePadCanvas;
    const ratio = Math.max(window.devicePixelRatio || 1, 1);
    canvas.width = canvas.offsetWidth * ratio;
    canvas.height = canvas.offsetHeight * ratio;
    canvas.getContext("2d").scale(ratio, ratio);
    this.signaturePad.clear();
  }
}
</script>

<style lang="scss" scoped>
.canvas {
  height: calc(100% - 65px);
  width: 100%;
}
.button-view {
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  background: #fff;
  .item {
    padding: 6px 20px;
    background: #3a5be4;
    border-radius: 8px;
    color: #fff;
    margin-right: 10px;
  }
}
</style>

页面调用即可

    <van-popup v-model="show" position="right" get-container="body" :overlay="false">
      <Sign  @cancel="show = false" @confirm="confirm" />
    </van-popup>

 类似资料: