最近项目组要求做一个移动端手写签名的组件
第一种实现方式:代码如下,可直接复制使用,不需要安装任何插件
<template>
<div class="page" ref="page">
<canvas ref="signHandle" class="canvas" />
<div class="btn_container van-hairline--top">
<van-button class="button" size="normal" @click="clearHandle"
>清空</van-button
>
<van-button
class="button button-right"
size="normal"
type="info"
@click="onComfirm"
>确认</van-button
>
</div>
</div>
</template>
<script>
// 解构设备的宽度, 和 高度
import Vue from 'vue'
import { Button, Toast } from 'vant'
Vue.use(Button).use(Toast)
export default {
data () {
return {
radio: '#000',
height: 50,
direction: true, // true 代表横屏, false 代表'竖屏' -- 但是亲测没有效果
el: '', // canvas dom
ctx: '', // canvas context
background: '#fff', // canvas background-color
color: '#000', // 绘制时线条的颜色
linewidth: 3, // 线条的宽度
liColors: ['#000'],
drawCheck: false, //用来判断是否签字
clientHeight: document.documentElement.clientHeight,
clientWidth: document.documentElement.clientWidth
}
},
mounted () {
window.onresize = () => {
this.clientHeight = document.documentElement.clientHeight
this.clientWidth = document.documentElement.clientWidth
this.draw()
return
}
this.draw()
},
methods: {
// 添加绘制 line
draw () {
this.$refs.signHandle.addEventListener(
'touchstart',
e => e.preventDefault(),
{
passive: false
}
)
this.el = this.$refs.signHandle
this.initCanvas()
},
// 初始化canvas配置
initCanvas () {
const { height, direction, el } = this
el.width = this.clientWidth
el.height = this.clientHeight - 50
this.ctx = el.getContext('2d')
this.setCanvas()
this.drawStart()
this.drawing()
this.drawEnd()
},
// 配置 canvas
setCanvas () {
const { ctx, height, direction } = this
console.log(direction)
// 设置背景色
ctx.fillStyle = this.background
ctx.fillRect(0, 0, this.clientWidth, this.clientHeight - 50)
// 设置线条颜色
ctx.strokeStyle = this.color
// 设置线宽
ctx.lineWidth = this.linewidth
// 设置线条两头的结束点和开始点是圆形的
ctx.lineCap = 'round'
},
// 开始绘制
drawStart () {
const { el, ctx } = this
el.addEventListener(
'touchstart',
e => {
ctx.beginPath()
ctx.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)
this.drawCheck = true //代表签过字
},
false
)
},
// 绘制中
drawing () {
const { el, ctx } = this
el.addEventListener(
'touchmove',
e => {
ctx.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY)
ctx.stroke()
},
false
)
},
// 绘制结束
drawEnd () {
const { el, ctx } = this
el.addEventListener('touchend', () => ctx.closePath(), false)
},
// 清空
clearHandle () {
console.log('清空')
this.initCanvas()
this.drawCheck = false //代表签过字
},
onComfirm () {
if (this.drawCheck == false) {
Toast.fail('请确保已经签字')
return
}
this.saveImg()
this.adminSave()
},
// 保存信息
saveImg () {
const imgBase64 = this.el.toDataURL()
console.log(imgBase64)
},
}
}
</script>
<style lang="less" scoped>
.page {
height: 100vh;
width: 100vw;
.btn_container {
width: 100%;
position: fixed;
bottom: 0;
left: 0;
background-color: #fff;
display: flex;
align-items: center;
padding: 0 8px;
box-sizing: border-box;
justify-content: space-between;
.button {
width: 50%;
}
.button-right {
margin-left: 4px;
}
}
}
.button-wrapper {
min-width: 180px;
display: flex;
justify-content: space-between;
}
</style>
第二种:安装vueEsign插件
1.安装插件: npm install vue-esign --save
2.全局引用 在main.js 中引入
import vueEsign from 'vue-esign'
Vue.use(vueEsign)
3.页面代码如下:
<template>
<div class="HelloWorld">
<div style="border: 2px solid #E6E6E6 ;background-color: white">
<vue-esign ref="esign" :width="800" :height="300" :isCrop="isCrop"
:lineWidth="lineWidth" :lineColor="lineColor" :bgColor.sync="bgColor" />
</div>
<button @click="handleReset">清空画板</button>
<button @click="handleGenerate">生成图片</button>
<img :src="resultImg" alt="">
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
lineWidth: 6,
lineColor: 'red',
bgColor: '',
resultImg: '',
isCrop: false
};
},
methods: {
handleReset () {
this.$refs.esign.reset()
},
// 生成base64格式
handleGenerate () {
this.$refs.esign.generate().then(res => {
this.resultImg = res //把base64赋给img
console.log(this.resultImg)
}).catch(err => {
alert(err) // 画布没有签字时会执行这里
})
}
}
}
</script>
<style scoped>
</style>