8 changed files with 314 additions and 46 deletions
@ -0,0 +1,79 @@ |
|||||
|
<template> |
||||
|
<view class="container"> |
||||
|
<view class="page-body"> |
||||
|
<view class="btn-area"> |
||||
|
<u-button type="primary" @click="sendTCP">发送TCP</u-button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { tcp: null }; |
||||
|
}, |
||||
|
|
||||
|
props: { |
||||
|
name: { type: String, default: '' }, |
||||
|
password: { type: String, default: '' }, |
||||
|
}, |
||||
|
|
||||
|
onUnload() {}, |
||||
|
onLoad() {}, |
||||
|
methods: { |
||||
|
sendTCP() { |
||||
|
console.log('发送'); |
||||
|
if (!this.tcp) { |
||||
|
this.tcp = wx.createTCPSocket(); |
||||
|
} |
||||
|
console.log('this.tcp', this.tcp); |
||||
|
this.tcp.connect({ |
||||
|
address: '192.168.4.1', |
||||
|
port: 1001, |
||||
|
}); |
||||
|
console.log('链接this.tcp', this.tcp); |
||||
|
this.tcp.write(`#${this.name}:${this.password}$`); |
||||
|
console.log('write-this.tcp', this.tcp); |
||||
|
this.tcp.onMessage((message, remoteInfo, localInfo) => { |
||||
|
console.log(message, remoteInfo, localInfo); |
||||
|
// 如果成功,关掉 tcp 返回上一页 |
||||
|
// this.tcp = null; |
||||
|
if (message) { |
||||
|
this.tcp = null; |
||||
|
this.tcp.close(); |
||||
|
this.$t.page.openPage('/pagesYanyuan/hold-all/hold-all'); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.content { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
height: 200rpx; |
||||
|
width: 200rpx; |
||||
|
margin-top: 200rpx; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
margin-bottom: 50rpx; |
||||
|
} |
||||
|
|
||||
|
.text-area { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-size: 36rpx; |
||||
|
color: #8f8f94; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,176 @@ |
|||||
|
<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