vue 手写签名模板

2022-07-06  本文已影响0人  Pluto_7a23

最近项目需要用户签名,网上整合了一下 发一下
首先下载一个签名插件

npm i --save sign-canvas

在 main.js中

import SignCanvas from "sign-canvas";//签名插件
Vue.use(SignCanvas);

HTML中

<template>
    <div class="sign">
        <!-- <p class="sign-title">建议您调整手机,横向进行签名!</p> -->
        <div class="btnList" ref="btnList">
            <el-button type="danger" v-throttle size="small" @click="clearSignImg">清空</el-button>
            <!-- <el-button type="primary" v-throttle size="small" class="ml30 mr30" @click="saveSignImg">保存</el-button> -->
            <el-button type="primary" v-throttle size="small" @click="saveSignImg">提交</el-button>
        </div>

        <sign-canvas
        class="sign-canvas"
        ref="SignCanvas"
        :options="options"
        v-model="value"
        />
    </div>
</template>

CSS中

//设置提交按钮的样式
.btnList {
    position: fixed;
    bottom: 10%;
    left: -40%;
    width: 100%;
    padding: 20px 0;
    display: flex;
    justify-content: center;
    transform: rotate(90deg);
}
.sign{
    padding: 10px;
    overflow-x: scroll;
    .sign-title{
        font-weight: bold;
        padding: 10px 0;
    }
     .sign-canvas {
        background: #F1F1F1 !important;
        border-radius: 8px;
        position: absolute;
        right: 20px;
        border: 1px solid #000;
   }
     .signName{
        border: 1px solid #000;
    }
}

JS中

<script>
      export default {
          data() {
        return {
        value: null,
        wsobj:{},
        //配置画布
        options: {
            lastWriteSpeed: 1, //书写速度 [Number] 可选
            lastWriteWidth: 2, //下笔的宽度 [Number] 可选
            lineCap: "round", //线条的边缘类型 [butt]平直的边缘 [round]圆形线帽 [square]    正方形线帽
            lineJoin: "round", //线条交汇时边角的类型  [bevel]创建斜角 [round]创建圆角 [miter]创建尖角。
            canvasWidth: "250", //canvas宽高 [Number] 可选
            canvasHeight: "750", //高度  [Number] 可选
            isShowBorder: false, //是否显示边框 [可选]
            bgColor: "#fcc", //背景色 [String] 可选
            borderWidth: 1, // 网格线宽度  [Number] 可选
            borderColor: "#ff787f", //网格颜色  [String] 可选
            writeWidth: 3, //基础轨迹宽度  [Number] 可选
            maxWriteWidth: 50, // 写字模式最大线宽  [Number] 可选
            minWriteWidth: 5, // 写字模式最小线宽  [Number] 可选
            writeColor: "#101010", // 轨迹颜色  [String] 可选
            isSign: true, //签名模式 [Boolean] 默认为非签名模式,有线框, 当设置为true的时候没有任何线框
            imgType: "png", //下载的图片格式  [String] 可选为 jpeg  canvas本是透明背景的
            },
            isbase64:""
          };
          },
          mounted() {

          },
          methods() {
              //清除画板
               clearSignImg() {
                     this.$refs.SignCanvas.canvasClear();
                },
                 // 保存图片
                saveSignImg() {
                      if (this.value == null) {
                   this.$message({showClose: true,duration:1000,message:'请先签名',type: 'error',});
                      } else {
                      this.rotateBase64Img(this.value, 270,this.callback)   
                       }
                },
              //签名写出来的的角度不对 将base64转换度数
                rotateBase64Img(src, edg, callback) {
                     var canvas = document.createElement("canvas");
                     var ctx = canvas.getContext("2d");
                     var imgW;//图片宽度
                      var imgH;//图片高度
                      var size;//canvas初始大小
                      if (edg % 90 != 0) {
                     console.error("旋转角度必须是90的倍数!");
                               throw '旋转角度必须是90的倍数!';
                        }
                      (edg < 0) && (edg = (edg % 360) + 360)
                     const quadrant = (edg / 90) % 4; //旋转象限
                     const cutCoor = {sx: 0, sy: 0, ex: 0, ey: 0}; //裁剪坐标
                     var image = new Image();
                      image.crossOrigin = "anonymous"
                     image.src = src;
                     image.onload = function () {
                             imgW = image.width;
                            imgH = image.height;
                           size = imgW > imgH ? imgW : imgH;
                           canvas.width = size * 2;
                           canvas.height = size * 2;
                       switch (quadrant) {
                           case 0:
                              cutCoor.sx = size;
                              cutCoor.sy = size;
                              cutCoor.ex = size + imgW;
                              cutCoor.ey = size + imgH;
                               break;
                           case 1:
                                cutCoor.sx = size - imgH;
                                cutCoor.sy = size;
                                cutCoor.ex = size;
                                cutCoor.ey = size + imgW;
                               break;
                           case 2:
                                 cutCoor.sx = size - imgW;
                                 cutCoor.sy = size - imgH;
                                 cutCoor.ex = size;
                                 cutCoor.ey = size;
                               break;
                          case 3:
                                cutCoor.sx = size;
                                cutCoor.sy = size - imgW;
                                cutCoor.ex = size + imgH;
                                cutCoor.ey = size + imgW;
                             break;
            }
                        ctx.translate(size, size);
                       ctx.rotate(edg * Math.PI / 180);
                 ctx.drawImage(image, 0, 0);
                        var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
                       if (quadrant % 2 == 0) {
                               canvas.width = imgW;
                                canvas.height = imgH;
                     } else {
                      canvas.width = imgH;
                           canvas.height = imgW;
                     }
                      ctx.putImageData(imgData, 0, 0);
                          callback(canvas.toDataURL())
                     };
                 }
            },
         callback(base64data) {
        let a = this.base64toFile(base64data) //将base64转换成file流文件进行上传
          this.$confirm('请先确认签名是否正确,一旦签名成功,无法撤销', '签名确认', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            closeOnClickModal:false,
            }).then(() => {
                this.upImg(a)
            }).catch(() => {
            this.$message({
                type: 'info',
                message: '已取消删除'
            });          
                  });
           },
            base64toFile (dataurl, filename = 'file') {
                       let arr = dataurl.split(',')
                      let mime = arr[0].match(/:(.*?);/)[1]
                       let suffix = mime.split('/')[1]
                       let bstr = atob(arr[1])
                       let n = bstr.length
                        let u8arr = new Uint8Array(n)
                      while (n--) {
                           u8arr[n] = bstr.charCodeAt(n)
                           }
                     return new File([u8arr], `${filename}.${suffix}`, {
                        type: mime
                   })
             },
            //上传照片
    upImg(file){
        正常调用接口上传就可以了
      },
      }
</script>
上一篇 下一篇

猜你喜欢

热点阅读