244 lines
5.4 KiB
Vue
244 lines
5.4 KiB
Vue
<template>
|
||
<view class="box-center">
|
||
<view class="center" id="center">
|
||
<text class="sign-area">签名区域</text>
|
||
<canvas canvas-id="jushiSignature" :style="{width:`${settings.width}rpx`,height:`${settings.height}rpx`}"
|
||
disable-scroll="true" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"></canvas>
|
||
</view>
|
||
<view class="btn-view">
|
||
|
||
<view class="clear" @click="clear()">取消</view>
|
||
<view class="reset" @click="reset()">重置</view>
|
||
<view class="save" @click="save()">签署</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
pathToBase64,
|
||
base64ToPath
|
||
} from '../image-tools/index.js'
|
||
var ctx = null
|
||
var tempPoint = [] //存放当前画纸上的轨迹点
|
||
export default {
|
||
props: {
|
||
settings: { //签名设置
|
||
type: Object,
|
||
default: () => {
|
||
return {
|
||
width: '750', //签名区域的宽
|
||
height: '500', //签名区域的高
|
||
lineWidth: 4, //签名时线宽
|
||
textColor: '#000000' //签名文字颜色
|
||
}
|
||
}
|
||
},
|
||
base64: { //是否强制返回base64
|
||
type: Boolean,
|
||
default: false
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
points: [], //路径点
|
||
canvasWidth: 0,
|
||
canvasHeight: 0
|
||
};
|
||
},
|
||
created() {
|
||
//微信小程序 需传第二个参数 this才生效
|
||
ctx = uni.createCanvasContext('jushiSignature', this)
|
||
this.setPaintStyle()
|
||
},
|
||
onReady() {
|
||
// #ifdef MP-WEIXIN
|
||
const query = uni.createSelectorQuery().in(this);
|
||
query.select('#center').boundingClientRect(data => {
|
||
this.canvasWidth = data.width
|
||
this.canvasHeight = data.height
|
||
this.setCanvasBg()
|
||
}).exec();
|
||
// #endif
|
||
},
|
||
methods: {
|
||
setPaintStyle() { //画笔样式
|
||
ctx.lineWidth = this.settings.lineWidth
|
||
ctx.lineCap = "round"
|
||
ctx.lineJoin = "round"
|
||
ctx.setStrokeStyle(this.settings.textColor)
|
||
},
|
||
touchstart(e) {
|
||
const startX = e.changedTouches[0].x
|
||
const startY = e.changedTouches[0].y
|
||
let startPoint = {
|
||
X: startX,
|
||
Y: startY
|
||
}
|
||
this.points.push(startPoint)
|
||
//每次触摸开始,开启新的路径
|
||
ctx.beginPath()
|
||
},
|
||
touchmove(e) {
|
||
let moveX = e.changedTouches[0].x
|
||
let moveY = e.changedTouches[0].y
|
||
let movePoint = {
|
||
X: moveX,
|
||
Y: moveY
|
||
}
|
||
this.points.push(movePoint); //存点
|
||
if (this.points.length >= 2) {
|
||
this.draw() //绘制路径
|
||
}
|
||
tempPoint.push(movePoint)
|
||
},
|
||
touchend() { // 清空未绘制的点避免对后续路径产生干扰
|
||
this.points = []
|
||
},
|
||
/*
|
||
* 绘制笔迹
|
||
* 1.移动的同时绘制笔迹,保证实时显示
|
||
* 2.从路径中取两个点作为起点(moveTo)和终点(lineTo)保证笔迹连续性
|
||
* 3.把上一次的终点作为下一次绘制的起点(即清除第一个点)
|
||
* */
|
||
draw() {
|
||
let p1 = this.points[0]
|
||
let p2 = this.points[1]
|
||
this.points.shift()
|
||
ctx.moveTo(p1.X, p1.Y)
|
||
ctx.lineTo(p2.X, p2.Y)
|
||
ctx.stroke()
|
||
ctx.draw(true)
|
||
},
|
||
clear() { //清空画布
|
||
let that = this
|
||
uni.getSystemInfo({
|
||
success: function(res) {
|
||
ctx.clearRect(0, 0, res.windowWidth, res.windowHeight)
|
||
ctx.draw(true)
|
||
// #ifdef MP-WEIXIN
|
||
that.setCanvasBg()
|
||
// #endif
|
||
that.setPaintStyle()
|
||
},
|
||
})
|
||
tempPoint = []
|
||
this.$emit('cancel')
|
||
},
|
||
save() { //保存
|
||
let that = this
|
||
if (tempPoint.length == 0) {
|
||
uni.showToast({
|
||
title: '您还未签名,请先签名',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
return
|
||
}
|
||
uni.canvasToTempFilePath({
|
||
canvasId: 'jushiSignature',
|
||
quality: 1,
|
||
success: function(res) {
|
||
console.log(res, '签名');
|
||
//强制返回base64
|
||
that.emit(res.tempFilePath)
|
||
},
|
||
fail(e) {
|
||
console.log(JSON.stringify(e))
|
||
}
|
||
}, this)
|
||
},
|
||
reset() {
|
||
let that = this
|
||
uni.getSystemInfo({
|
||
success: function(res) {
|
||
ctx.clearRect(0, 0, res.windowWidth, res.windowHeight)
|
||
ctx.draw(true)
|
||
// #ifdef MP-WEIXIN
|
||
that.setCanvasBg()
|
||
// #endif
|
||
that.setPaintStyle()
|
||
},
|
||
})
|
||
tempPoint = []
|
||
// 注意:这里不触发任何emit事件
|
||
},
|
||
emit(tempFilePath) {
|
||
this.$emit('change', tempFilePath)
|
||
},
|
||
setCanvasBg() { //设置canvas背景色 不设置 导出的canvas的背景为黑色
|
||
ctx.rect(0, 0, this.canvasWidth, this.canvasHeight)
|
||
ctx.setFillStyle('#ffffff')
|
||
ctx.fill()
|
||
ctx.draw()
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.box-center {
|
||
width: 95%;
|
||
overflow: hidden;
|
||
margin: 0 auto;
|
||
box-sizing: border-box;
|
||
padding-bottom: 20px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.center {
|
||
background-color: #f4f5f6;
|
||
display: flex;
|
||
flex-direction: column;
|
||
position: relative;
|
||
}
|
||
|
||
.btn-view {
|
||
margin-top: 20rpx;
|
||
font-size: 14px;
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
}
|
||
|
||
.save,
|
||
.clear,
|
||
.reset {
|
||
height: 70rpx;
|
||
width: 200rpx;
|
||
text-align: center;
|
||
font-weight: bold;
|
||
color: #979797;
|
||
border-radius: 5rpx;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 10px 30px rgba(104, 104, 104, 0.3);
|
||
// flex-direction: row;
|
||
display: flex;
|
||
border: 1px solid #e4e4e4;
|
||
border-radius: 50px;
|
||
background: #fff;
|
||
}
|
||
|
||
.save {
|
||
background: #059647;
|
||
color: white;
|
||
}
|
||
|
||
.clear {}
|
||
|
||
.reset {
|
||
background: #FF9900;
|
||
color: white;
|
||
}
|
||
|
||
.sign-area {
|
||
position: absolute;
|
||
top: 40%;
|
||
left: 15%;
|
||
color: #eeeeee;
|
||
font-size: 130rpx;
|
||
transform: rotate(-20deg);
|
||
}
|
||
|
||
</style> |