|
@@ -1,3 +1,16 @@
|
|
|
+const formatDateTime = (date) => {
|
|
|
+ if (!date) return
|
|
|
+ const dateObj = new Date(date)
|
|
|
+ const year = dateObj.getFullYear()
|
|
|
+ const month = String(dateObj.getMonth() + 1).padStart(2, '0')
|
|
|
+ const day = String(dateObj.getDate()).padStart(2, '0')
|
|
|
+ const hours = String(dateObj.getHours()).padStart(2, '0')
|
|
|
+ const minutes = String(dateObj.getMinutes()).padStart(2, '0')
|
|
|
+ const seconds = String(dateObj.getSeconds()).padStart(2, '0')
|
|
|
+
|
|
|
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
|
|
+}
|
|
|
+
|
|
|
const yieldCPU = () => {
|
|
|
return new Promise((resolve) => {
|
|
|
setTimeout(resolve, 0)
|
|
@@ -14,7 +27,7 @@ const initWasm = (url) => {
|
|
|
drawPlc('DO', i, _GetTrustDO(i))
|
|
|
}
|
|
|
for (let i = 0; i < 2; i++) {
|
|
|
- drawPlc('AO', i, _GetTrustAO(i))
|
|
|
+ drawPlc('AO', i, Math.floor(_GetTrustAO(i) / 100))
|
|
|
}
|
|
|
drawPlc('time', 0, _GetTimeStamp())
|
|
|
await yieldCPU() // 让出cpu,保证有间隔进入消息接收回调
|
|
@@ -30,26 +43,58 @@ const canvasMsg = {
|
|
|
height: 0
|
|
|
}
|
|
|
|
|
|
+let distance = 48 // 每个模块间隔
|
|
|
+let textDis = 60
|
|
|
+let r = 18
|
|
|
+let l_r_dis = 25
|
|
|
const drawPlc = async (key, index, val, type) => {
|
|
|
if (!ctx) return
|
|
|
- const distance = 48 // 每个模块间隔
|
|
|
- const textDis = 95
|
|
|
- const r = 18
|
|
|
- const l_r_dis = 50
|
|
|
- ctx.font = '24px 黑体'
|
|
|
+ ctx.font = `${16 * ratioPixel}px 黑体`
|
|
|
ctx.textAlign = 'start'
|
|
|
ctx.globalAlpha = 1
|
|
|
if (type === 'init') {
|
|
|
ctx.beginPath()
|
|
|
- ctx.rect(l_r_dis - r - 10, 50 - r - 10, (r + 10) * 2, distance * 11 + r / 4)
|
|
|
- ctx.rect(l_r_dis - r - 10, 50 - r - 10 + distance * 11 + r / 4, (r + 10) * 2, distance * 2)
|
|
|
- ctx.rect(l_r_dis - r - 10, 50 - r - 10 + distance * 13 + r / 4, (r + 10) * 2, distance * 2)
|
|
|
+ const modBetweenDis = (distance - 2 * r) / 2
|
|
|
+ const safeDis = 10
|
|
|
+ ctx.rect(
|
|
|
+ l_r_dis - r - safeDis,
|
|
|
+ l_r_dis - r - safeDis,
|
|
|
+ (r + safeDis) * 2,
|
|
|
+ distance * 10 + r * 2 + safeDis + modBetweenDis
|
|
|
+ )
|
|
|
+ ctx.rect(l_r_dis - r - safeDis, l_r_dis + distance * 10 + r + modBetweenDis, (r + safeDis) * 2, distance * 2)
|
|
|
+ ctx.rect(l_r_dis - r - safeDis, l_r_dis + distance * 12 + r + modBetweenDis, (r + safeDis) * 2, distance * 2)
|
|
|
|
|
|
- ctx.rect(canvasMsg.width - l_r_dis - r - 10, 50 - r - 10, (r + 10) * 2, distance * 11 + r / 4)
|
|
|
- ctx.rect(canvasMsg.width - l_r_dis - r - 10, 50 + distance * 11 - r - 10 + r / 4, (r + 10) * 2, distance * 5)
|
|
|
- ctx.rect(canvasMsg.width - l_r_dis - r - 10, 50 + distance * 16 - r - 10 + r / 4, (r + 10) * 2, distance * 2)
|
|
|
- ctx.rect(canvasMsg.width - l_r_dis - r - 10, 50 + distance * 18 - r - 10 + r / 4, (r + 10) * 2, distance * 2)
|
|
|
- ctx.rect(canvasMsg.width - l_r_dis - r - 10, 50 + distance * 20 - r - 10 + r / 4, (r + 10) * 2, distance * 2)
|
|
|
+ ctx.rect(
|
|
|
+ canvasMsg.width - l_r_dis - r - safeDis,
|
|
|
+ l_r_dis - r - safeDis,
|
|
|
+ (r + safeDis) * 2,
|
|
|
+ distance * 10 + r * 2 + safeDis + modBetweenDis
|
|
|
+ )
|
|
|
+ ctx.rect(
|
|
|
+ canvasMsg.width - l_r_dis - r - safeDis,
|
|
|
+ l_r_dis + distance * 10 + r + modBetweenDis,
|
|
|
+ (r + safeDis) * 2,
|
|
|
+ distance * 5
|
|
|
+ )
|
|
|
+ ctx.rect(
|
|
|
+ canvasMsg.width - l_r_dis - r - safeDis,
|
|
|
+ l_r_dis + distance * 15 + r + modBetweenDis,
|
|
|
+ (r + safeDis) * 2,
|
|
|
+ distance * 2
|
|
|
+ )
|
|
|
+ ctx.rect(
|
|
|
+ canvasMsg.width - l_r_dis - r - safeDis,
|
|
|
+ l_r_dis + distance * 17 + r + modBetweenDis,
|
|
|
+ (r + safeDis) * 2,
|
|
|
+ distance * 2
|
|
|
+ )
|
|
|
+ ctx.rect(
|
|
|
+ canvasMsg.width - l_r_dis - r - safeDis,
|
|
|
+ l_r_dis + distance * 19 + r + modBetweenDis,
|
|
|
+ (r + safeDis) * 2,
|
|
|
+ distance * 2
|
|
|
+ )
|
|
|
ctx.stroke()
|
|
|
ctx.closePath()
|
|
|
|
|
@@ -57,152 +102,180 @@ const drawPlc = async (key, index, val, type) => {
|
|
|
ctx.beginPath()
|
|
|
// ctx.fillStyle = val !== 0 ? 'green' : 'red'
|
|
|
ctx.fillStyle = 'red'
|
|
|
- ctx.arc(canvasMsg.width - l_r_dis, 50 + distance * 11, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(canvasMsg.width - l_r_dis, l_r_dis + distance * 11, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
const GND_textInfo = ctx.measureText(`GND`)
|
|
|
ctx.fillStyle = 'black'
|
|
|
ctx.fillText(
|
|
|
`GND`,
|
|
|
canvasMsg.width - textDis - GND_textInfo.width,
|
|
|
- 50 + distance * 11 + GND_textInfo.actualBoundingBoxAscent / 2
|
|
|
+ l_r_dis + distance * 11 + GND_textInfo.actualBoundingBoxAscent / 2
|
|
|
)
|
|
|
|
|
|
// left com
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = 'red'
|
|
|
- ctx.arc(l_r_dis, 50, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(l_r_dis, l_r_dis, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
const textInfo = ctx.measureText('COM')
|
|
|
ctx.fillStyle = 'black'
|
|
|
- ctx.fillText('COM', textDis, 50 + textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('COM', textDis, l_r_dis + textInfo.actualBoundingBoxAscent / 2)
|
|
|
|
|
|
// right com
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = 'red'
|
|
|
- ctx.arc(canvasMsg.width - l_r_dis, 50, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(canvasMsg.width - l_r_dis, l_r_dis, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
ctx.fillStyle = 'black'
|
|
|
- ctx.fillText('COM', canvasMsg.width - textDis - textInfo.width, 50 + textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('COM', canvasMsg.width - textDis - textInfo.width, l_r_dis + textInfo.actualBoundingBoxAscent / 2)
|
|
|
|
|
|
// RS485
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = '#a3a3a3'
|
|
|
- ctx.arc(l_r_dis, 50 + 11 * distance, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(l_r_dis, l_r_dis + 11 * distance, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = '#a3a3a3'
|
|
|
- ctx.arc(l_r_dis, 50 + 12 * distance, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(l_r_dis, l_r_dis + 12 * distance, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
const rs485_textInfo = ctx.measureText('RS485_0')
|
|
|
ctx.fillStyle = 'black'
|
|
|
- ctx.fillText('RS485_0', textDis, 50 + 11 * distance + r + rs485_textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('RS485_0', textDis, l_r_dis + 11 * distance + r + rs485_textInfo.actualBoundingBoxAscent / 2)
|
|
|
|
|
|
let a_textInfo = ctx.measureText('A')
|
|
|
- ctx.fillText('A', l_r_dis - a_textInfo.width / 2, 50 + 11 * distance + a_textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('A', l_r_dis - a_textInfo.width / 2, l_r_dis + 11 * distance + a_textInfo.actualBoundingBoxAscent / 2)
|
|
|
let b_textInfo = ctx.measureText('B')
|
|
|
- ctx.fillText('B', l_r_dis - a_textInfo.width / 2, 50 + 12 * distance + b_textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('B', l_r_dis - a_textInfo.width / 2, l_r_dis + 12 * distance + b_textInfo.actualBoundingBoxAscent / 2)
|
|
|
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = '#a3a3a3'
|
|
|
- ctx.arc(l_r_dis, 50 + 13 * distance, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(l_r_dis, l_r_dis + 13 * distance, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = '#a3a3a3'
|
|
|
- ctx.arc(l_r_dis, 50 + 14 * distance, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(l_r_dis, l_r_dis + 14 * distance, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
ctx.fillStyle = 'black'
|
|
|
- ctx.fillText('RS485_1', textDis, 50 + 13 * distance + r + rs485_textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('RS485_1', textDis, l_r_dis + 13 * distance + r + rs485_textInfo.actualBoundingBoxAscent / 2)
|
|
|
|
|
|
- ctx.fillText('A', l_r_dis - a_textInfo.width / 2, 50 + 13 * distance + a_textInfo.actualBoundingBoxAscent / 2)
|
|
|
- ctx.fillText('B', l_r_dis - a_textInfo.width / 2, 50 + 14 * distance + b_textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('A', l_r_dis - a_textInfo.width / 2, l_r_dis + 13 * distance + a_textInfo.actualBoundingBoxAscent / 2)
|
|
|
+ ctx.fillText('B', l_r_dis - a_textInfo.width / 2, l_r_dis + 14 * distance + b_textInfo.actualBoundingBoxAscent / 2)
|
|
|
|
|
|
// 配置按钮
|
|
|
ctx.beginPath()
|
|
|
const response1 = await fetch(new URL('/wxapp/canvas-icon/cfg-icon.png', self.location.href).href)
|
|
|
const blob1 = await response1.blob()
|
|
|
const imgBitmap1 = await createImageBitmap(blob1)
|
|
|
- ctx.drawImage(imgBitmap1, l_r_dis - r - 10, 50 + distance * 16 - r, (r + 10) * 2, (r + 10) * 2)
|
|
|
+ ctx.drawImage(imgBitmap1, l_r_dis - r - 10, l_r_dis + distance * 16 - r, (r + 10) * 2, (r + 10) * 2)
|
|
|
const cfg_textInfo = ctx.measureText('配置按钮')
|
|
|
- ctx.fillText('配置按钮', textDis, 50 + 16 * distance + cfg_textInfo.actualBoundingBoxAscent / 2 + r - 10)
|
|
|
+ ctx.fillText(
|
|
|
+ '配置按钮',
|
|
|
+ textDis,
|
|
|
+ l_r_dis + 16 * distance + cfg_textInfo.actualBoundingBoxAscent / 2 + r - 10 * ratioPixel
|
|
|
+ )
|
|
|
// 屏接口
|
|
|
ctx.beginPath()
|
|
|
const response2 = await fetch(new URL('/wxapp/canvas-icon/screen-icon.png', self.location.href).href)
|
|
|
const blob2 = await response2.blob()
|
|
|
const imgBitmap2 = await createImageBitmap(blob2)
|
|
|
- ctx.drawImage(imgBitmap2, l_r_dis - r + 5, 50 + distance * 18 - 20, 25, 80)
|
|
|
+ ctx.drawImage(imgBitmap2, l_r_dis - r + 5, l_r_dis + distance * 18 - 20, 25 * ratioPixel, 80 * ratioPixel)
|
|
|
const screen_textInfo = ctx.measureText('屏接口')
|
|
|
- ctx.fillText('屏接口', textDis, 50 + 18 * distance + screen_textInfo.actualBoundingBoxAscent / 2 + 40 - 20)
|
|
|
+ ctx.fillText(
|
|
|
+ '屏接口',
|
|
|
+ textDis,
|
|
|
+ l_r_dis + 18 * distance + screen_textInfo.actualBoundingBoxAscent / 2 + 40 * ratioPixel
|
|
|
+ )
|
|
|
// 指示灯
|
|
|
ctx.beginPath()
|
|
|
const response3 = await fetch(new URL('/wxapp/canvas-icon/light-icon.png', self.location.href).href)
|
|
|
const blob3 = await response3.blob()
|
|
|
const imgBitmap3 = await createImageBitmap(blob3)
|
|
|
- ctx.drawImage(imgBitmap3, l_r_dis - r, 50 + distance * 19 + 40, 40, 40)
|
|
|
+ ctx.drawImage(imgBitmap3, l_r_dis - r, l_r_dis + distance * 19 + 40 * ratioPixel, 35 * ratioPixel, 35 * ratioPixel)
|
|
|
const light1_textInfo = ctx.measureText('指示灯')
|
|
|
- ctx.fillText('指示灯', textDis, 50 + 19 * distance + light1_textInfo.actualBoundingBoxAscent / 2 + 60)
|
|
|
+ ctx.fillText(
|
|
|
+ '指示灯',
|
|
|
+ textDis,
|
|
|
+ l_r_dis + 19 * distance + light1_textInfo.actualBoundingBoxAscent / 2 + 60 * ratioPixel
|
|
|
+ )
|
|
|
// 网口
|
|
|
ctx.beginPath()
|
|
|
const response6 = await fetch(new URL('/wxapp/canvas-icon/rg45-icon.png', self.location.href).href)
|
|
|
const blob6 = await response6.blob()
|
|
|
const imgBitmap6 = await createImageBitmap(blob6)
|
|
|
- ctx.drawImage(imgBitmap6, l_r_dis - r, 50 + distance * 21 + 20, 40, 40)
|
|
|
+ ctx.drawImage(imgBitmap6, l_r_dis - r, l_r_dis + distance * 21 + 20, 40 * ratioPixel, 40 * ratioPixel)
|
|
|
const rg45_textInfo = ctx.measureText('网口')
|
|
|
- ctx.fillText('网口', textDis, 50 + 21 * distance + rg45_textInfo.actualBoundingBoxAscent / 2 + 40)
|
|
|
+ ctx.fillText(
|
|
|
+ '网口',
|
|
|
+ textDis,
|
|
|
+ l_r_dis + 21 * distance + rg45_textInfo.actualBoundingBoxAscent / 2 + (40 * ratioPixel) / 2 + 20
|
|
|
+ )
|
|
|
// logo
|
|
|
ctx.beginPath()
|
|
|
const response4 = await fetch(new URL('/wxapp/canvas-icon/logo-icon.png', self.location.href).href)
|
|
|
const blob4 = await response4.blob()
|
|
|
const imgBitmap4 = await createImageBitmap(blob4)
|
|
|
- ctx.drawImage(imgBitmap4, canvasMsg.width / 2 - imgBitmap4.width / 2, 100)
|
|
|
+ ctx.drawImage(
|
|
|
+ imgBitmap4,
|
|
|
+ canvasMsg.width / 2 - (imgBitmap4.width * ratioPixel) / 4,
|
|
|
+ 100 * ratioPixel,
|
|
|
+ (imgBitmap4.width / 2) * ratioPixel,
|
|
|
+ (imgBitmap4.height / 2) * ratioPixel
|
|
|
+ )
|
|
|
// brand
|
|
|
ctx.beginPath()
|
|
|
const response5 = await fetch(new URL('/wxapp/canvas-icon/brand.png', self.location.href).href)
|
|
|
const blob5 = await response5.blob()
|
|
|
const imgBitmap5 = await createImageBitmap(blob5)
|
|
|
- ctx.drawImage(imgBitmap5, canvasMsg.width / 2 - 140 / 2, 300, 140, (140 * imgBitmap5.height) / imgBitmap5.width)
|
|
|
+ ctx.drawImage(
|
|
|
+ imgBitmap5,
|
|
|
+ canvasMsg.width / 2 - (140 * ratioPixel) / 4,
|
|
|
+ 200 * ratioPixel,
|
|
|
+ (140 * ratioPixel) / 2,
|
|
|
+ (((140 * imgBitmap5.height) / imgBitmap5.width) * ratioPixel) / 2
|
|
|
+ )
|
|
|
|
|
|
// GND VCC
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = '#a3a3a3'
|
|
|
- ctx.arc(canvasMsg.width - l_r_dis, 50 + distance * 20, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(canvasMsg.width - l_r_dis, l_r_dis + distance * 20, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
ctx.fillStyle = 'black'
|
|
|
ctx.fillText(
|
|
|
`GND`,
|
|
|
canvasMsg.width - textDis - GND_textInfo.width,
|
|
|
- 50 + distance * 20 + GND_textInfo.actualBoundingBoxAscent / 2
|
|
|
+ l_r_dis + distance * 20 + GND_textInfo.actualBoundingBoxAscent / 2
|
|
|
)
|
|
|
ctx.beginPath()
|
|
|
ctx.fillStyle = '#a3a3a3'
|
|
|
- ctx.arc(canvasMsg.width - l_r_dis, 50 + distance * 21, r, 0, 2 * Math.PI)
|
|
|
+ ctx.arc(canvasMsg.width - l_r_dis, l_r_dis + distance * 21, r, 0, 2 * Math.PI)
|
|
|
ctx.fill()
|
|
|
ctx.fillStyle = 'black'
|
|
|
const VCC_textInfo = ctx.measureText(`VCC`)
|
|
|
ctx.fillText(
|
|
|
`VCC`,
|
|
|
canvasMsg.width - textDis - VCC_textInfo.width,
|
|
|
- 50 + distance * 21 + VCC_textInfo.actualBoundingBoxAscent / 2
|
|
|
+ l_r_dis + distance * 21 + VCC_textInfo.actualBoundingBoxAscent / 2
|
|
|
)
|
|
|
ctx.fillText(
|
|
|
'+',
|
|
|
canvasMsg.width - l_r_dis - a_textInfo.width / 2,
|
|
|
- 50 + 21 * distance + a_textInfo.actualBoundingBoxAscent / 2
|
|
|
+ l_r_dis + 21 * distance + a_textInfo.actualBoundingBoxAscent / 2
|
|
|
)
|
|
|
ctx.fillText(
|
|
|
'-',
|
|
|
canvasMsg.width - l_r_dis - a_textInfo.width / 2,
|
|
|
- 50 + 20 * distance + b_textInfo.actualBoundingBoxAscent / 2
|
|
|
+ l_r_dis + 20 * distance + b_textInfo.actualBoundingBoxAscent / 2
|
|
|
)
|
|
|
|
|
|
const tip_textInfo = ctx.measureText('当前plc系统时间')
|
|
|
ctx.fillText(
|
|
|
`当前plc系统时间`,
|
|
|
canvasMsg.width / 2 - tip_textInfo.width / 2,
|
|
|
- canvasMsg.height - 100 + tip_textInfo.actualBoundingBoxAscent
|
|
|
+ 20 * ratioPixel + tip_textInfo.actualBoundingBoxAscent
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- const y = 50 + distance * (index + 1)
|
|
|
+ const y = l_r_dis + distance * (index + 1)
|
|
|
switch (key) {
|
|
|
case 'DI':
|
|
|
case 'DO':
|
|
@@ -236,9 +309,9 @@ const drawPlc = async (key, index, val, type) => {
|
|
|
y + distance * 11 + AI_textInfo.actualBoundingBoxAscent / 2
|
|
|
)
|
|
|
}
|
|
|
- ctx.clearRect(canvasMsg.width - textDis - AI_textInfo.width - 120, y + distance * 11 - r, 100, r * 2)
|
|
|
+ ctx.clearRect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y + distance * 11 - r, 100 * ratioPixel, r * 2)
|
|
|
ctx.beginPath()
|
|
|
- ctx.rect(canvasMsg.width - textDis - AI_textInfo.width - 120, y + distance * 11 - r, 100, r * 2)
|
|
|
+ ctx.rect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y + distance * 11 - r, 100 * ratioPixel, r * 2)
|
|
|
ctx.lineCap = 'round'
|
|
|
ctx.stroke()
|
|
|
ctx.closePath()
|
|
@@ -247,9 +320,9 @@ const drawPlc = async (key, index, val, type) => {
|
|
|
|
|
|
ctx.fillText(
|
|
|
`${val}`,
|
|
|
- canvasMsg.width - textDis - AI_textInfo.width - 60 - AI_val_textInfo.width / 2,
|
|
|
+ canvasMsg.width - textDis - (60 + 50) * ratioPixel,
|
|
|
y + distance * 11 + AI_textInfo.actualBoundingBoxAscent / 2,
|
|
|
- 100
|
|
|
+ 100 * ratioPixel
|
|
|
)
|
|
|
break
|
|
|
case 'AO':
|
|
@@ -269,9 +342,9 @@ const drawPlc = async (key, index, val, type) => {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
- ctx.clearRect(canvasMsg.width - textDis - AO_textInfo.width - 120, y1, 100, r * 2)
|
|
|
+ ctx.clearRect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y1, 100 * ratioPixel, r * 2)
|
|
|
ctx.beginPath()
|
|
|
- ctx.rect(canvasMsg.width - textDis - AO_textInfo.width - 120, y1, 100, r * 2)
|
|
|
+ ctx.rect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y1, 100 * ratioPixel, r * 2)
|
|
|
ctx.lineCap = 'round'
|
|
|
ctx.stroke()
|
|
|
ctx.closePath()
|
|
@@ -279,9 +352,9 @@ const drawPlc = async (key, index, val, type) => {
|
|
|
const AO_val_textInfo = ctx.measureText(`${val}`)
|
|
|
ctx.fillText(
|
|
|
`${val}`,
|
|
|
- canvasMsg.width - textDis - AO_textInfo.width - 60 - AO_val_textInfo.width / 2.5,
|
|
|
+ canvasMsg.width - textDis - (60 + 50) * ratioPixel,
|
|
|
y1 + r + AO_textInfo.actualBoundingBoxAscent / 2,
|
|
|
- 100
|
|
|
+ 100 * ratioPixel
|
|
|
)
|
|
|
if (type === 'draw') {
|
|
|
ctx.textAlign = 'start'
|
|
@@ -306,48 +379,100 @@ const drawPlc = async (key, index, val, type) => {
|
|
|
}
|
|
|
break
|
|
|
case 'time':
|
|
|
- const timeVal = new Date(val * 1000).toLocaleString()
|
|
|
+ const timeVal = formatDateTime(val * 1000)
|
|
|
const valTextInfo = ctx.measureText(timeVal)
|
|
|
ctx.clearRect(
|
|
|
canvasMsg.width / 2 - valTextInfo.width / 2,
|
|
|
- canvasMsg.height - 50 - valTextInfo.actualBoundingBoxAscent,
|
|
|
+ 25 * ratioPixel + l_r_dis - valTextInfo.actualBoundingBoxAscent,
|
|
|
valTextInfo.width,
|
|
|
- valTextInfo.actualBoundingBoxAscent * 2
|
|
|
+ valTextInfo.actualBoundingBoxAscent * 2 + 4
|
|
|
)
|
|
|
ctx.fillText(
|
|
|
timeVal,
|
|
|
canvasMsg.width / 2 - valTextInfo.width / 2,
|
|
|
- canvasMsg.height - 50 + valTextInfo.actualBoundingBoxAscent
|
|
|
+ 25 * ratioPixel + l_r_dis + valTextInfo.actualBoundingBoxAscent
|
|
|
)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const DIValMap = {}
|
|
|
+
|
|
|
onmessage = (e) => {
|
|
|
- const { type, url, ratio, canvas } = e.data
|
|
|
+ const { type, url, ratio, canvas, position, val, i } = e.data
|
|
|
if (!canvasEl && type === 'init') {
|
|
|
canvasEl = canvas
|
|
|
ctx = canvas.getContext('2d')
|
|
|
initWasm(url)
|
|
|
canvasMsg.width = canvas.width
|
|
|
canvasMsg.height = canvas.height
|
|
|
+ // ratioPixel = Math.ceil(canvas.width / ratio / 375)
|
|
|
ratioPixel = ratio
|
|
|
+ distance *= ratioPixel
|
|
|
+ textDis *= ratioPixel
|
|
|
+ r *= ratioPixel
|
|
|
+ console.log(r)
|
|
|
+
|
|
|
+ l_r_dis *= ratioPixel
|
|
|
+ console.log(ratioPixel)
|
|
|
drawPlc(null, null, null, 'init')
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
drawPlc('DI', i, 0, 'draw')
|
|
|
drawPlc('DO', i, 0, 'draw')
|
|
|
+ DIValMap[i] = 0
|
|
|
}
|
|
|
for (let i = 0; i < 4; i++) {
|
|
|
- drawPlc('AI', i, i, 'draw')
|
|
|
+ drawPlc('AI', i, 0, 'draw')
|
|
|
}
|
|
|
for (let i = 0; i < 2; i++) {
|
|
|
- drawPlc('AO', i, i, 'draw')
|
|
|
+ drawPlc('AO', i, 0, 'draw')
|
|
|
}
|
|
|
}
|
|
|
- if (type === 1) {
|
|
|
- if (sendMsg.type === 'AI') {
|
|
|
- _SetTrustAI(sendMsg.index, +sendMsg.valuel)
|
|
|
- } else {
|
|
|
- _SetTrustDI(sendMsg.index, +sendMsg.value)
|
|
|
+ if (type === 'set') {
|
|
|
+ console.log(+i, +val);
|
|
|
+
|
|
|
+ _SetTrustAI(+i, +val * 100)
|
|
|
+ drawPlc('AI', +i, +val)
|
|
|
+ }
|
|
|
+ if (type === 'time') {
|
|
|
+ _SetDiffTimeStamp(+val)
|
|
|
+ }
|
|
|
+ if (type === 'click') {
|
|
|
+ if (!position) return
|
|
|
+ const { x, y } = position
|
|
|
+ console.log(x, y)
|
|
|
+
|
|
|
+ // 判断是否点击到DI
|
|
|
+ for (let i = 0; i < 10; i++) {
|
|
|
+ const p_to_p_dis = Math.sqrt((l_r_dis - x * ratio) ** 2 + (l_r_dis + distance * (i + 1) - y * ratio) ** 2)
|
|
|
+ if (p_to_p_dis <= r) {
|
|
|
+ if (DIValMap[i] === 0) {
|
|
|
+ DIValMap[i] = 1
|
|
|
+ } else {
|
|
|
+ DIValMap[i] = 0
|
|
|
+ }
|
|
|
+ _SetTrustDI(i, DIValMap[i])
|
|
|
+ drawPlc('DI', i, DIValMap[i])
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 判断是否点击到AI
|
|
|
+ for (let i = 0; i < 4; i++) {
|
|
|
+ const rectX = canvasMsg.width - textDis - (60 + 100) * ratioPixel
|
|
|
+ const rectY = l_r_dis + distance * (i + 1) + distance * 11 - r
|
|
|
+ if (x * ratio >= rectX && x <= rectX + 100 * ratioPixel && y * ratio >= rectY && y * ratio <= rectY + r * 2) {
|
|
|
+ postMessage({ type: 'AI', i })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 判断是否点击时间
|
|
|
+ if (
|
|
|
+ x * ratio >= canvasMsg.width / 2 - 80 * ratio &&
|
|
|
+ x * ratio <= canvasMsg.width / 2 + 80 * ratio &&
|
|
|
+ y * ratio >= 20 * ratioPixel + l_r_dis &&
|
|
|
+ y * ratio <= 40 * ratio + l_r_dis
|
|
|
+ ) {
|
|
|
+ postMessage({ type: 'time' })
|
|
|
+ return
|
|
|
}
|
|
|
}
|
|
|
}
|