公司需要在用户培训考试后签名
费话不多说,开撸
手写签字,归根到底就是对一个canvas进行操作,我们的需要也比较简单,就不要什么花里胡哨的,只需要签名, 清除这两个功能就可以,只不过需要兼容一下web端。
其他的控制笔画粗细,控制笔画颜色,笔锋,等等没有开发。
因为这些功能根本不是我们的客户所需要的
<template>
<div class="sign-canvas">
<canvas
ref="canvas"
canvas-id="signCanvas"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
@mousedown="mouseDown"
@mousemove="mouseMove"
@mouseup="mouseUp"
/>
<div class="contents-buttons">
<div class="contents-button" @click="clearCanvas">清除</div>
<div class="contents-button" @click="saveCanvas">确定</div>
</div>
</div>
</template>
<script>
var canvas = null
var canvasTxt = null
var points = []
export default {
data() {
return {
client: {},
startX: 0,
startY: 0,
moveY: 0,
moveX: 0,
isDown: false
};
},
mounted() {
this.initCanvas()
},
methods: {
initCanvas() {
canvas = this.$refs.canvas// 指定canvas
canvas.width = window.screen.availWidth - 90
canvas.height = 400
canvasTxt = canvas.getContext('2d')// 设置2D渲染区域
canvasTxt.lineWidth = 3 // 设置线的宽度
canvasTxt.lineCap = 'round'
canvasTxt.lineJoin = 'round'
canvasTxt.fillStyle = '#fff'
canvasTxt.fillRect(0, 0, canvas.width, canvas.height)
},
// mobile
touchStart(ev) {
ev = ev || event
ev.preventDefault()
if (ev.touches.length === 1) {
const obj = {
x: ev.touches[0].clientX - canvas.offsetLeft,
y: ev.touches[0].clientY - canvas.offsetTop
}
this.startX = obj.x
this.startY = obj.y
canvasTxt.beginPath()
canvasTxt.moveTo(this.startX, this.startY)
canvasTxt.lineTo(obj.x, obj.y)
canvasTxt.closePath()
canvasTxt.stroke()
points.push(obj)
}
},
touchMove(ev) {
ev = ev || event
ev.preventDefault()
if (ev.touches.length === 1) {
const obj = {
x: ev.touches[0].clientX - canvas.offsetLeft,
y: ev.touches[0].clientY - canvas.offsetTop
}
canvasTxt.beginPath()
canvasTxt.moveTo(this.startX, this.startY)
canvasTxt.lineTo(obj.x, obj.y)
canvasTxt.stroke()
canvasTxt.closePath()
this.startX = obj.x
this.startY = obj.y
points.push(obj)
}
},
touchEnd(ev) {
ev = ev || event
ev.preventDefault()
if (ev.touches.length === 1) {
const obj = {
x: ev.touches[0].clientX - canvas.offsetLeft,
y: ev.touches[0].clientY - canvas.offsetTop
}
canvasTxt.beginPath()
canvasTxt.moveTo(this.startX, this.startY)
canvasTxt.lineTo(obj.x, obj.y)
canvasTxt.stroke()
canvasTxt.closePath()
points.push(obj)
}
},
// pc
mouseDown(ev) {
ev = ev || event
ev.preventDefault()
const obj = {
x: ev.offsetX,
y: ev.offsetY
}
this.startX = obj.x
this.startY = obj.y
canvasTxt.beginPath()
canvasTxt.moveTo(this.startX, this.startY)
canvasTxt.lineTo(obj.x, obj.y)
canvasTxt.stroke()
canvasTxt.closePath()
points.push(obj)
this.isDown = true
},
mouseMove(ev) {
ev = ev || event
ev.preventDefault()
if (this.isDown) {
const obj = {
x: ev.offsetX,
y: ev.offsetY
}
canvasTxt.beginPath()
canvasTxt.moveTo(this.startX, this.startY)
canvasTxt.lineTo(obj.x, obj.y)
canvasTxt.stroke()
canvasTxt.closePath()
this.startY = obj.y
this.startX = obj.x
points.push(obj)
}
},
mouseUp(ev) {
ev = ev || event
ev.preventDefault()
const obj = {
x: ev.offsetX,
y: ev.offsetY
}
canvasTxt.beginPath()
canvasTxt.moveTo(this.startX, this.startY)
canvasTxt.lineTo(obj.x, obj.y)
canvasTxt.stroke()
canvasTxt.closePath()
points.push(obj)
this.isDown = false
},
// 重写
clearCanvas() {
canvasTxt.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)
points = []
},
// 确定签名
async saveCanvas() {
if (points.length === 0) {
this.$toast.fail('请完成手写签名')
return
}
const file = {}
file.type = 'image/png'
file.name = 'sign.png'
file.content = this.$refs.canvas.toDataURL()
const imgFile = await this.dataURLToBlob(file)
// 上传...
},
dataURLToBlob(file) {
var arr = file.content.split(',')
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], file.name, {
type: file.type
})
}
},
};
</script>
<style lang="scss">
.sign-canvas {
background-color: white;
}
.contents-buttons {
display: flex;
justify-content: space-between;
padding: 5px 0;
border-top: 1px solid #ededed;
.contents-button {
padding: 10px 0;
text-align: center;
flex: 1;
font-size: 15px;
color: #257FFF;
}
}
</style>