一時的なヘルプ友人の書き込みプロジェクトの移動端、プロジェクトには、PDF文書の署名機能を見つけましたが、また少し署名コンポーネントをトスしました
署名コンポーネント原則:イベントの終了を動かすとネイティブのキャンバスを使用し、touchstart、touchend、touchmove、署名を生成するために、最終的には、キャンバスのキャンバス上に線を引きましたが、()、toDataURL方法のbase64で画像で保存した署名を得た、と達成結果は以下の通りであります:
空のキャンバス、保存、署名のフォントの色を選択し、比較的簡単な関数
githubの上の 署名コンポーネント
コードああオン
注:このプロジェクトの用途はvant-UIを、しかし、あなたは、フォント、色、空、確認などの効果の一部が表示されない場合があり、vant-UIコンポーネントを削除することを忘れない、小さなパートナーを与えられたプレゼンテーションを見ます
1.テンプレートテンプレート
<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>
いくつかのAPI 2. jsが、説明されていない、キャンバスです。
<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>