
<template>
<div>
<div ref="canvasBox" style="border: 1px solid #eee">
<canvas id="canvasId" />
</div>
<div class="btnBox">
<el-button round type="primary" size="small" @click="clear">重签</el-button>
<el-button round type="success" size="small" @click="save">确定</el-button>
</div>
</div>
</template>
<script setup>
import SignaturePad from 'signature_pad'
import { reactive, defineEmits, ref, onMounted } from 'vue'
import { ElNotification } from 'element-plus'
const emit = defineEmits(['getSignature'])
const props = defineProps({})
const canvasBox = ref()
const reactData = reactive({
SignaturePad: null,
config: {
penColor: '#000000', // 笔刷颜色
minWidth: 3 // 最小宽度
}
})
onMounted(() => {
getCanvas()
})
function getCanvas() {
const canvas = document.getElementById('canvasId')
reactData.signaturePad = new SignaturePad(canvas, reactData.config)
canvas.height = 200
canvas.width = canvasBox.value.clientWidth
}
// 保存
function save() {
// console.log(this.signaturePad.isEmpty()) //判断画布有没有内容,布尔型
if (reactData.signaturePad.isEmpty()) {
ElNotification.error('电子签名不能为空')
} else {
changeBase64ToBlob(reactData.signaturePad.toDataURL())
}
}
// 清除画布内容
function clear() {
reactData.signaturePad.clear()
}
/** Base64转成 Blob 再转成 File*/
function changeBase64ToBlob(base64) {
const base64Arr = base64.split(',')
const base64String = base64Arr[1]
const bytes = atob(base64String)
const bytesCode = new ArrayBuffer(bytes.length)
const byteArray = new Uint8Array(bytesCode)
for (let i = 0; i < bytes.length; i++) {
byteArray[i] = bytes.charCodeAt(i) // 对类型化数组进行赋值
}
const blobData = new Blob([bytesCode], { type: 'application/x-png' })
const imageFile = new File([blobData], '签名图片.png') // 将blob转换为file类型
uploadImage({ file: imageFile })
}
/** 上传图片 */
function uploadImage(file) {
console.log('file', file)
const files = new FormData()
// 文件对象
files.append('files', file.file, file.file.name)
files.append('expires', 86400)
files.append('modelName', '考生签名图片')
files.append('serverName', '培训平台')
// 上传接口
emit('getSignature', res.data[0].key)
}
</script>
<style lang="scss" scoped>
.btnBox {
margin-top: 14px;
}
</style>