需求:用户需要手写签名(需要带笔锋)
思路:可以使用smooth-signature实现,越用力写出的字越粗
如下是效果图:
一、安装 smooth-signature
yarn add smooth-signature或者npm install smooth-signature
二、封装组件,方便复用
通过finally事件将签字内容传递出去。
<template>
<div class="sign-finish">
<div class="wrap1" v-show="isHorizontal">
<p class="sign-title">请在区域内签字</p>
<canvas class="canvas1" ref="canvas1" />
<div class="actions">
<van-button class="danger" @click="handleClear(1)">清除</van-button>
<van-button class="warning" @click="revoked(1)">撤销</van-button>
<van-button class="primary" @click="handleFull">横屏</van-button>
<van-button class="success" @click="save(1)">保存</van-button>
</div>
</div>
<div class="wrap2" v-show="!isHorizontal">
<div class="actionsWrap">
<div class="actions">
<van-button class="danger" @click="handleClear(2)">清除</van-button>
<van-button class="warning" @click="revoked(2)">撤销</van-button>
<van-button class="primary" @click="handleFull">竖屏</van-button>
<van-button class="success" @click="save(2)">保存</van-button>
</div>
</div>
<canvas class="canvas" ref="canvas2" />
</div>
</div>
</template>
<script>
import SmoothSignature from "smooth-signature";
import { Toast } from "vant";
export default {
name: "signatureMenu",
data() {
return {
isHorizontal: false,
signature1: null,
signature2: null,
};
},
mounted() {
this.initSignature();
},
methods: {
initSignature() {
const canvas1 = this.$refs.canvas1;
const canvas2 = this.$refs.canvas2;
const options1 = {
width: window.innerWidth - 30,
height: 200,
minWidth: 2,
maxWidth: 6,
openSmooth: true,
bgColor: "#f6f6f6",
};
const options2 = {
width: window.innerWidth - 120,
height: window.innerHeight - 80,
minWidth: 3,
maxWidth: 10,
openSmooth: true,
bgColor: "#f6f6f6",
};
this.signature1 = new SmoothSignature(canvas1, options1);
this.signature2 = new SmoothSignature(canvas2, options2);
},
handleClear() {
this.signature1.clear();
this.signature2.clear();
},
revoked(type = 1) {
this[`signature${type}`].undo();
},
handleFull() {
this.isHorizontal = !this.isHorizontal;
this.handleClear();
},
save(type = 1) {
const isEmpty = this[`signature${type}`].isEmpty();
if (isEmpty) {
Toast.fail(`请先完成签字`);
return;
}
// const pngUrl = this[`signature${type}`].getPNG();
const pngUrl = this[`signature${type}`].toDataURL();
this.$emit("finally", pngUrl);
console.log(pngUrl);
},
},
};
</script>
<style lang="scss" scoped>
.sign-finish {
text-align: center;
height: 100%;
box-sizing: border-box;
width: 100%;
button {
height: 32px;
padding: 0 8px;
font-size: 12px;
border-radius: 2px;
}
.danger {
color: #fff;
background: #ee0a24;
border: 1px solid #ee0a24;
}
.warning {
color: #fff;
background: #ff976a;
border: 1px solid #ff976a;
}
.primary {
color: #fff;
background: #1989fa;
border: 1px solid #1989fa;
}
.success {
color: #fff;
background: #07c160;
border: 1px solid #07c160;
}
canvas {
border-radius: 10px;
border: 2px dashed #ccc;
}
.wrap1 {
height: 100%;
width: 96%;
margin: auto;
margin-top: 100px;
.actions {
display: flex;
justify-content: space-around;
}
}
.wrap2 {
padding: 15px;
height: 100%;
display: flex;
justify-content: center;
.actionsWrap {
width: 50px;
display: flex;
justify-content: center;
align-items: center;
}
.canvas {
flex: 1;
margin: auto;
}
.actions {
margin-right: 10px;
white-space: nowrap;
transform: rotate(90deg);
button {
margin-right: 20px;
}
}
}
}
</style>