H5中 手写签名

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

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>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值