<template>
<div>
<div class="fixed_header">
<div>采集电子签名</div>
<div class="header_icon" @click="goBack">
<img :src="require('@/images/back.png')" alt="">
</div>
</div>
<div id="signature-pop">
<div id="signature-container">
<div class="demo-top-info" id="rotate-container">
<div class="return" id="return">返回</div>
<div class="signature-title text-center">手写签名</div>
</div>
<div class="canvas-container">
<div class="canvas-parent">
<canvas id="canvas"></canvas>
</div>
</div>
<div class="demo-bottom-info" :class="{'demo-bottom-key':!entershuping}" id="demo-bottom-info">
<div class="empey" :class="{'entershuping':!entershuping}">请收款人在上方空白处手写您的签名</div>
<div id="clean_canvas" :class="{'entershuping':!entershuping}">清除重写</div>
<div id="sure_canvas" :class="{'disabled':disabledBtn,'entershuping':!entershuping}">确认签名</div>
</div>
</div>
<canvas id="canvas2"></canvas>
</div>
</div>
</template>
<script>
import { uploadImg } from "@/api/driverCertification.js";
import { imgUpload } from "@/utils/enumeration.js";
export default {
data() {
return {
disabledBtn:false,
entershuping:true,
};
},
mounted() {
// 手绘签名类
let _this = this
var SignatureClass = (function () {
//获取当前位置(返回px)
function getStyle(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
}
function Signatrue(options) {
this.cavnas = null;
this.ctx = null;
this.maxparams = {};
this.minparams = {};
this.entershuping = true; //是否是竖屏 true=是
this.firstTouch = true; // 第一次点击或touch
this.allowSubmit = false; // 是否手写了内容 是=才能提交 否=不能提交
if (options === void 0) {
options = {};
}
this.options = options;
}
// 初始化
Signatrue.prototype.init = function () {
var self = this;
console.log(
getStyle(document.getElementById("rotate-container"), "height")
); // 不知道为什么加,否则有些Apple出问题
this.hengshuping();
this.clear();
this.submit();
window.addEventListener(
"resize",
function () {
self.hengshuping();
},
false
);
};
// 判断横竖屏
Signatrue.prototype.hengshuping = function () {
if (window.orientation == 90 || window.orientation == -90) {
this.entershuping = false; // 横屏
_this.entershuping = false
document.getElementById("canvas2").style.display = "none";
document.getElementById("canvas").style.display = "block";
this.canvas = document.getElementById("canvas");
this.ctx = this.canvas.getContext("2d");
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "#000000";
this.drawEvent();
document.querySelector("#signature-container").style.width =
window.innerWidth + "px";
document.querySelector("#signature-container").style.height =
window.innerHeight + "px";
this.canvas.height = parseInt(
getStyle(document.getElementById("canvas").parentNode, "height")
);
this.canvas.width = parseInt(
getStyle(document.getElementById("canvas").parentNode, "width")
);
document.querySelector("#signature-container").style.transform =
"rotate(0deg)";
document.querySelector("#signature-container").style.transformOrigin =
"0 0";
document.querySelector("#signature-container").style.marginLeft =
"0px";
} else {
// 竖屏
this.entershuping = true;
_this.entershuping = true
document.getElementById("canvas").style.display = "none";
document.getElementById("canvas2").style.display = "block";
this.canvas = document.getElementById("canvas2");
this.ctx = this.canvas.getContext("2d");
this.canvas.height = window.innerHeight;
let signatureContainerDom = document.querySelector("#signature-container")
let demoBottomInfoDom = document.getElementById("demo-bottom-info")
this.canvas.width =
window.innerWidth -
demoBottomInfoDom.offsetHeight;
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "#000000";
this.drawEvent();
signatureContainerDom .style.width =
window.innerHeight + "px";
signatureContainerDom .style.height =
window.innerWidth + "px";
signatureContainerDom .style.transform =
"rotate(90deg)";
signatureContainerDom .style.transformOrigin =
"0 0";
signatureContainerDom .style.marginLeft =
window.innerWidth + "px";
}
};
// 绘画事件
Signatrue.prototype.drawEvent = function () {
var self = this;
this.canvas.addEventListener("touchstart", function (evt) {
var oEvent = evt || event;
oEvent.preventDefault();
var position = self.pos(oEvent);
self.ctx.beginPath();
self.ctx.moveTo(position.x, position.y);
if (self.firstTouch) {
self.minparams = {
x: position.x,
y: position.y,
};
self.maxparams = {
x: position.x,
y: position.y,
};
self.firstTouch = false;
} else {
self.judgeSize(position);
}
self.canvas.addEventListener("touchmove", touchmove, false);
function touchmove(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
var position = self.pos(oEvent);
self.ctx.lineTo(position.x, position.y);
self.judgeSize(position);
self.ctx.stroke();
}
document.addEventListener("touchend", touchend, false);
function touchend(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
self.allowSubmit = true;
self.canvas.removeEventListener("touchmove", touchmove);
document.removeEventListener("touchend", touchend);
}
});
};
// 清空画笔
Signatrue.prototype.clear = function () {
var self = this;
document
.getElementById("clean_canvas")
.addEventListener("click", function () {
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
self.allowSubmit = false;
});
};
// 提交画笔内容
Signatrue.prototype.submit = function () {
var self = this;
document
.getElementById("sure_canvas")
.addEventListener("click", function () {
if (self.allowSubmit) {
var imgSRC = self.canvas.toDataURL("image/png", 1);
var img = new Image();
img.src = imgSRC;
// self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
img.onload = function () {
var width = self.maxparams.x - self.minparams.x;
var height = self.maxparams.y - self.minparams.y;
var targetWidth = 200;
var targetHeight = 100;
var clipCanvas = document.createElement("canvas");
clipCanvas.width = targetWidth;
clipCanvas.height = targetHeight;
var ctx2 = clipCanvas.getContext("2d");
if (self.entershuping) {
ctx2.translate(0, targetHeight);
ctx2.rotate((-90 * Math.PI) / 180);
ctx2.drawImage(
img,
self.minparams.x,
self.minparams.y,
width,
height,
0,
0,
targetHeight,
targetWidth
);
} else {
ctx2.drawImage(
img,
self.minparams.x,
self.minparams.y,
width,
height,
0,
0,
targetWidth,
targetHeight
);
}
var imgSRC2 = clipCanvas.toDataURL("image/png", 1);
console.log("imgSRC2==", imgSRC2);
if(self.options && self.options.callback && typeof self.options.callback == 'function') {
self.options.callback(imgSRC2);
}
// self.canvas = null;
// self.ctx = null;
// ctx2 = null;
// clipCanvas = null;
};
} else {
// alert("没有手写签名,不能提交!");
}
});
};
// 获取当前位置
Signatrue.prototype.pos = function (event) {
var x = event.touches[0].pageX - event.target.offsetLeft;
var y = event.touches[0].pageY - event.target.offsetTop;
return {
x: x,
y: y,
};
};
// 优化画笔界限,去掉空白区域
Signatrue.prototype.judgeSize = function (value) {
if (this.minparams.x > value.x) {
this.minparams.x = value.x;
}
if (this.maxparams.x < value.x) {
this.maxparams.x = value.x;
}
if (this.minparams.y > value.y) {
this.minparams.y = value.y;
}
if (this.maxparams.y < value.y) {
this.maxparams.y = value.y;
}
};
return Signatrue;
})();
var signatrueDraw = new SignatureClass({
callback: function (base64) {
console.log(base64)
if(_this.disabledBtn){
return
}
_this.disabledBtn = true
_this.handleCompessUpload(
base64,
imgUpload,
(res) => {
_this.disabledBtn = false
console.log("{res.imgUrl==",res.imgUrl)
_this.$router.replace({
path: `/drive/saveSign?signUrl=${res.imgUrl}`,
});
},
"",
(res) => {}
);
},
});
signatrueDraw.init();
},
methods: {
goBack(){
this.$router.go(-1)
},
dataURLtoBlob(dataurl) {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
},
//上传前压缩
handleCompessUpload(
file,
uploadUrl,
uploadCallBack,
ocrLoadUrl,
ocrLoadCallback
) {
let self = this;
let Orientation;
let ndata;
let _fileBlob = this.dataURLtoBlob(file);
let fileOfBlob = new File([_fileBlob], new Date() + ".jpg");
self.postImg(
2,
fileOfBlob,
uploadUrl,
(res) => {
uploadCallBack && uploadCallBack(res);
},
ocrLoadUrl,
(res) => {
ocrLoadCallback && ocrLoadCallback(res);
}
);
},
async postImg(
type,
blob,
uploadUrl,
uploadCallBack,
ocrLoadUrl,
ocrLoadCallback
) {
let fd;
if (type == 1) {
let filename = `${new Date().getTime()}.jpg`;
let file = new File([blob], filename, { type: "image/jpg" });
fd = new FormData();
fd.append("file", file);
} else {
fd = new FormData();
fd.append("file", blob);
}
uploadImg(uploadUrl, fd).then((res) => {
console.log(res, "res===");
if (res.data) {
uploadCallBack && uploadCallBack(res.data);
}
});
if (ocrLoadUrl) {
uploadImg(ocrLoadUrl, fd).then((res) => {
if (res.data) {
ocrLoadCallback && ocrLoadCallback(res.data);
}
});
}
},
compress(img, Orientation) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
//瓦片canvas
let tCanvas = document.createElement("canvas");
let tctx = tCanvas.getContext("2d");
let initSize = img.src.length;
let width = img.width;
let height = img.height;
//如果图片大于四百万像素,计算压缩比并将大小压至400万以下
let ratio;
if ((ratio = (width * height) / 4000000) > 1) {
console.log("大于400万像素");
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
// 铺底色
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
//如果图片像素大于100万则使用瓦片绘制
let count;
if ((count = (width * height) / 1000000) > 1) {
console.log("超过100W像素");
count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
// 计算每块瓦片的宽和高
let nw = ~~(width / count);
let nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(
img,
i * nw * ratio,
j * nh * ratio,
nw * ratio,
nh * ratio,
0,
0,
nw,
nh
);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
//修复ios上传图片的时候 被旋转的问题
// if (Orientation != "" && Orientation != 1) {
// switch (Orientation) {
// case 6: //需要顺时针(向左)90度旋转
// this.rotateImg(img, "left", canvas);
// break;
// case 8: //需要逆时针(向右)90度旋转
// this.rotateImg(img, "right", canvas);
// break;
// case 3: //需要180度旋转
// this.rotateImg(img, "right", canvas); //转两次
// this.rotateImg(img, "right", canvas);
// break;
// }
// }
//进行最小压缩
let ndata = canvas.toDataURL("image/jpeg", 0.1);
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return ndata;
},
},
};
</script>
<style lang="scss" scoped>
.fixed_header{
position:fixed;
left: 0px;
top:0px;
line-height: 0.88rem;
width: 100%;
z-index: 100;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid #F2F3F7;
.header_icon{
position:absolute;
height: 0.88rem;
left: 0px;
top:0px;
width: 1rem;
display: flex;
justify-content: center;
align-items: center;
img{
// position:absolute;
// left: 0.3rem;
// top: 50%;
width:0.2rem ;
height: 0.36rem;
// transform: translateY(-50%);
}
}
}
.text-center {
text-align: center;
}
#signature-button {
display: block;
margin: 0 auto;
}
#signature-img {
width: 200px;
height: 100px;
margin: 10px auto;
display: none;
}
#signature-pop {
position: fixed;
background-color: #fff;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
/* display: none; */
}
#signature-container {
/* width: 100%;
height: 100%; */
width: 812px;
height: 375px;
transform: rotate(90deg);
transform-origin: 0px 0px;
margin-left: 375px;
}
.demo-top-info {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 40px;
background: #cccccc;
box-sizing: border-box;
text-align: center;
display: none;
}
.demo-top-info .return {
padding-left: 5px;
height: 40px;
line-height: 40px;
position: absolute;
left: 10px;
display: inline-block;
}
.signature-title {
height: 40px;
line-height: 40px;
display: inline-block;
}
.canvas-container {
width: 100%;
height: 100%;
background-color: #ffffff;
box-sizing: border-box;
}
.canvas-parent {
width: 100%;
height: 100%;
}
.demo-bottom-info {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: #fff;
box-sizing: border-box;
overflow: hidden;
display: flex;
justify-content: space-around;
align-items: center;
border-top: 1px solid #f5f6fa;
padding-left: 0.88rem;
&.demo-bottom-key{
padding-left: 0rem;
}
}
.empey {
// width: 4.8rem;
height: 1.5rem;
font-size: 0.28rem;
font-weight: 500;
display: flex;
justify-content: center;
align-items: center;
&.entershuping{
font-size: 0.24rem;
}
}
#clean_canvas {
font-size: 0.3rem;
font-weight: 500;
background: #fff;
border: 1px solid #989db2;
padding: 10px 15px;
border-radius: 4px;
color: #ff0000;
&.entershuping{
font-size: 0.24rem;
}
}
#sure_canvas {
background: #0f7dfc;
padding: 10px 15px;
border: 1px solid #0f7dfc;
border-radius: 4px;
color: #fff;
font-size: 0.3rem;
font-weight: 500;
&.entershuping{
font-size: 0.24rem;
}
}
#canvas2 {
position: absolute;
top: 0;
left: 0;
z-index: 999;
margin-left: 1.5rem;
}
</style>
手写电子签名 横屏和竖屏
最新推荐文章于 2022-04-13 11:23:23 发布