You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
6.6 KiB
322 lines
6.6 KiB
2 months ago
|
<template>
|
||
|
<view class="uni-list list-pd">
|
||
|
<view v-if="visibleSync" class="cat-signature" :class="{ visible: show }" @touchmove.stop.prevent="moveHandle">
|
||
|
<view class="mask" @tap="close" />
|
||
|
<view class="content">
|
||
|
<canvas
|
||
|
class="firstCanvas"
|
||
|
:canvas-id="canvasId"
|
||
|
name="autograph"
|
||
|
@touchmove="move"
|
||
|
@touchstart="start($event)"
|
||
|
@touchend="end"
|
||
|
@touchcancel="cancel"
|
||
|
@longtap="tap"
|
||
|
disable-scroll="true"
|
||
|
@error="error"
|
||
|
/>
|
||
|
<view class="btns">
|
||
|
<u-button class="btn" @tap="clear" type="primary" size="mini" text="清除签名"></u-button>
|
||
|
<u-button class="btn" @tap="close" type="primary" size="mini" text="退出签名"></u-button>
|
||
|
<u-button class="btn" @tap="save" type="primary" size="mini" text="保存到相册"></u-button>
|
||
|
</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
var content = null;
|
||
|
var touchs = [];
|
||
|
var canvasw = 0;
|
||
|
var canvash = 0;
|
||
|
/**
|
||
|
* 获取系统信息
|
||
|
* 获取系统可视区域的宽高
|
||
|
*/
|
||
|
uni.getSystemInfo({
|
||
|
success: function(res) {
|
||
|
canvasw = res.windowWidth;
|
||
|
canvash = res.windowHeight;
|
||
|
}
|
||
|
});
|
||
|
export default {
|
||
|
name: 'sign',
|
||
|
props: {
|
||
|
visible: {
|
||
|
type: Boolean,
|
||
|
default: false
|
||
|
},
|
||
|
canvasId: {
|
||
|
type: String,
|
||
|
default: 'firstCanvas'
|
||
|
}
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
show: false,
|
||
|
visibleSync: false,
|
||
|
signImage: '',
|
||
|
hasDh: false
|
||
|
};
|
||
|
},
|
||
|
watch: {
|
||
|
visible(val) {
|
||
|
this.visibleSync = val;
|
||
|
this.show = val;
|
||
|
this.getInfo();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
created(options) {
|
||
|
this.visibleSync = this.visible;
|
||
|
this.getInfo();
|
||
|
setTimeout(() => {
|
||
|
this.show = this.visible;
|
||
|
}, 100);
|
||
|
},
|
||
|
methods: {
|
||
|
getInfo() {
|
||
|
//获得Canvas的上下文
|
||
|
content = uni.createCanvasContext(this.canvasId, this);
|
||
|
//设置线的颜色
|
||
|
content.setStrokeStyle('#000');
|
||
|
//设置线的宽度
|
||
|
content.setLineWidth(5);
|
||
|
//设置线两端端点样式更加圆润
|
||
|
content.setLineCap('round');
|
||
|
//设置两条线连接处更加圆润
|
||
|
content.setLineJoin('round');
|
||
|
},
|
||
|
/**
|
||
|
* 关闭签名
|
||
|
*/
|
||
|
close() {
|
||
|
this.show = false;
|
||
|
this.hasDh = false;
|
||
|
this.$emit('close');
|
||
|
},
|
||
|
moveHandle() {},
|
||
|
/**
|
||
|
* 画布的触摸移动开始手势响应
|
||
|
*/
|
||
|
|
||
|
start(e) {
|
||
|
let point = {
|
||
|
x: e.touches[0].x,
|
||
|
y: e.touches[0].y
|
||
|
};
|
||
|
touchs.push(point);
|
||
|
this.hasDh = true;
|
||
|
},
|
||
|
// 画布的触摸移动手势响应
|
||
|
move: function(e) {
|
||
|
let point = {
|
||
|
x: e.touches[0].x,
|
||
|
y: e.touches[0].y
|
||
|
};
|
||
|
touchs.push(point);
|
||
|
if (touchs.length >= 2) {
|
||
|
this.draw(touchs);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// 画布的触摸移动结束手势响应
|
||
|
end: function(e) {
|
||
|
//清空轨迹数组
|
||
|
for (let i = 0; i < touchs.length; i++) {
|
||
|
touchs.pop();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// 画布的触摸取消响应
|
||
|
cancel: function(e) {
|
||
|
// console.log("触摸取消" + e)
|
||
|
},
|
||
|
|
||
|
// 画布的长按手势响应
|
||
|
tap: function(e) {
|
||
|
// console.log("长按手势" + e)
|
||
|
},
|
||
|
|
||
|
error: function(e) {
|
||
|
// console.log("画布触摸错误" + e)
|
||
|
},
|
||
|
|
||
|
//绘制
|
||
|
draw: function(touchs) {
|
||
|
let point1 = touchs[0];
|
||
|
let point2 = touchs[1];
|
||
|
// console.log(JSON.stringify(touchs))
|
||
|
content.moveTo(point1.x, point1.y);
|
||
|
content.lineTo(point2.x, point2.y);
|
||
|
content.stroke();
|
||
|
content.draw(true);
|
||
|
touchs.shift();
|
||
|
},
|
||
|
//清除操作
|
||
|
clear: function() {
|
||
|
// console.log(canvasw, canvash, '222');
|
||
|
//清除画布
|
||
|
content.clearRect(0, 0, canvasw, canvash);
|
||
|
content.draw(true);
|
||
|
// this.close()
|
||
|
this.hasDh = false;
|
||
|
this.$emit('clear');
|
||
|
},
|
||
|
save() {
|
||
|
var that = this;
|
||
|
if (!this.hasDh) {
|
||
|
uni.showToast({ title: '请先签字', icon: 'none' });
|
||
|
return;
|
||
|
}
|
||
|
uni.showLoading({ title: '生成中...' });
|
||
|
setTimeout(() => {
|
||
|
uni.canvasToTempFilePath(
|
||
|
{
|
||
|
canvasId: this.canvasId,
|
||
|
success: function(res) {
|
||
|
that.signImage = res.tempFilePath;
|
||
|
//把base图片保存本地一份
|
||
|
|
||
|
//触发父组件emit时间传值
|
||
|
that.$emit('save', res.tempFilePath);
|
||
|
//把base图片保存本地一份
|
||
|
// #ifdef APP-PLUS
|
||
|
uni.saveImageToPhotosAlbum({
|
||
|
filePath: res.tempFilePath,
|
||
|
success: function(res) {
|
||
|
uni.showToast({
|
||
|
title: '保存成功',
|
||
|
//将值设置为 success 或者直接不用写icon这个参数
|
||
|
icon: 'success',
|
||
|
//显示持续时间为 2秒
|
||
|
duration: 2000
|
||
|
});
|
||
|
console.log(res.path, res.errMsg.saveImageToPhotosAlbum, 'save success');
|
||
|
},
|
||
|
fail: () => {
|
||
|
uni.showToast({
|
||
|
title: '失败',
|
||
|
//将值设置为 success 或者直接不用写icon这个参数
|
||
|
//显示持续时间为 2秒
|
||
|
duration: 2000
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
// #endif
|
||
|
// #ifdef H5
|
||
|
// 获取当前时间并转成字符串,用来当做文件名
|
||
|
const date = Date.now().toString();
|
||
|
// 创建一个 a 标签
|
||
|
const a = document.createElement('a');
|
||
|
// 设置 a 标签的下载文件名
|
||
|
a.download = `${date}.png`;
|
||
|
// 设置 a 标签的跳转路径为 文件流地址
|
||
|
a.href = res.tempFilePath;
|
||
|
// 手动触发 a 标签的点击事件
|
||
|
a.click();
|
||
|
// 移除 a 标签
|
||
|
a.remove();
|
||
|
// #endif
|
||
|
uni.hideLoading();
|
||
|
that.hasDh = false;
|
||
|
that.show = false;
|
||
|
},
|
||
|
fail: function(err) {
|
||
|
console.log(err);
|
||
|
uni.hideLoading();
|
||
|
}
|
||
|
},
|
||
|
this
|
||
|
);
|
||
|
}, 100);
|
||
|
}
|
||
|
// 1
|
||
|
}
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss">
|
||
|
.cat-signature.visible {
|
||
|
visibility: visible;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
.cat-signature {
|
||
|
display: block;
|
||
|
position: fixed;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
overflow: hidden;
|
||
|
z-index: 11;
|
||
|
height: 100vh;
|
||
|
visibility: hidden;
|
||
|
.mask {
|
||
|
display: block;
|
||
|
opacity: 0;
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
background: rgba(0, 0, 0, 0.4);
|
||
|
transition: opacity 0.3s;
|
||
|
}
|
||
|
.content {
|
||
|
display: block;
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
bottom: 0;
|
||
|
right: 0;
|
||
|
margin: auto;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
background: #fff;
|
||
|
border-radius: 8upx;
|
||
|
box-shadow: 0px 3px 3px #333;
|
||
|
// canvas
|
||
|
.firstCanvas {
|
||
|
background-color: #ffffff;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
// canvas
|
||
|
|
||
|
.btns {
|
||
|
padding: 0 15px;
|
||
|
display: flex;
|
||
|
overflow: hidden;
|
||
|
position: absolute;
|
||
|
bottom: 10upx;
|
||
|
left: 0;
|
||
|
right: 0;
|
||
|
margin: auto;
|
||
|
|
||
|
.btn {
|
||
|
width: 30%;
|
||
|
text-align: center;
|
||
|
font-size: 28upx;
|
||
|
height: 60upx;
|
||
|
line-height: 60upx;
|
||
|
color: #fff;
|
||
|
border-radius: 6upx;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.visible .mask {
|
||
|
display: block;
|
||
|
opacity: 1;
|
||
|
}
|
||
|
|
||
|
.uni-list:after {
|
||
|
// 全局样式里面有一个,所以我们用白色把他隐藏起来
|
||
|
background-color: #ffffff;
|
||
|
}
|
||
|
</style>
|