|
|
@ -1,9 +1,5 @@ |
|
|
|
<template> |
|
|
|
<!-- <view> |
|
|
|
<canvas style="width: 300px; height: 200px" canvas-id="firstCanvas" id="firstCanvas" ref="reduceCanvas"></canvas> |
|
|
|
</view> --> |
|
|
|
|
|
|
|
<view class="indeximg"> |
|
|
|
<view class="canvas-box w-full"> |
|
|
|
<canvas style="width: 100%; height: 450px" canvas-id="firstCanvas"></canvas> |
|
|
|
</view> |
|
|
|
</template> |
|
|
@ -18,76 +14,146 @@ export default { |
|
|
|
context: null, |
|
|
|
points: [], |
|
|
|
timers: [], |
|
|
|
width: '', |
|
|
|
}; |
|
|
|
}, |
|
|
|
|
|
|
|
onReady(e) { |
|
|
|
console.log('e: ', e); |
|
|
|
this.initCanvas(); |
|
|
|
}, |
|
|
|
|
|
|
|
async mounted() { |
|
|
|
this.initCanvas(); |
|
|
|
this.drawImage(); |
|
|
|
mounted() { |
|
|
|
this.$nextTick(() => { |
|
|
|
const query = uni.createSelectorQuery().in(this); |
|
|
|
query |
|
|
|
.selectAll('.canvas-box') |
|
|
|
.boundingClientRect(data => { |
|
|
|
if (data && data.length) { |
|
|
|
this.width = data[0].width; |
|
|
|
this.clearTimers(); |
|
|
|
this.initCanvas(); |
|
|
|
this.drawImage(this.width); |
|
|
|
} |
|
|
|
}) |
|
|
|
.exec(); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
methods: { |
|
|
|
// 清除定时器 |
|
|
|
clearTimers() { |
|
|
|
if (this.timers.length) { |
|
|
|
this.timers.forEach(item => { |
|
|
|
item && clearTimeout(item); |
|
|
|
}); |
|
|
|
this.timers = []; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 初始化canvas元素 ctx数据 |
|
|
|
initCanvas() { |
|
|
|
this.canvas = this.$refs['reduceCanvas']; |
|
|
|
this.context = uni.createCanvasContext('firstCanvas', this); |
|
|
|
}, |
|
|
|
|
|
|
|
const { lines } = this.trainResult; |
|
|
|
lines.forEach((item, index) => { |
|
|
|
this.drawPath(item.line, index); |
|
|
|
// 绘制图片 |
|
|
|
drawImage(width) { |
|
|
|
const { context } = this; |
|
|
|
const { cardUrl, lines } = this.trainResult; |
|
|
|
let that = this; |
|
|
|
|
|
|
|
uni.downloadFile({ |
|
|
|
url: cardUrl, |
|
|
|
success: function (res) { |
|
|
|
context.drawImage(res.tempFilePath, 0, 0, width, 450); |
|
|
|
context.draw(true); |
|
|
|
// 绘制路径 |
|
|
|
lines.forEach(item => { |
|
|
|
that.drawPath(item, width); |
|
|
|
}); |
|
|
|
}, |
|
|
|
fail(error) { |
|
|
|
console.error('图片加载失败:', error); |
|
|
|
}, |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
* 绘制每段路径 |
|
|
|
* @param {string} str; |
|
|
|
* 绘制路径 |
|
|
|
* 图片坐标是155,194 |
|
|
|
*/ |
|
|
|
drawPath(str, index) { |
|
|
|
console.log('index: ', index); |
|
|
|
if (!this.trainResult.lines || this.trainResult.lines.length === 0) return; |
|
|
|
drawPath(str, width) { |
|
|
|
const data = this.generatePathData(str); |
|
|
|
const ctx = this.context; |
|
|
|
|
|
|
|
this.timers.push( |
|
|
|
setTimeout(() => { |
|
|
|
if (!data || data.length === 0) { |
|
|
|
if (!this.trainResult.lines || this.trainResult.lines.length === 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
this.context.beginPath(); |
|
|
|
this.context.setLineWidth(10); |
|
|
|
this.context.setStrokeStyle('#f00'); |
|
|
|
const x = +(data[0][0] / 10); |
|
|
|
const y = +(data[0][1] / 10); |
|
|
|
console.log('x, y: ', x, y); |
|
|
|
this.context.moveTo(x, y); |
|
|
|
ctx.beginPath(); |
|
|
|
ctx.setLineWidth(10); |
|
|
|
ctx.setStrokeStyle('#1890ff'); |
|
|
|
const x = (+data[0][0] * width) / 155; |
|
|
|
const y = (+data[0][1] * 450) / 194; |
|
|
|
ctx.moveTo(x, y); |
|
|
|
if (data.length === 1) { |
|
|
|
// 如果只有1个点 就画个小圆圈 |
|
|
|
this.context.arc(x, y, 2, 0, Math.PI * 2, false); |
|
|
|
this.context.fill(); |
|
|
|
ctx.arc(x, y, 2, 0, Math.PI * 2, false); |
|
|
|
ctx.fill(); |
|
|
|
} |
|
|
|
}, +data[0][2]), |
|
|
|
); |
|
|
|
|
|
|
|
for (let i = 1, len = data.length; i < len; i++) { |
|
|
|
if (!this.trainResult.lines || this.trainResult.lines.length === 0) return; |
|
|
|
this.timers.push( |
|
|
|
setTimeout(() => { |
|
|
|
if (!this.trainResult.lines || this.trainResult.lines.length === 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
this.context.lineTo(+data[i][0] / 10, +data[i][1] / 10); |
|
|
|
this.context.stroke(); |
|
|
|
// if (index === this.trainResult.lines.length - 1 && i === len - 1) { |
|
|
|
// this.drawing = false; |
|
|
|
// } |
|
|
|
}, +data[i][2]), |
|
|
|
|
|
|
|
if (i > 1) { |
|
|
|
this.clearAndDraw(data, i, width); |
|
|
|
} else { |
|
|
|
const x = (+data[i][0] * width) / 155; |
|
|
|
const y = (+data[i][1] * 450) / 194; |
|
|
|
ctx.lineTo(x, y); |
|
|
|
ctx.stroke(); |
|
|
|
ctx.draw(true); |
|
|
|
} |
|
|
|
|
|
|
|
ctx.closePath(); |
|
|
|
// }, +data[i][2]), |
|
|
|
}, this.getIntervalTime(+data[i][2], +str.operateTime, +data[0][2])), |
|
|
|
); |
|
|
|
} |
|
|
|
this.drawPoint(+data[0][0] / 10, +data[0][1] / 10); |
|
|
|
this.drawPoint(+data[data.length - 1][0] / 10, +data[data.length - 1][1] / 10); |
|
|
|
this.context.closePath(); |
|
|
|
}, |
|
|
|
|
|
|
|
clearAndDraw(data, i, width) { |
|
|
|
if (!data || data.length < 1 || i >= data.length) return; |
|
|
|
const ctx = this.context; |
|
|
|
const x = (+data[0][0] * width) / 155; |
|
|
|
const y = (+data[0][1] * 450) / 194; |
|
|
|
ctx.moveTo(x, y); |
|
|
|
for (let j = 1; j < i + 1; j++) { |
|
|
|
const x = (+data[j][0] * width) / 155; |
|
|
|
const y = (+data[j][1] * 450) / 194; |
|
|
|
ctx.lineTo(x, y); |
|
|
|
if (j === i) { |
|
|
|
ctx.stroke(); |
|
|
|
ctx.draw(true); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
|
* 计算间隔时间 |
|
|
|
* 第一条线的操作时间 |
|
|
|
* 每条线的第一个点的时间 |
|
|
|
* 时间 = (当前线条的操作时间 - 第一条线的操作时间)+ (当前点的时间-同一条线的第一个点的时间) |
|
|
|
*/ |
|
|
|
getIntervalTime(pointTime, operateTime, firstPointTime) { |
|
|
|
const { lines } = this.trainResult; |
|
|
|
let time = 0; |
|
|
|
time = operateTime - lines[0].operateTime + (pointTime - firstPointTime); |
|
|
|
return time; |
|
|
|
}, |
|
|
|
|
|
|
|
/** |
|
|
@ -96,45 +162,13 @@ export default { |
|
|
|
* @return {array} result [[x,y,time]] |
|
|
|
*/ |
|
|
|
generatePathData(str) { |
|
|
|
if (!str) return; |
|
|
|
if (!str || !str.line) return; |
|
|
|
let result = []; |
|
|
|
str.split(';').forEach(point => { |
|
|
|
str.line.split(';').forEach(point => { |
|
|
|
result.push(point.split(',')); |
|
|
|
}); |
|
|
|
return result; |
|
|
|
}, |
|
|
|
|
|
|
|
// 开始结束点 |
|
|
|
drawPoint(x, y) { |
|
|
|
const { context } = this; |
|
|
|
context.beginPath(); |
|
|
|
context.setFillStyle('#CCC'); |
|
|
|
context.arc(x, y, 4, 0, Math.PI * 3); |
|
|
|
context.fill(); |
|
|
|
context.setFillStyle('#CCC'); //颜色 |
|
|
|
context.font = 'normal 10px 微软雅黑'; //字体 |
|
|
|
context.setTextBaseline('middle'); //竖直对齐 |
|
|
|
context.setTextAlign('center'); //水平对齐 |
|
|
|
context.fillText(0, x, y, 10); //绘制文专字 |
|
|
|
}, |
|
|
|
|
|
|
|
// 绘制图片 |
|
|
|
drawImage() { |
|
|
|
const { context } = this; |
|
|
|
const { cardUrl } = this.trainResult; |
|
|
|
|
|
|
|
uni.downloadFile({ |
|
|
|
url: cardUrl, |
|
|
|
success: function (res) { |
|
|
|
context.drawImage(res.tempFilePath, 0, 0, 300, 500); |
|
|
|
context.restore(); |
|
|
|
context.draw(); |
|
|
|
}, |
|
|
|
fail(error) { |
|
|
|
console.error('图片加载失败:', error); |
|
|
|
}, |
|
|
|
}); |
|
|
|
}, |
|
|
|
}, |
|
|
|
}; |
|
|
|
</script> |
|
|
|