Browse Source

修改canvas,让其直接使用UI设计师提供的底图

jevian ma(马作伟_沃航科技) 1 month ago
parent
commit
2d4111b841

BIN
public/canvas-icon/brand.png


BIN
public/canvas-icon/cfg-icon.png


BIN
public/canvas-icon/ditu.png


BIN
public/canvas-icon/light-icon.png


BIN
public/canvas-icon/logo-icon.png


BIN
public/canvas-icon/rg45-icon.png


BIN
public/canvas-icon/screen-icon.png


BIN
public/canvas-icon/v-icon.png


+ 31 - 373
src/utils/worker.js

@@ -48,374 +48,58 @@ const initWasm = (url) => {
 
 let canvasEl
 let ctx
-let ratioPixel
-const canvasMsg = {
-  width: 0,
-  height: 0
-}
 
-let distance = 48 // 每个模块间隔
-let textDis = 72
-let r = 18
-let l_r_dis = 36
+const r = 26 // 圆的半径
+const l_x = 47 + r  // 左上角圆的圆的心x坐标
+const r_x = 589 + r // 右上角圆的圆的心x坐标
+const lr_y = 57 + r // 最上面的圆的圆心y坐标
+const lr_dis = 74 // 上下两个圆圆心的距离
+// AI与AO的输入框左上角点坐标
+const rectX = 346
+const rectY = [942, 1016, 1090, 1164, 1286, 1432]
+
 const drawPlc = async (key, index, val, type) => {
   if (!ctx) return
-  ctx.font = `${16 * ratioPixel}px 黑体`
-  ctx.textAlign = 'start'
-  ctx.globalAlpha = 1
+  ctx.font = '30px Noto Sans SC'
   if (type === 'init') {
-    ctx.beginPath()
-    ctx.strokeStyle = '#'
-    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 - 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()
-
-    // GND
-    ctx.beginPath()
-    // ctx.fillStyle = val !== 0 ? 'green' : 'red'
-    ctx.fillStyle = 'red'
-    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,
-      l_r_dis + distance * 11 + GND_textInfo.actualBoundingBoxAscent / 2
-    )
-
-    // left com
-    ctx.beginPath()
-    ctx.fillStyle = (DIValMap[0] || DIValMap[1] || DIValMap[2] || DIValMap[3] || DIValMap[4] || DIValMap[5] || DIValMap[6] || DIValMap[7] || DIValMap[8] || DIValMap[9]) ? '#green' : 'red'
-    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, l_r_dis + textInfo.actualBoundingBoxAscent / 2)
-
-    // right com
-    ctx.beginPath()
-    ctx.fillStyle = 'red'
-    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, l_r_dis + textInfo.actualBoundingBoxAscent / 2)
-
-    // RS485
-    ctx.beginPath()
-    ctx.fillStyle = '#a3a3a3'
-    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, 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, 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, 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, l_r_dis + 12 * distance + b_textInfo.actualBoundingBoxAscent / 2)
-
-    ctx.beginPath()
-    ctx.fillStyle = '#a3a3a3'
-    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, l_r_dis + 14 * distance, r, 0, 2 * Math.PI)
-    ctx.fill()
-    ctx.fillStyle = 'black'
-    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, 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, l_r_dis + distance * 16 - r, (r + 10) * 2, (r + 10) * 2)
-    const cfg_textInfo = ctx.measureText('配置按钮')
-    ctx.fillText(
-      '配置按钮',
-      textDis + 20 * ratioPixel,
-      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, l_r_dis + distance * 18 - 20, 25 * ratioPixel, 80 * ratioPixel)
-    const screen_textInfo = ctx.measureText('屏接口')
-    ctx.fillText(
-      '屏接口',
-      textDis + 20 * ratioPixel,
-      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, l_r_dis + distance * 19 + 40 * ratioPixel, 35 * ratioPixel, 35 * ratioPixel)
-    const light1_textInfo = ctx.measureText('指示灯')
-    ctx.fillText(
-      '指示灯',
-      textDis + 20 * ratioPixel,
-      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, l_r_dis + distance * 21 + 20, 40 * ratioPixel, 40 * ratioPixel)
-    const rg45_textInfo = ctx.measureText('网口')
-    ctx.fillText(
-      '网口',
-      textDis +20 * ratioPixel,
-      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 * 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 * 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, l_r_dis + distance * 20, r, 0, 2 * Math.PI)
-    ctx.fill()
-    ctx.fillStyle = 'black'
-    ctx.fillText(
-      `GND`,
-      canvasMsg.width - textDis - GND_textInfo.width,
-      l_r_dis + distance * 20 + GND_textInfo.actualBoundingBoxAscent / 2
-    )
-    ctx.beginPath()
-    ctx.fillStyle = '#a3a3a3'
-    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,
-      l_r_dis + distance * 21 + VCC_textInfo.actualBoundingBoxAscent / 2
-    )
-    ctx.fillText(
-      '+',
-      canvasMsg.width - l_r_dis - a_textInfo.width / 2,
-      l_r_dis + 21 * distance + a_textInfo.actualBoundingBoxAscent / 2
-    )
-    ctx.fillText(
-      '-',
-      canvasMsg.width - l_r_dis - a_textInfo.width / 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,
-    //   20 * ratioPixel + tip_textInfo.actualBoundingBoxAscent
-    // )
+    const response = await fetch(new URL('/wxapp/canvas-icon/ditu.png', self.location.href).href)
+    const blob = await response.blob()
+    const imgBitmap = await createImageBitmap(blob)
+    ctx.drawImage(imgBitmap, 0, 0)
   }
 
