<!-- 在线签名 -->
<template>
<div class="signature">
<div class="signature-content">
<div class="signature-content-inside">
<canvas class="canvas" />
</div>
</div>
<div :class="`signature-${className}`">
<div :class="`signature-${className}-navigation`">
<div :class="`signature-${className}-navigation-remark`">
<span class="tixing"
><img src="@/assets/img/tixing.png" alt="" /></span
>请在上方空白处签写名字
</div>
<div :class="`signature-${className}-navigation-buttoms`">
<van-button class="del btn" type="warning" @click="click_del"
>重签</van-button
>
<van-button class="finish btn" type="primary" @click="testDebounce"
>上传</van-button
>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import { showFailToast } from "vant";
import SignaturePad from "signature_pad";
import { UploadImage } from "@/api/index";
import router from "@/router";
import { useRoute } from "vue-router";
import { debounce } from "lodash-es";
const route = useRoute();
const data = reactive({
signaturePad: null, // 存放竖屏SignaturePad对象
signature_value: null,
loading: false,
});
const className = ref("rotate");
// 初始化画板
function init() {
const canvas = document.querySelector(".canvas");
data.signaturePad = new SignaturePad(canvas, {
minWidth: 2,
maxWidth: 2,
penColor: "rgb(0, 0, 0)",
});
const clientWidth = document.documentElement.clientWidth;
const clientHeight = document.documentElement.clientHeight;
const height = (30 * clientWidth) / 375;
const width = (90 * clientWidth) / 375;
if (clientWidth < clientHeight) {
className.value = "rotate";
// 画板高度
canvas.height = clientHeight - height;
// 画板宽度
canvas.width = clientWidth - width;
} else {
className.value = "default";
// 画板高度
canvas.height = clientHeight - width;
// 画板宽度
canvas.width = clientWidth - height;
}
}
// 清除画板
function click_del() {
if (data.signaturePad) data.signaturePad.clear();
}
// 确认画板
const click_submit = async () => {
if (data.signaturePad) data.signature_value = data.signaturePad.toDataURL();
if (!data.signature_value) return;
data.loading = true;
const bytes = window.atob(data.signature_value.split(",")[1]);
const array = [];
for (let i = 0; i < bytes.length; i++) {
array.push(bytes.charCodeAt(i));
}
const blob = new Blob([new Uint8Array(array)], { type: "image/jpeg" });
const fd = new FormData();
fd.append("img", blob, "law.jpg");
try {
const res = await UploadImage(route.query.PRId, route.query.type, 0, fd); //fd为画好的图,其他参数根据自己需要
if (res.code == 10) {
router.go(-1);
}
showFailToast("上传失败");
} catch (error) {
showFailToast("上传失败");
}
};
const testDebounce = debounce(click_submit, 500);
onMounted(() => {
init();
window.onresize = () => {
init();
};
});
</script>
<style lang="less" scoped>
.signature {
width: 100vw;
height: 100vh;
overflow: hidden;
position: relative;
display: flex;
justify-content: flex-end;
// 写字板
.signature-content {
padding: 0.9375rem;
width: calc(100vw - 5.625rem);
height: auto;
background-color: #fff;
z-index: 2;
overflow: hidden;
.signature-content-inside {
display: flex;
justify-content: flex-end;
position: relative;
background-color: rgb(242, 242, 242);
}
}
// 横屏样式
.signature-default {
z-index: 1;
.signature-default-navigation {
display: flex;
align-items: center;
justify-content: space-between;
width: 100vw;
padding: 0 0.625rem 0.9375rem;
.signature-default-navigation-remark {
font-size: 1rem;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #666666;
}
// 按钮们
.signature-default-navigation-buttoms {
display: flex;
align-items: center;
.btn {
width: 6.25rem;
height: 2.75rem;
opacity: 1;
border: none;
&.del {
background: #fff;
}
&.finish {
background: #2b8eff;
}
&:active {
position: relative;
&::after {
content: "";
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: rgba(255, 255, 255, 0.2);
}
}
}
}
}
}
// 竖屏样式
.signature-rotate {
position: absolute;
left: 4.625rem;
top: 0px;
z-index: 1;
.signature-rotate-navigation {
display: flex;
align-items: center;
justify-content: space-between;
transform: rotateZ(90deg);
transform-origin: left top;
width: 100vh;
padding: 0.9375rem;
.signature-rotate-navigation-remark {
font-size: 1rem;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #666666;
}
// 按钮们
.signature-rotate-navigation-buttoms {
display: flex;
align-items: center;
.btn {
width: 6.25rem;
height: 2.75rem;
opacity: 1;
border: none;
&.del {
background: #fff;
border: 0.0625rem solid rgba(44, 153, 254, 1);
margin-right: 0.625rem;
color: rgba(44, 153, 254, 1);
font-size: 1rem;
}
&.finish {
background: #2b8eff;
}
&:active {
position: relative;
&::after {
content: "";
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: rgba(255, 255, 255, 0.2);
}
}
}
}
}
}
.tixing {
width: 1.125rem;
height: 1.125rem;
display: inline-block;
vertical-align: middle;
font-size: 0;
img {
width: 100%;
}
}
}
</style>
拿来即用的签名,cavans签名,h5签名,签名上传
于 2023-06-09 17:04:14 首次发布