vue写uniapp打包安卓包,实现原生地图截屏(andirod同事做的)-画板编辑功能
1. 由 原生地图nvue部分,回调返回 地图截屏生成的base64 数据,
2. 通过 uni插件市场 image-tools 插件 base64ToPath方法,将base64数据 转成文件路径
3. 通过 uni -API- uni.createCanvasContext() 、ctx.createPattern() 方法,将 图片数据 创建绘图对象
4. 通过 uni - movable-area+movable-view 控制画布缩放
5. 通过 canvas @touchmove="touchmove" @touchend="touchend" @touchstart="touchstart" 等方法实现在画布上绘制画笔
6. 生成图片及清空画布
image-tools - DCloud 插件市场
import { pathToBase64, base64ToPath } from '@/js_sdk/mmmm-image-tools/index.js'
uni-app官网 API- createPattern()
initC() {
const that = this
// 创建绘图对象
this.ctx = uni.createCanvasContext('mycanvas', this);
// 在canvas设置背景 - 入参 仅支持包内路径和临时路径
const pattern = this.ctx.createPattern(this.imageUrl, 'repeat-x')
this.ctx.fillStyle = pattern
this.ctx.setStrokeStyle('red')
this.ctx.fillRect(0, 0, this.dWidth, this.dHeight)
this.ctx.draw()
// 方法二 在画布上插入图片
// this.img = new Image();
// this.img.src = this.imageUrl;
// this.img.onload = () => {
// console.log('this.img', that.img.width)
// that.ctx.drawImage(that.img, 0, 0, this.dWidth, this.dHeight)
// // that.ctx.draw()
// }
},
touchstart(e) {
let startX = e.changedTouches[0].x
let startY = e.changedTouches[0].y
if (this.scaleValue > 1) {
startX = e.changedTouches[0].x / this.scaleValue;
startY = e.changedTouches[0].y / this.scaleValue;
} else {
startX = e.changedTouches[0].x * this.scaleValue;
startY = e.changedTouches[0].y * this.scaleValue;
}
console.log('touchstart()-x', e.changedTouches[0].x, 'scaleValue', this.scaleValue, 'startX', startX)
let startPoint = { X: startX, Y: startY };
this.points.push(startPoint);
// 每次触摸开始,开启新的路径
this.ctx.beginPath();
},
touchmove(e) {
if (this.isEdit) {
let moveX = e.changedTouches[0].x
let moveY = e.changedTouches[0].y
if (this.scaleValue > 1) {
moveX = e.changedTouches[0].x / this.scaleValue;
moveY = e.changedTouches[0].y / this.scaleValue;
} else {
moveX = e.changedTouches[0].x * this.scaleValue;
moveY = e.changedTouches[0].y * this.scaleValue;
}
console.log('touchmove()-x', e.changedTouches[0].x, 'scaleValue', this.scaleValue, 'moveX', moveX)
let movePoint = { X: moveX, Y: moveY };
this.points.push(movePoint); // 存点
let len = this.points.length;
if (len >= 2) {
this.draw(); // 绘制路径
}
}
},
touchend() {
this.points = [];
},
draw() {
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() {
let that = this;
this.scaleValue = 1
this.isEdit = false
this.movableDisabled = false
uni.getSystemInfo({
success: function(res) {
let canvasw = res.windowWidth;
let canvash = res.windowHeight;
that.ctx.clearRect(0, 0, canvasw, canvash);
const pattern = that.ctx.createPattern(that.imageUrl, 'repeat-x')
that.ctx.fillStyle = pattern
that.dWidth = 285
that.dHeight = 200
that.ctx.setStrokeStyle('red')
that.ctx.fillRect(0, 0, that.dWidth, that.dHeight)
that.ctx.draw()
// that.ctx.draw(true);
}
});
},
finish() {
let that = this;
uni.canvasToTempFilePath({
canvasId: 'mycanvas',
success: function(res) {
// 这里的res.tempFilePath就是生成的签字图片
// console.log('tempFilePath', res.tempFilePath);
that.tempFilePath = res.tempFilePath
that.$emit('onImgUrl', that.tempFilePath) // 向父级组件传值
}
});
},
utils:
// 是否是 base64数据
export function isBase64Two(str) {
try {
return btoa(atob(str)) === str;
} catch (err) {
return false;
}
}
export function isBase64(str) {
// 正则表达式匹配B4-64编码格式
const regex = /^[a-zA-Z0-9+\/]+={0,2}$/;
return regex.test(str);
}
// 校验内容是否包含base64格式的图片
export function isBase64Three(str){
let imgReg = RegExp(/data:image\/.*;base64,/)
const res = imgReg.test(str)
return res
}
以下完整代码 DrawingBoard.vue:
编辑
由于hbuildex-真机调试-打印很费劲,需要来回构建打包,从而找问题找了好久,其中因为 原生地图截屏返回的是纯base64的数据,未带 data:image\/.*;base64,然后找了半天的问题,需要一步步的推导和确认有没有错,错在那,花费了很多时间和精力;