-  const y = l_r_dis + distance * (index + 1)
   switch (key) {
     case 'DI':
     case 'DO':
       // left com
       ctx.beginPath()
-      ctx.fillStyle = (DIValMap[0] || DIValMap[1] || DIValMap[2] || DIValMap[3] || DIValMap[4] || DIValMap[5] || DIValMap[6] || DIValMap[7] || DIValMap[8] || DIValMap[9]) ? 'green' : 'red'
-      ctx.arc(l_r_dis, l_r_dis, r, 0, 2 * Math.PI)
+      ctx.fillStyle = (DIValMap[0] || DIValMap[1] || DIValMap[2] || DIValMap[3] || DIValMap[4] || DIValMap[5] || DIValMap[6] || DIValMap[7] || DIValMap[8] || DIValMap[9]) ? 'green' : '#D11E27'
+      ctx.arc(l_x, lr_y, r, 0, 2 * Math.PI)
       ctx.fill()
 
       // right com
       ctx.beginPath()
-      ctx.fillStyle = doCom ? 'green' : 'red'
-      ctx.arc(canvasMsg.width - l_r_dis, l_r_dis, r, 0, 2 * Math.PI)
+      ctx.fillStyle = doCom ? 'green' : '#D11E27'
+      ctx.arc(r_x, lr_y, r, 0, 2 * Math.PI)
       ctx.fill()
 
-      ctx.clearRect(key === 'DI' ? l_r_dis - r : canvasMsg.width - l_r_dis - r, y - r, r * 2, r * 2)
       ctx.beginPath()
-      ctx.fillStyle = val !== 0 ? 'green' : 'red'
-      ctx.arc(key === 'DI' ? l_r_dis : canvasMsg.width - l_r_dis, y, r, 0, 2 * Math.PI)
+      ctx.fillStyle = val !== 0 ? 'green' : '#D11E27'
+      ctx.arc(key === 'DI' ? l_x : r_x, lr_y + lr_dis * (index + 1), r, 0, 2 * Math.PI)
       ctx.fill()
-      const DI_DO_textInfo = ctx.measureText(`${key}_${index}`)
-      ctx.fillStyle = 'black'
-      if (type === 'draw') {
-        ctx.fillText(
-          `${key}_${index}`,
-          key === 'DI' ? textDis : canvasMsg.width - textDis - DI_DO_textInfo.width,
-          y + DI_DO_textInfo.actualBoundingBoxAscent / 2
-        )
-      }
       break
     case 'AI':
-      ctx.beginPath()
-      // ctx.fillStyle = val !== 0 ? 'green' : 'red'
-      const AI_textInfo = ctx.measureText(`${key}_${index}`)
-      if (type === 'draw') {
-        ctx.fillStyle = 'red'
-        ctx.arc(canvasMsg.width - l_r_dis, y + distance * 11, r, 0, 2 * Math.PI)
-        ctx.fill()
-        ctx.fillStyle = 'black'
-        ctx.fillText(
-          `${key}_${index}`,
-          canvasMsg.width - textDis - AI_textInfo.width,
-          y + distance * 11 + AI_textInfo.actualBoundingBoxAscent / 2
-        )
-      }
-      ctx.clearRect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y + distance * 11 - r, 100 * ratioPixel, r * 2)
-      ctx.beginPath()
-      ctx.rect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y + distance * 11 - r, 100 * ratioPixel, r * 2)
-      ctx.lineCap = 'round'
-      ctx.stroke()
-      ctx.closePath()
-      ctx.textAlign = 'center'
-      const AI_val_textInfo = ctx.measureText(`${val}`)
-
-      ctx.fillText(
-        `${val}`,
-        canvasMsg.width - textDis - (60 + 50) * ratioPixel,
-        y + distance * 11 + AI_textInfo.actualBoundingBoxAscent / 2,
-        100 * ratioPixel
-      )
+      ctx.fillStyle = '#ffffff'
+      ctx.fillRect(rectX + 100, rectY[index] + 6, 100, 38)
+      ctx.fillStyle = '#202020'
+      ctx.fillText(`${val}`, rectX + 100, rectY[index] + 39)
       break
     case 'AO':
