借鉴文章
<template>
<view @touchmove.stop.prevent="moveHandle">
<view class="signature" v-show="showCanvas">
<canvas
class="mycanvas"
canvas-id="mycanvas"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
></canvas>
<view class="footer">
<view class="left" @click="finish">确认上传</view>
<view class="right" @click="clear">清除笔迹</view>
</view>
</view>
</view>
</template>
<script>
import Util from "@/utils/httpUtil.js";
import Local from "@/utils/local.js";
var x = 20;
var y = 20;
export default {
data() {
return {
showCanvas: false,
ctx: "", //绘图图像
points: [], //路径点集合
signature: ""
};
},
mounted() {},
onShow() {
this.createCanvas();
let that = this;
setTimeout(function() {
// 笔迹反显
if (Local.local.getItem("canvasPath")) {
let imgPath = Local.local.getItem("canvasPath");
const sInfo = uni.getSystemInfoSync();
that.ctx.drawImage(
imgPath,
0,
0,
sInfo.windowWidth,
sInfo.windowHeight
);
that.ctx.draw(true);
}
}, 500);
},
methods: {
moveHandle() {},
//关闭并清空画布
close: function() {
this.showCanvas = false;
this.clear();
},
//创建并显示画布
createCanvas: function() {
this.showCanvas = true;
this.ctx = uni.createCanvasContext("mycanvas", this); //创建绘图对象
//设置画笔样式
this.ctx.lineWidth = 4;
this.ctx.lineCap = "round";
this.ctx.lineJoin = "round";
},
//触摸开始,获取到起点
touchstart: function(e) {
let startX = e.changedTouches[0].x;
let startY = e.changedTouches[0].y;
let startPoint = { X: startX, Y: startY };
this.points.push(startPoint);
//每次触摸开始,开启新的路径
this.ctx.beginPath();
},
//触摸移动,获取到路径点
touchmove: function(e) {
let moveX = e.changedTouches[0].x;
let moveY = e.changedTouches[0].y;
let movePoint = { X: moveX, Y: moveY };
this.points.push(movePoint); //存点
let len = this.points.length;
if (len >= 2) {
this.draw(); //绘制路径
}
},
// 触摸结束,将未绘制的点清空防止对后续路径产生干扰
touchend: function() {
this.points = [];
},
/* ***********************************************
# 绘制笔迹
# 1.为保证笔迹实时显示,必须在移动的同时绘制笔迹
# 2.为保证笔迹连续,每次从路径集合中区两个点作为起点(moveTo)和终点(lineTo)
# 3.将上一次的终点作为下一次绘制的起点(即清除第一个点)
************************************************ */
draw: function() {
let point1 = this.points[0];
let point2 = this.points[1];
this.points.shift();
this.ctx.moveTo(point1.X, point1.Y);
this.ctx.lineTo(point2.X, point2.Y);
this.ctx.stroke();
this.ctx.draw(true);
},
//清空画布
clear: function() {
let that = this;
uni.getSystemInfo({
success: function(res) {
let canvasw = res.windowWidth;
let canvash = res.windowHeight;
that.ctx.clearRect(0, 0, canvasw, canvash);
that.ctx.draw(true);
}
});
},
//完成绘画并保存到本地
finish: function() {
let that = this;
uni.canvasToTempFilePath({
canvasId: "mycanvas",
success: function(res) {
console.log(res);
Local.local.setItem("canvasPath", res.tempFilePath);
uni.uploadFile({
url: Util.fileUrl + "/file/objects", //仅为示例,非真实的接口地址
filePath: res.tempFilePath,
name: "file",
header: {
authorization: Local.local.getItem("token")
},
success: uploadFileRes => {
let data = JSON.parse(uploadFileRes.data).data;
console.log(data);
Local.local.setItem("signImg", data.uri);
that.clear();
that.$Common.user.linkBack(1);
}
});
}
});
}
}
};
</script>
<style>
.signature {
position: fixed;
top: 10px;
left: 2%;
z-index: 999;
width: 96%;
}
page {
background: #fff;
}
.container {
padding: 20rpx 0 120rpx 0;
box-sizing: border-box;
}
.title {
height: 50upx;
line-height: 50upx;
font-size: 16px;
}
.mycanvas {
width: 100%;
height: calc(100vh - 220upx);
background-color: #ececec;
}
.footer {
font-size: 14px;
height: 150upx;
display: flex;
justify-content: space-around;
align-items: center;
}
.left,
.right{
line-height: 100upx;
height: 100upx;
width: 300upx;
text-align: center;
font-weight: bold;
color: white;
border-radius: 5upx;
}
.left {
background: #007aff;
}
.right {
background: orange;
}
</style>
// httpUtil.js
const host = `https://xxx/`;
let fileUrl = 'https://xxx/'; //文件服务
let imageUrl = 'https://xxx/'; //图片文件服务
let caseHost = "https://xxx/"
const fingerPkg = 'com.xxx' // 指纹采集包名
const reportBook = imageUrl + "xx" // 告知书地址
const androidPkgUrl = imageUrl + "xxxx" // 安卓安装包地址
const pageSize = 10;
var quanliyiwugaozhishu = 'https://xxx' // 权利义务告知书
var shigurendingshu = 'https://xxx' //事故认定书
var searchLetter = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
import Local from '@/utils/local.js';
import Common from '@/utils/common.js';
let httpUtil = {
getData: (url, data, method, callBack, msg) => {
// 检测网络是否可用
uni.getNetworkType({
success: function (res) {
let networkType = res.networkType;
if (networkType == 'none') {
// 无网络
uni.showToast({
title: '无网络',
icon: 'none',
duration: 500
})
} else {
var header = {
'Content-Type': 'application/json'
}
var urlString = "", dataNew = '';
if ((method == 'get' || method == 'GET') && url.indexOf('getWxConfig') < 0) {
// get 请求讲请求数据拼接在url上
for (var key in data) {
if (urlString != '') {
urlString = urlString + '&' + key + '=' + data[key]
} else {
urlString = urlString + '?' + key + '=' + data[key]
}
}
if (urlString == '') {
urlString = url;
} else {
urlString = url + urlString
}
} else {
dataNew = JSON.stringify(data)
urlString = url;
}
if (url.indexOf('getWxConfig') < 0 && url.indexOf('oauth2wx') < 0) {
if (Local.local.getItem("token") != '' && Local.local.getItem("token") != undefined) {
header.Authorization = Local.local.getItem("token")
}
}
uni.request({
method: method,
url: urlString,
data: dataNew,
header: header,
success: res => {
console.log(res)
if (msg == '更新') {
callBack(res.data)
return
}
if (urlString.indexOf('qywx/oauth2wx') >= 0) {
callBack(res.data)
}
if (res.header.token != '' && res.header.token != undefined) {
// 更新token
Local.local.setItem("token", res.header.token)
}
if (res.data.success == true) {
callBack(res.data)
} else {
if (url.indexOf("getWxConfig") >= 0) {
Local.local.removeItem('perm')
callBack("error")
} else {
if (res.data.errMessage != null && res.data.errMessage != "" && res.data.errMessage != undefined) {
uni.showToast({
title: res.data.errMessage,
icon: 'none',
duration: 2000
})
}
if (res.data.errCode == "InvalidToken") {
// token 过期到登录界面
// #ifdef APP-PLUS
wx.clearStorage()
setTimeout(function () {
uni.redirectTo({
url: "/pages/app/login/login"
})
}, 1000)
// #endif
}
}
return;
}
},
fail: err => {
uni.showToast({
title: err.message,
icon: 'none',
duration: 2000
})
}
})
}
}
})
}
}
// 输出
module.exports = {
host: host,
httpUtil: httpUtil,
imageUrl: imageUrl,
caseHost: caseHost,
pageSize: pageSize,
fileUrl: fileUrl,
searchLetter: searchLetter,
fingerPkg: fingerPkg,
reportBook: reportBook,
androidPkgUrl: androidPkgUrl,
quanliyiwugaozhishu: quanliyiwugaozhishu,
shigurendingshu: shigurendingshu
}
// local.js
let local = {
// 同步获取存储数据
getItem:key =>{
return wx.getStorageSync(key);
},
// 异步获取存储数据
getItemAsyn:(key,callBck) =>wx.getStorage({
key: key,
success:function(res){
callBck(res.data)
}
}),
// 异步设置存储数据
setItem:(key,value) =>wx.setStorage({
key: key,
data: value,
}),
setItemNow:(key,value)=>wx.setStorageSync(key, value),
// 情况缓存
clear:() => wx.clearStorage(),
// 删除异步存储数据
removeItem:key => {
let guard;
wx.removeStorage({
key: key,
success: () => guard = true,
fail: () => guard = false,
})
return guard;
},
// 异步获取storage信息
getSize:() =>{
let size;
wx.getStorageInfo({
success: res => size = res.currentSize
})
},
}
module.exports = {
local: local
}