5 changed files with 15 additions and 182 deletions
@ -1,176 +0,0 @@ |
|||||
<template> |
|
||||
<view class="canvas-box w-full"> |
|
||||
<canvas style="width: 100%; height: 450px" canvas-id="firstCanvas"></canvas> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
props: { trainResult: { type: Object, default: () => {} } }, |
|
||||
|
|
||||
data() { |
|
||||
return { |
|
||||
canvas: null, |
|
||||
context: null, |
|
||||
points: [], |
|
||||
timers: [], |
|
||||
width: '', |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
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); |
|
||||
}, |
|
||||
|
|
||||
// 绘制图片 |
|
||||
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); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 绘制路径 |
|
||||
* 图片坐标是155,194 |
|
||||
*/ |
|
||||
drawPath(str, width) { |
|
||||
const data = this.generatePathData(str); |
|
||||
const ctx = this.context; |
|
||||
|
|
||||
this.timers.push( |
|
||||
setTimeout(() => { |
|
||||
if (!this.trainResult.lines || this.trainResult.lines.length === 0) { |
|
||||
return; |
|
||||
} |
|
||||
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个点 就画个小圆圈 |
|
||||
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; |
|
||||
} |
|
||||
|
|
||||
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])), |
|
||||
); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
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; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 生成绘制每段路径的数据 |
|
||||
* @param {string} str 每条路径的数据"x,y,time;x,y,time" |
|
||||
* @return {array} result [[x,y,time]] |
|
||||
*/ |
|
||||
generatePathData(str) { |
|
||||
if (!str || !str.line) return; |
|
||||
let result = []; |
|
||||
str.line.split(';').forEach(point => { |
|
||||
result.push(point.split(',')); |
|
||||
}); |
|
||||
return result; |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style scoped lang="scss"></style> |
|
Loading…
Reference in new issue