-      const y1 = y + distance * (15 + index * 1)
-      // ctx.fillStyle = val !== 0 ? 'green' : 'red'
-      const AO_textInfo = ctx.measureText(`${key}_${index}`)
-      if (type === 'draw') {
-        ctx.beginPath()
-        ctx.fillStyle = 'red'
-        ctx.arc(canvasMsg.width - l_r_dis, y1, r, 0, 2 * Math.PI)
-        ctx.fill()
-        ctx.fillStyle = 'black'
-        ctx.fillText(
-          `${key}_${index}`,
-          canvasMsg.width - textDis - AO_textInfo.width,
-          y1 + r + AO_textInfo.actualBoundingBoxAscent / 2
-        )
-      }
-
-      ctx.clearRect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y1, 100 * ratioPixel, r * 2)
-      ctx.beginPath()
-      ctx.rect(canvasMsg.width - textDis - (60 + 100) * ratioPixel, y1, 100 * ratioPixel, r * 2)
-      ctx.lineCap = 'round'
-      ctx.stroke()
-      ctx.closePath()
-      ctx.textAlign = 'center'
-      const AO_val_textInfo = ctx.measureText(`${val}`)
-      ctx.fillText(
-        `${val}`,
-        canvasMsg.width - textDis - (60 + 50) * ratioPixel,
-        y1 + r + AO_textInfo.actualBoundingBoxAscent / 2,
-        100 * ratioPixel
-      )
-      if (type === 'draw') {
-        ctx.textAlign = 'start'
-        const add_textInfo = ctx.measureText('+')
-        ctx.fillText(
-          `+`,
-          canvasMsg.width - l_r_dis - add_textInfo.width / 2,
-          y1 + add_textInfo.actualBoundingBoxAscent / 2
-        )
-      }
-
-      const y2 = y + distance * (15 + index * 1 + 1)
-      if (type === 'draw') {
-        ctx.beginPath()
-        // ctx.fillStyle = val !== 0 ? 'green' : 'red'
-        ctx.fillStyle = 'red'
-        ctx.arc(canvasMsg.width - l_r_dis, y2, r, 0, 2 * Math.PI)
-        ctx.fill()
-        ctx.fillStyle = 'black'
-        const sub_textInfo = ctx.measureText('-')
-        ctx.fillText(`-`, canvasMsg.width - l_r_dis - sub_textInfo.width / 2, y2 + sub_textInfo.actualBoundingBoxAscent)
-      }
+      ctx.fillStyle = '#ffffff'
+      ctx.fillRect(rectX + 110, rectY[index + 4] + 6, 95, 38)
+      ctx.fillStyle = '#202020'
+      ctx.fillText(`${val}`, rectX + 110, rectY[index + 4] + 39)
       break
-    case 'time':
-      const timeVal = formatDateTime(val * 1000)
-      const valTextInfo = ctx.measureText(timeVal)
-      ctx.clearRect(
-        canvasMsg.width / 2 - valTextInfo.width / 2,
-        25 * ratioPixel + l_r_dis - valTextInfo.actualBoundingBoxAscent,
-        valTextInfo.width,
-        valTextInfo.actualBoundingBoxAscent * 2 + 4
-      )
-      ctx.fillText(
-        timeVal,
-        canvasMsg.width / 2 - valTextInfo.width / 2,
-        25 * ratioPixel + l_r_dis + valTextInfo.actualBoundingBoxAscent
-      )
   }
 }
 
