Trabajo temporal a un amigo Escribir un extremo móvil del proyecto, el proyecto ha encontrado su característica de la firma de un documento PDF, sino también lanzar una pequeña componente de firma
Firma principio de componente: el uso de tela nativa con el movimiento final del evento, touchstart, touchend, touchmove, fueron trazando una línea sobre la tela de lona, por último, para generar una firma, () Parada de toDataURL imagen método de base 64, consiguió la firma, y lograr resultados son los siguientes:
lienzo en blanco, seleccionar el tipo de letra color de la firma, la función de ahorro, relativamente simple
en github componente de firma
En el código ah
Nota: Este proyecto usos Vant-ui, ver la presentación que se está dado un socio pequeño, recuerde que debe eliminar el componente Vant-ui, sin embargo, no puede ver algunos de los efectos, como el color de fuente, vacío, la confirmación
1. plantilla de la plantilla
<template>
<div class="signHandle">
<canvas ref="signHandle" class="canvas" />
<div class="btn_container van-hairline--top" :style="{height:height + 'px'}">
<van-radio-group v-model="radio" class="radio_container" @change="radioHandle">
<van-radio v-for="item in liColors" :key="item" :checked-color="item" :name="item" />
</van-radio-group>
<div>
<van-button size="mini" @touchstart="clearHandle">清空</van-button>
<van-button type="info" size="mini" @touchstart="saveImg">确认</van-button>
</div>
</div>
</div>
</template>
Algunos api 2. JS, es el lienzo, no se explica
<script>
// 解构设备的宽度, 和 高度
const { clientWidth, clientHeight } = document.documentElement
export default {
data() {
return {
radio: '#000',
height: 50,
direction: false, // true 代表横屏, false 代表'竖屏'
el: '', // canvas dom
ctx: '', // canvas context
background: '#fff', // canvas background-color
color: '#000', // 绘制时线条的颜色
linewidth: 3, // 线条的宽度
liColors: ['#ee0a24', '#000', '#1890ff']
}
},
created() {
this.color = this.radio
window.addEventListener(
'onorientationchange' in window ? 'orientationchange' : 'resize',
() => {
if (window.orientation === 180 || window.orientation === 0) {
this.direction = false
this.draw()
}
if (window.orientation === 90 || window.orientation === -90) {
this.direction = true
this.draw()
}
},
false
)
},
mounted() {
this.draw()
},
methods: {
radioHandle(value) {
this.color = value
this.setCanvas()
},
// 添加绘制 line
draw() {
document.addEventListener('touchmove', e => e.preventDefault(), {
passive: false
})
this.el = this.$refs.signHandle
this.initCanvas()
},
// 初始化canvas配置
initCanvas() {
const { height, direction, el } = this
if (direction) {
el.width = clientHeight
el.height = clientWidth - height
} else {
el.width = clientWidth
el.height = clientHeight - height
}
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
// 绘制矩形
if (direction) {
ctx.fillRect(0, 0, clientHeight, clientWidth - height)
} else {
ctx.fillRect(0, 0, clientWidth, clientHeight - height)
}
// 设置线条颜色
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)
},
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() {
this.initCanvas()
},
// 保存信息
saveImg() {
const imgBase64 = this.el.toDataURL()
console.log('保存签名成功' + imgBase64)
}
}
}
</script>
3. css
.signHandle {
position: relative;
background-color: #666;
.canvas {
position: absolute;
top: 0;
left: 0;
}
.btn_container {
width: 100%;
position: fixed;
bottom: 0;
left: 0;
background-color: #fff;
display: flex;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
justify-content: space-between;
.radio_container {
display: flex;
/deep/ .van-radio {
margin-right: 10px;
&:nth-child(1) {
/deep/ .van-icon {
background-color: #ee0a24;
}
}
&:nth-child(2) {
/deep/ .van-icon {
background-color: #000;
}
}
&:nth-child(3) {
/deep/ .van-icon {
background-color: #1890ff;
}
}
}
}
}
}
</style>