<template>
<div>
<div>
<canvas class="canvas" id="canvas" ref="canvas"></canvas>
<canvas id="blank" style="display: none"></canvas>
<p v-else style="font-size: 240px; line-height: 360px">
请适当放慢签写速度,确保字迹清晰可辨认!
</p>
<div class="button">
<div class="signature">
<button class="re-sign" ref="clearBtn">重新签名</button>
</div>
<div class="signature">
<button class="re-sign" @click="imgcanvas">提交签名</button>
</div>
</div>
<!-- <img :src="dataURL" alt="" /> -->
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import axios from 'axios'
const canvas = ref(null)
let ctx = ref()
let canvasWidth = document.body.clientWidth
let canvasHeight = canvasWidth
const initContext = () => {
ctx = canvas.value.getContext('2d')
canvas.value.width = canvasWidth * 0.98
canvas.value.height = canvasHeight * 0.98
}
let isDrawing = false
let lastX = 0
let lastY = 0
// 重新写
let clearBtn = ref(null)
onMounted(() => {
initContext()
canvas.value.addEventListener('touchstart', function (e) {
isDrawing = true
e.preventDefault()
;[lastX, lastY] = [e.changedTouches[0].clientX, e.changedTouches[0].clientY]
})
canvas.value.addEventListener('touchmove', function (e) {
e.preventDefault()
if (isDrawing) {
ctx.beginPath()
ctx.lineWidth = 24
ctx.strokeStyle = '#007768'
ctx.moveTo(lastX, lastY)
ctx.lineTo(e.changedTouches[0].clientX, e.changedTouches[0].clientY)
ctx.stroke()
;[lastX, lastY] = [e.changedTouches[0].clientX, e.changedTouches[0].clientY]
}
})
canvas.value.addEventListener('touchend', function () {
e.preventDefault()
isDrawing = false
})
clearBtn.value.addEventListener('click', function () {
ctx.clearRect(0, 0, canvas.value.width, canvas.value.height)
})
})
const dataURL = ref()
const reader = ref()
const successing = ref(false)
//验证canvas画布是否为空
function isCanvasBlank(canvas) {
var blank = document.createElement('canvas') //系统获取一个空canvas对象
blank.width = canvas.width
blank.height = canvas.height
return canvas.toDataURL() == blank.toDataURL() //比较值相等则为空
}
// 转换为文件
let flies = ref()
const imgcanvas = async () => {
var c = document.getElementById('canvas') // 获取html的canvas对象
if (isCanvasBlank(c)) {
alert('请签名,签名后即可提交')
return
}
dataURL.value = canvas.value.toDataURL('image/png')
flies.value = base64ImgtoFile(dataURL.value)
try {
UploadFile(flies.value)
} catch (error) {
console.error('上传失败:', error)
}
}
const base64ImgtoFile = (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
})
}
//file上传至服务器
let dataimg = ref()
const UploadFile = (file) => {
let uploadkey = localStorage.getItem('uploadkey')
let fd = new FormData()
fd.append('file', file) //传文件
fd.append('type', '3') //传文件
axios.post('地址', fd).then((res) => {
//data为后端返回的上传结果,里面包含文件在服务器上的地址
dataimg.value = res.data.data //oss返回的地址
})
}
</script>