@@ -423,22 +107,11 @@ const DIValMap = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
 let doCom = false
 
 onmessage = (e) => {
-  const { type, url, ratio, canvas, position, val, i } = e.data
+  const { type, url, 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')
@@ -453,8 +126,6 @@ onmessage = (e) => {
     }
   }
   if (type === 'set') {
-    console.log(+i, +val)
-
     _SetTrustAI(+i, +val * 100)
     drawPlc('AI', +i, +val)
   }
@@ -464,11 +135,10 @@ onmessage = (e) => {
   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)
+      const p_to_p_dis = Math.sqrt((l_x - x) ** 2 + (lr_y + lr_dis * (i + 1) - y) ** 2)
       if (p_to_p_dis <= r) {
         if (DIValMap[i] === 0) {
           DIValMap[i] = 1
@@ -482,22 +152,10 @@ onmessage = (e) => {
     }
     // 判断是否点击到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) {
+      if (x >= rectX && x <= rectX + 208 && y >= rectY[i] && y <= rectY[i] + 58) {
         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
-    // }
   }
 }

+ 12 - 22
src/views/runtime.vue

@@ -7,8 +7,8 @@
 
       <div class="time" @click="updateTime">PLC系统时间:{{ crtPlcTime }}</div>
     </div>
-    <div class="canvas-main" ref="canvasMainRef">
-      <canvas ref="canvasRef" @click="handleCanvasClick"></canvas>
+    <div class="canvas-main">
+      <canvas ref="canvasRef" @click="handleCanvasClick" width="688" height="1877" style="width: 100%"></canvas>
     </div>
 
     <van-popup v-model:show="showPopup" round :style="{ width: '80%' }" :close-on-click-overlay="false">
@@ -38,7 +38,7 @@
         <van-cell-group inset>
           <van-field border v-model="port" label="端口" readonly name="port" />
           <van-field
-            v-model="newVal"
+            v-model="newDatetime"
             label="值"
             name="newVal"
             type="text"
@@ -93,8 +93,6 @@ watch(
   }
 )
 const canvasRef = ref<HTMLCanvasElement | null>(null)
-const canvasMainRef = ref<HTMLElement | null>(null)
-const ratio = window.devicePixelRatio
 
 const runtimeWorker = new Worker(new URL('@/utils/worker.js', import.meta.url))
 
@@ -119,14 +117,15 @@ const port = ref('AI0')
 const showPopup = ref(false)
 const showPicker = ref(false)
 const showDateTime = ref(false)
-const newVal: any = ref(0)
+const newVal = ref(0)
+const newDatetime = ref('')
 const columns = reactive([[{}], [{}], [{}], [{}], [{}], [{}]])
 const pickerValue = reactive([0, 0, 0, 0, 0, 0])
 
 const onSubmit = () => {
   runtimeWorker.postMessage({
     type: popupType.value === 'AI' ? 'set' : 'time',
-    val: popupType.value === 'AI' ? newVal.value : (new Date(newVal.value).getTime() - new Date().getTime()) / 1000,
+    val: popupType.value === 'AI' ? newVal.value : (new Date(newDatetime.value).getTime() - new Date().getTime()) / 1000,
     i: port.value.slice(-1)
   })
   handleCancel()
@@ -135,7 +134,6 @@ const handleCancel = () => {
   showPopup.value = false
   showDateTime.value = false
   showPicker.value = false
-  newVal.value = 0
 }
 
 const updateTime = () => {
@@ -182,14 +180,14 @@ const updateTime = () => {
   pickerValue[3] = date.getHours()
   pickerValue[4] = date.getMinutes()
   pickerValue[5] = date.getSeconds()
-  newVal.value = crtPlcTime.value
+  newDatetime.value = crtPlcTime.value
   popupType.value = 'time'
   port.value = `设备时间`
   showDateTime.value = true
 }
 
 const PickerConfirm = (res: any) => {
-  newVal.value = String(res.selectedValues[0]) + '-' +
+  newDatetime.value = String(res.selectedValues[0]) + '-' +
     String(res.selectedValues[1]).padStart(2, '0') + '-' +
     String(res.selectedValues[2]).padStart(2, '0') + ' ' +
     String(res.selectedValues[3]).padStart(2, '0') + ':' +
@@ -203,32 +201,24 @@ let timer: any
 const handleCanvasClick = (e: MouseEvent) => {
   if (timer) clearTimeout(timer)
   timer = setTimeout(() => {
+    let ratio = 688 / (document.body.clientWidth - 16) // document.body.clientWidth - 16是canvas通过style变形后的宽度,实际宽度是688,因此页面实际显示的会经过(document.body.clientWidth - 16)/688的等比例缩放
     runtimeWorker.postMessage({
       type: 'click',
-      ratio,
       position: {
-        x: e.offsetX,
-        y: e.offsetY
+        x: e.offsetX * ratio,
+        y: e.offsetY * ratio
       }
     })
   }, 50)
 }
 
 onMounted(() => {
-  if (!canvasRef.value || !canvasMainRef.value) return
-  const w = Math.floor(canvasMainRef.value.clientWidth)
-  // const h = Math.floor(canvasMainRef.value.clientHeight)
-  const h = 1150
-  canvasRef.value.width = w * ratio
-  canvasRef.value.height = h * ratio
-  canvasRef.value.style.width = `${w}px`
-  canvasRef.value.style.height = `${h}px`
+  if (!canvasRef.value) return
   const offscreenCanvas = canvasRef.value.transferControlToOffscreen()
   runtimeWorker.postMessage(
     {
       type: 'init',
       url: route.query.url,
-      ratio,
       canvas: offscreenCanvas
     },
     [offscreenCanvas]