caner 1 year ago
parent
commit
db504529da

BIN
src/pages/svgAnimation/img/2.png


BIN
src/pages/svgAnimation/img/3.png


BIN
src/pages/svgAnimation/img/4.png


BIN
src/pages/svgAnimation/img/5.png


+ 9 - 9
src/pages/svgAnimation/img/test.svg

@@ -22,15 +22,15 @@
                fill="freeze"/>
                fill="freeze"/>
     </path>
     </path>
     <!-- 运动对象 -->
     <!-- 运动对象 -->
-    <path d="M-15,-5 L0,-15 L15,-5 L5,5 L-5,5 Z" fill="red">
-      <animateMotion 
-        begin="pathAnim.begin" 
-        dur="8s" 
-        rotate="auto" 
-        fill="freeze">
-        <mpath xlink:href="#complexPath"/>
-      </animateMotion>
-    </path>
+    <g>
+        <path d="M-15,-5 L0,-15 L15,-5 L5,5 L-5,5 Z" fill="red" />
+        <animateMotion 
+          dur="8s" 
+          rotate="auto" 
+          fill="freeze">
+          <mpath xlink:href="#complexPath"/>
+        </animateMotion>
+    </g>
   </g>
   </g>
     <script type="application/ecmascript">
     <script type="application/ecmascript">
     <![CDATA[
     <![CDATA[

+ 1390 - 107
src/pages/svgAnimation/index.vue

@@ -1,12 +1,67 @@
 <template>
 <template>
-  <div class="box">
+  <div
+    id="SVGBOX"
+    class="box"
+  >
     <svg
     <svg
-      :viewBox="`0 0 ${svgConfig.width} ${svgConfig.height}`"
-      preserveAspectRatio="none"
       version="1.1"
       version="1.1"
       xmlns="http://www.w3.org/2000/svg"
       xmlns="http://www.w3.org/2000/svg"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       xmlns:xlink="http://www.w3.org/1999/xlink"
     >
     >
+      <!-- 模版 -->
+      <defs>
+        <!-- 短竖线-->
+        <marker
+          id="s"
+          viewBox="0 0 2 10"
+          refX="0"
+          refY="5"
+          markerWidth="5"
+          markerHeight="10"
+        >
+          <line
+            x1="0"
+            y1="0.5"
+            x2="0"
+            y2="10"
+            stroke="white"
+            stroke-width="2"
+          />
+        </marker>
+        <!-- 定义描边滤镜 -->
+        <filter
+          id="outline"
+          x="-10%"
+          y="-10%"
+          width="120%"
+          height="120%"
+        >
+          <!-- 扩张图片边缘 -->
+          <feMorphology
+            operator="dilate"
+            radius="2"
+            in="SourceAlpha"
+            result="thicker"
+          />
+          <!-- 描边颜色 -->
+          <feFlood
+            flood-color="#25DCE2"
+            result="color"
+          />
+          <!-- 合并描边和原图 -->
+          <feComposite
+            in="color"
+            in2="thicker"
+            operator="in"
+            result="outline"
+          />
+          <feComposite
+            in="SourceGraphic"
+            in2="outline"
+            operator="over"
+          />
+        </filter>
+      </defs>
       <!-- 底色 -->
       <!-- 底色 -->
       <image
       <image
         v-for="(item, index) in svgConfig.tunnel"
         v-for="(item, index) in svgConfig.tunnel"
@@ -18,153 +73,1381 @@
         :height="item.h"
         :height="item.h"
         preserveAspectRatio="none"
         preserveAspectRatio="none"
       />
       />
+      <!-- leng -->
+      <g v-if="svgConfig.leng.length">
+        <polyline
+          :points="`0,${svgConfig.height + 5} ${svgConfig.leng[1].x},${svgConfig.height + 5} ${svgConfig.domWidth - 1},${svgConfig.height + 5}`"
+          fill="none"
+          stroke="white"
+          stroke-width="1"
+          marker-start="url(#s)"
+          marker-mid="url(#s)"
+          marker-end="url(#s)"
+        />
+        <g
+          v-for="(item, index) in svgConfig.leng"
+          :key="index"
+        >
+          <text
+            :x="item.x"
+            :y="svgConfig.height + 25"
+            fill="white"
+            font-size="12"
+            :text-anchor="item.type"
+          >{{ item.name
+          }}</text>
+          <text
+            :x="item.x"
+            :y="svgConfig.height + 40"
+            fill="white"
+            font-size="11"
+            :text-anchor="item.type"
+          >{{ item.stake
+          }}</text>
+        </g>
+      </g>
 
 
-      <!-- 运动对象 -->
+      <!-- 移动目标 -->
       <g
       <g
-        v-for="(item, index) in list"
+        v-for="(item, index) in devices"
         :key="index"
         :key="index"
       >
       >
-        <!-- 运动路径+动画 -->
-        <path
-          v-if="item.showPath"
-          :id="item.pathId"
-          :d="item.path"
-          fill="none"
-          stroke="#3498db"
-          stroke-width="1"
-          :stroke-dasharray="item.pathStorkeDasharray"
-          stroke-dashoffset="0"
-        >
-          <animate
-            :id="item.animoId"
-            attributeName="stroke-dasharray"
-            begin="0s"
-            :dur="`${item.duration}s`"
-            :values="item.animoValues"
-            calcMode="linear"
-            fill="freeze"
-          />
-        </path>
+        <!-- 存运动路径+动画 -->
+        <g :id="item.pathId" />
         <!-- 对象 -->
         <!-- 对象 -->
-        <image
-          :href="item.img"
-          :x="item.x"
-          :y="item.y"
-          :width="item.w"
-          :height="item.h"
-          :transform="item.transform"
-          preserveAspectRatio="none"
-        >
-          <animateMotion
-            :begin="`${item.animoId}.begin`"
-            :dur="`${item.duration}s`"
-            fill="freeze"
-          >
-            <mpath :xlink:href="`#${item.pathId}`" />
-          </animateMotion>
-        </image>
+        <g :id="item.imgId">
+          <image
+            :href="item.img"
+            :x="item.x"
+            :y="item.y"
+            :width="item.w"
+            :height="svgConfig.height / 2"
+            :transform="item.transform"
+            :filter="props.dataCheck === index ? 'url(#outline)':''"
+          />
+          <!-- tip -->
+          <image
+            v-if="item.isDevice"
+            :href="img5"
+            :x="props.startAnimate? item.x-item.w/2-187/2: item.x+187/2"
+            :y="item.y"
+            width="187"
+            height="60"
+            preserveAspectRatio="xMidYMid meet"
+          />
+          <text
+            v-if="item.isDevice"
+            :x="props.startAnimate? item.x-item.w/2-187/2+3: item.x+187/2+3"
+            :y="item.y+20"
+            font-size="20"
+            fill="white"
+            textLength="180"
+            font-weight="bold"
+            dominant-baseline="middle"
+          >{{ item.positionTime }}</text>
+        </g>
       </g>
       </g>
     </svg>
     </svg>
   </div>
   </div>
 </template>
 </template>
 
 
 <script setup lang='ts'>
 <script setup lang='ts'>
-import { onMounted, reactive, ref } from 'vue'
+import {
+  onMounted,
+  onUnmounted, reactive, ref, watch
+} from 'vue'
+import img1 from './img/1.png'
+import img2 from './img/2.png'
+import img5 from './img/5.png'
 
 
 const props = withDefaults(defineProps<{
 const props = withDefaults(defineProps<{
-  data?: { stake: number, img: string, stakes: number[] }[], // 原始数据
-  showPath?: boolean, // 是否显示路径
-  isIn?: boolean // 进口|出口
+  data?: { img: string, postions: any[] }[], // 原始数据
+  dataCheck?: number, // 对象选中
+  startAnimate?: boolean, // 显示动画
+  menuItem?: { isIn: boolean, startStake: number, endStake: number, currentStake: number, length: number, stakeType: string },
 }>(), {
 }>(), {
-  isIn: true,
-  showPath: true,
+  menuItem: () => ({
+    currentStake: 167175.4,
+    endStake: 167395,
+    isIn: false,
+    length: 6560,
+    name: '出口',
+    stakeType: 'K',
+    startStake: 160835
+  }),
   data: () => [ {
   data: () => [ {
-    stake: 200, img: new URL('./img/3.png', import.meta.url).href, name: '台车', stakes: [ 0, 10, 20, 30, 40, 50, 60, 70, 80, 100, 120, 140, 160, 180, 200 ]
-  } ]
+    img: new URL('./img/3.png', import.meta.url).href,
+    name: '台车',
+    isDevice: true,
+    w: 350,
+    postions: [
+      {
+        id: 1867949485392,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+240.6',
+        stakeType: 'K',
+        mileage: 167240.6,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:15:40',
+        createTime: '2025-04-01 09:15:58',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867949732232,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+238.1',
+        stakeType: 'K',
+        mileage: 167238.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:16:11',
+        createTime: '2025-04-01 09:16:29',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867949978792,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+235.4',
+        stakeType: 'K',
+        mileage: 167235.4,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:16:45',
+        createTime: '2025-04-01 09:17:00',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867950225528,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.1',
+        stakeType: 'K',
+        mileage: 167236.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:17:16',
+        createTime: '2025-04-01 09:17:31',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867950472120,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.9',
+        stakeType: 'K',
+        mileage: 167236.9,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:17:47',
+        createTime: '2025-04-01 09:18:01',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867950718728,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+237.2',
+        stakeType: 'K',
+        mileage: 167237.2,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:18:02',
+        createTime: '2025-04-01 09:18:32',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867950965224,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+239.0',
+        stakeType: 'K',
+        mileage: 167239,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:18:48',
+        createTime: '2025-04-01 09:19:03',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867951211776,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+230.1',
+        stakeType: 'K',
+        mileage: 167230.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:19:18',
+        createTime: '2025-04-01 09:19:34',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867951458280,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+230.1',
+        stakeType: 'K',
+        mileage: 167230.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:19:18',
+        createTime: '2025-04-01 09:20:05',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867951704944,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+230.1',
+        stakeType: 'K',
+        mileage: 167230.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:19:18',
+        createTime: '2025-04-01 09:20:35',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867951951600,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+230.1',
+        stakeType: 'K',
+        mileage: 167230.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:19:18',
+        createTime: '2025-04-01 09:21:06',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867966989040,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.0',
+        stakeType: 'K',
+        mileage: 167236,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:51:59',
+        createTime: '2025-04-01 09:52:26',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867967235976,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+234.6',
+        stakeType: 'K',
+        mileage: 167234.6,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:52:41',
+        createTime: '2025-04-01 09:52:57',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867967482088,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+241.0',
+        stakeType: 'K',
+        mileage: 167241,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:53:12',
+        createTime: '2025-04-01 09:53:28',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867967728584,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+241.0',
+        stakeType: 'K',
+        mileage: 167241,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:53:12',
+        createTime: '2025-04-01 09:53:58',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867967975160,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+241.0',
+        stakeType: 'K',
+        mileage: 167241,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:53:12',
+        createTime: '2025-04-01 09:54:29',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867968221744,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+241.0',
+        stakeType: 'K',
+        mileage: 167241,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:53:12',
+        createTime: '2025-04-01 09:55:00',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867969208024,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+235.0',
+        stakeType: 'K',
+        mileage: 167235,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:56:46',
+        createTime: '2025-04-01 09:57:03',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867969454552,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+235.3',
+        stakeType: 'K',
+        mileage: 167235.3,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:57:16',
+        createTime: '2025-04-01 09:57:34',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867969701016,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+237.0',
+        stakeType: 'K',
+        mileage: 167237,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:57:39',
+        createTime: '2025-04-01 09:58:05',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867969947232,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+234.1',
+        stakeType: 'K',
+        mileage: 167234.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:58:21',
+        createTime: '2025-04-01 09:58:36',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867970193744,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+234.1',
+        stakeType: 'K',
+        mileage: 167234.1,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:58:52',
+        createTime: '2025-04-01 09:59:07',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867970440616,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.2',
+        stakeType: 'K',
+        mileage: 167236.2,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:59:23',
+        createTime: '2025-04-01 09:59:37',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867970686784,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+235.7',
+        stakeType: 'K',
+        mileage: 167235.7,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 09:59:30',
+        createTime: '2025-04-01 10:00:08',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867970933312,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+237.0',
+        stakeType: 'K',
+        mileage: 167237,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:00:17',
+        createTime: '2025-04-01 10:00:39',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867971179808,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+237.0',
+        stakeType: 'K',
+        mileage: 167237,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:00:17',
+        createTime: '2025-04-01 10:01:10',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867971426616,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+237.0',
+        stakeType: 'K',
+        mileage: 167237,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:00:17',
+        createTime: '2025-04-01 10:01:41',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867971672784,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+237.0',
+        stakeType: 'K',
+        mileage: 167237,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:00:17',
+        createTime: '2025-04-01 10:02:11',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867974384400,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+380.0',
+        stakeType: 'K',
+        mileage: 167380,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:07:32',
+        createTime: '2025-04-01 10:07:50',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867974631248,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.6',
+        stakeType: 'K',
+        mileage: 167236.6,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:08:03',
+        createTime: '2025-04-01 10:08:21',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867974877752,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+235.6',
+        stakeType: 'K',
+        mileage: 167235.6,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:08:34',
+        createTime: '2025-04-01 10:08:52',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867975119856,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+232.6',
+        stakeType: 'K',
+        mileage: 167232.6,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:08:57',
+        createTime: '2025-04-01 10:09:22',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867975363520,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+235.7',
+        stakeType: 'K',
+        mileage: 167235.7,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:09:34',
+        createTime: '2025-04-01 10:09:53',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867975610072,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K165+387.7',
+        stakeType: 'K',
+        mileage: 165387.7,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:10:05',
+        createTime: '2025-04-01 10:10:24',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867975856184,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+230.6',
+        stakeType: 'K',
+        mileage: 167230.6,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:10:36',
+        createTime: '2025-04-01 10:10:54',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867976102720,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+235.5',
+        stakeType: 'K',
+        mileage: 167235.5,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:10:51',
+        createTime: '2025-04-01 10:11:25',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867976349496,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.6',
+        stakeType: 'K',
+        mileage: 167236.6,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:11:33',
+        createTime: '2025-04-01 10:11:56',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867976595752,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+232.8',
+        stakeType: 'K',
+        mileage: 167232.8,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:12:12',
+        createTime: '2025-04-01 10:12:27',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867976842304,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+241.8',
+        stakeType: 'K',
+        mileage: 167241.8,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:12:42',
+        createTime: '2025-04-01 10:12:58',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867977089152,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+239.8',
+        stakeType: 'K',
+        mileage: 167239.8,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:13:13',
+        createTime: '2025-04-01 10:13:28',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867977335624,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.5',
+        stakeType: 'K',
+        mileage: 167236.5,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:13:44',
+        createTime: '2025-04-01 10:13:59',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867977581744,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+237.3',
+        stakeType: 'K',
+        mileage: 167237.3,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:14:15',
+        createTime: '2025-04-01 10:14:30',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867978074784,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+239.7',
+        stakeType: 'K',
+        mileage: 167239.7,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:15:12',
+        createTime: '2025-04-01 10:15:32',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867978321336,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+240.8',
+        stakeType: 'K',
+        mileage: 167240.8,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:15:43',
+        createTime: '2025-04-01 10:16:02',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867978567776,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+240.0',
+        stakeType: 'K',
+        mileage: 167240,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:16:14',
+        createTime: '2025-04-01 10:16:33',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867979060840,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+238.0',
+        stakeType: 'K',
+        mileage: 167238,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:17:13',
+        createTime: '2025-04-01 10:17:35',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867979307328,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+238.4',
+        stakeType: 'K',
+        mileage: 167238.4,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:17:52',
+        createTime: '2025-04-01 10:18:06',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867979554296,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+238.2',
+        stakeType: 'K',
+        mileage: 167238.2,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:18:22',
+        createTime: '2025-04-01 10:18:37',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      },
+      {
+        id: 1867979800704,
+        equitId: '4f9d80fe22b34c4ebd0f15dd9579b315',
+        stakeNumber: 'K167+236.9',
+        stakeType: 'K',
+        mileage: 167236.9,
+        isInTunnel: true,
+        longitude: 102.541554,
+        latitude: 30.051554,
+        elevation: 0,
+        tunnelId: 'dt',
+        tunnelPositioningId: 'zj_ylq_dt',
+        workAreaId: '147ff77f39e54c859a55840a9b38ddba',
+        positionTime: '2025-04-01 10:18:52',
+        createTime: '2025-04-01 10:19:07',
+        createBy: 119,
+        tolerantTime: null,
+        startTime: null,
+        endTime: null,
+        isIn: null,
+        state: 0
+      }
+    ]
+  } ],
+  startAnimate: true,
+  dataCheck: -1
 })
 })
+
 // svg 配置
 // svg 配置
 const svgConfig = reactive({
 const svgConfig = reactive({
   width: 600,
   width: 600,
-  height: 400,
-  tunnel: [
+  height: 300,
+  domWidth: 1408,
+  tunnel: [] as any,
+  leng: [] as any
+})
+const devices = ref([] as { [key: string]: any }[])
+const timer = ref()
+const mileage2string = (num: number, type = '') => {
+  const a = Math.floor(num / 1000).toString()
+  const ab = parseFloat((num % 1000).toFixed(1))
+  const b = Math.floor(num % 1000).toString()
+  const c = b.length === 1 ? `00${ab}` : b.length === 2 ? `0${ab}` : ab
+  return `${type}${a}+${c}`
+}
+
+// 初始化svg
+function initSVG() {
+  if (!props.menuItem || !props.menuItem.currentStake) {
+    svgConfig.tunnel = []
+    svgConfig.leng = []
+    window.$notification.warning({ content: `无数据${JSON.stringify(props.menuItem)}`, duration: 3000 })
+    return
+  }
+  const box = document.getElementById('SVGBOX')?.getBoundingClientRect()
+  if (!box?.width) { window.$notification.warning({ content: 'dom初始化错误,请刷新重试!', duration: 3000 }); return }
+  // 隧道长度=已开挖/2+已开挖
+  const width = props.menuItem.isIn ? Math.floor(props.menuItem!.currentStake - props.menuItem!.startStake) : Math.floor(props.menuItem.endStake - props.menuItem.currentStake)
+  svgConfig.width = Math.floor(width / 2 + width)
+  svgConfig.domWidth = box!.width
+  // 计算当前已开挖dom实际位置
+  const w = (width / svgConfig.width) * box!.width
+  svgConfig.tunnel = [
     {
     {
-      type: 1, x: 0, y: 0, w: 400, h: 400, img: new URL('./img/2.png', import.meta.url).href
+      x: 0, y: 0, w: props.menuItem.isIn ? w : box!.width - w, h: svgConfig.height, img: props.menuItem.isIn ? img2 : img1
     },
     },
     {
     {
-      type: 0, x: 400, y: 0, w: 200, h: 400, img: new URL('./img/1.png', import.meta.url).href
+      x: props.menuItem.isIn ? w : box!.width - w, y: 0, w: props.menuItem.isIn ? box!.width - w : w, h: svgConfig.height, img: !props.menuItem.isIn ? img2 : img1
     }
     }
   ]
   ]
-})
-const list = ref([] as { [key: string]: any }[])
+  svgConfig.leng = [
+    {
+      name: '进口', stake: mileage2string(props.menuItem.startStake, props.menuItem!.stakeType), x: 0, type: 'start'
+    },
+    {
+      name: '当前位置', stake: mileage2string(props.menuItem!.currentStake, props.menuItem!.stakeType), x: props.menuItem.isIn ? w : box!.width - w, type: 'middle'
+    },
+    {
+      name: '出口', stake: mileage2string(props.menuItem.endStake, props.menuItem!.stakeType), x: box!.width, type: 'end'
+    }
+  ]
+  console.log('隧道配置', svgConfig)
+  console.log('传递参数', props)
+}
 
 
 // 计算path 路径
 // 计算path 路径
-function countPath(path: number[]) {
+function countPath(arr: { mileage: number }[]) {
+  if (!props.menuItem || !svgConfig.domWidth) return ''
   let str = 'M'
   let str = 'M'
-  const y = Math.floor(Math.random() * (svgConfig.height / 2)) + (svgConfig.height / 4)
-  for (let k = 0; k < path.length; k++) {
-    const el = path[k]
-    str += ` ${el},${y}`
+  const y = svgConfig.height / 2 + svgConfig.height / 4
+  for (let k = 0; k < arr.length; k++) {
+    const el = arr[k]
+    const width = props.menuItem.isIn ? (el.mileage - props.menuItem!.startStake) : (props.menuItem.endStake - el.mileage)
+    const x = props.menuItem?.isIn ? Math.floor((width / svgConfig.width) * svgConfig.domWidth) : svgConfig.domWidth - Math.floor((width / svgConfig.width) * svgConfig.domWidth)
+    str += ` ${x},${y}`
   }
   }
   return str
   return str
 }
 }
 
 
-// 更新数据
-function setData(data = props.data) {
-  list.value = data.map((el, index) => ({
-    ...el,
-    // 原始路径参数
-    path: countPath(el.stakes),
-    pathId: `PATH${index}`,
-    animoId: `Animo${index}`,
-    pathStorkeDasharray: '',
-    animoValues: '',
-    // 动画参数
-    duration: 8,
-    showPath: props.showPath,
-    // 图片参数
-    w: 33.9,
-    h: 60,
-    x: props.showPath ? -16.95 : el.stake,
-    y: props.showPath ? -60 : 60,
-    transform: props.isIn ? 'scale(-1, 1)' : '',
-    callBack() {
-      // 使动画同步
-      const pathDom = document.getElementById(this.pathId) as unknown as SVGPathElement
-      const pathLength = Math.ceil(pathDom?.getTotalLength())
-      this.pathStorkeDasharray = `0, ${pathLength}`
-      this.animoValues = `0, ${pathLength}; ${pathLength}, 0`
-      if (this.showPath) {
-        setTimeout(() => {
-          this.showPath = false
-        }, this.duration * 1000)
+function setData(data: any) {
+  if (!data || !data.length || !svgConfig.tunnel.length || !props.menuItem || !svgConfig.domWidth) { devices.value = []; return }
+  devices.value = data.map((el: { postions: { mileage: number, positionTime: string }[], w: number, isDevice:boolean }, index:number) => {
+    const lastPositon = el.postions[el.postions.length - 1]
+    const width = props.menuItem!.isIn ? (lastPositon.mileage - props.menuItem!.startStake) : (props.menuItem!.endStake - lastPositon.mileage)
+    const x = props.menuItem?.isIn ? Math.floor((width / svgConfig.width) * svgConfig.domWidth) : svgConfig.domWidth - Math.floor((width / svgConfig.width) * svgConfig.domWidth)
+    const y = svgConfig.height / 4
+    const transform = props.menuItem!.isIn && el.isDevice ? '' : `translate(${x + el.w / 2},${y}) scale(-1, 1) translate(${-(x + el.w / 2)},${-y})`
+    const h = svgConfig.height / 2
+    const obj = {
+      ...el,
+      pathId: `SVGPATH${index}`,
+      imgId: `SVGIMG${index}`,
+      pathD: countPath(el.postions),
+      positionTime: lastPositon.positionTime,
+      h,
+      x: props.startAnimate ? el.w / 2 : x,
+      y: props.startAnimate ? -h : y,
+      transform: props.startAnimate ? `translate(${el.w / 2},${h}) scale(-1, 1) translate(-${el.w / 2},-${h})` : transform,
+      mileage: lastPositon.mileage,
+      duration: data.length * 100,
+      startAnimate() {
+        // 路径
+        const g = document.getElementById(this.pathId)
+        // 创建path及动画
+        const pathChild = g?.childNodes
+        if (pathChild?.length) g?.replaceChildren()
+        // 移动目标
+        const img = document.getElementById(this.imgId)
+        const imgChild = img?.querySelectorAll('animateMotion')
+        if (imgChild?.length) imgChild.forEach((el) => el.remove())
+        // 开始动画
+        if (props.startAnimate) {
+        // 设置动画参数
+          const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
+          path.setAttribute('d', this.pathD)
+          path.setAttribute('fill', 'none')
+          path.setAttribute('stroke', '#3498db')
+          path.setAttribute('stroke-width', '1')
+          path.setAttribute('stroke-dashoffset', '0')
+          const pathLength = Math.ceil(path?.getTotalLength())
+          path.setAttribute('stroke-dasharray', `0, ${pathLength}`)
+          const pathAnimate = document.createElementNS('http://www.w3.org/2000/svg', 'animate')
+          pathAnimate.setAttribute('attributeName', 'stroke-dasharray')
+          pathAnimate.setAttribute('begin', '0s')
+          pathAnimate.setAttribute('dur', `${this.duration}s`)
+          pathAnimate.setAttribute('values', `0, ${pathLength}; ${pathLength}, 0`)
+          pathAnimate.setAttribute('calcMode', 'linear')
+          pathAnimate.setAttribute('fill', 'freeze')
+          path.appendChild(pathAnimate)
+          g?.appendChild(path)
+
+          // 给移动目标创建动画
+          const animateMotion = document.createElementNS('http://www.w3.org/2000/svg', 'animateMotion')
+          animateMotion.setAttribute('dur', `${this.duration}s`)
+          animateMotion.setAttribute('fill', 'freeze')
+          animateMotion.setAttribute('path', this.pathD)
+          img?.appendChild(animateMotion)
+
+          // 开始动画
+          animateMotion.beginElement()
+          pathAnimate.beginElement()
+        }
       }
       }
     }
     }
-  }))
-  setTimeout(() => {
-    for (let k = 0; k < list.value.length; k++) {
-      const el = list.value[k]
-      el.callBack()
+    return obj
+  })
+  console.log('台车位置', devices.value)
+  if (timer.value) clearTimeout(timer.value)
+  timer.value = setTimeout(() => {
+    for (let k = 0; k < devices.value.length; k++) {
+      const el = devices.value[k]
+      el.startAnimate()
     }
     }
   }, 200)
   }, 200)
 }
 }
 
 
-onMounted(() => {
-  document.title = 'svg动画同步'
-  setData()
-})
+watch(() => props.menuItem, (v) => initSVG())
+watch(() => props.data, (v) => setData(v))
+onMounted(() => { initSVG(); setData(props.data) })
+onUnmounted(() => clearTimeout(timer.value))
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .box {
 .box {
-  width: 100vw;
-  height: 100vh;
+  width: 1500px;
+  height: 390px;
   background: black;
   background: black;
-  display: flex;
-  align-items: center;
-  justify-content: center;
   svg {
   svg {
-    width: 98%;
-    height: 800px;
+    width: 100%;
+    height: 100%;
+    z-index: 1;
+  }
+
+  &-leng {
+    position: relative;
+    width: 100%;
+    height: 98px;
+    left: 0;
+    bottom: 0;
+
+    &-item {
+      position: absolute;
+      text-align: center;
+      font-size: 0.14rem;
+      top: 50%;
+      transform: translate(0, -50%);
+
+      &:nth-child(2) {
+        top: 0;
+      }
+    }
   }
   }
 }
 }
 </style>
 </style>

+ 0 - 283
src/pages/svgAnimation/newIndex.vue

@@ -1,283 +0,0 @@
-<template>
-    <div class="box">
-      <!-- preserveAspectRatio=none 拉伸 -->
-      <svg
-        :viewBox="`0 0 ${svgConfig.width} ${svgConfig.height}`"
-        preserveAspectRatio="none"
-        version="1.1"
-        xmlns="http://www.w3.org/2000/svg"
-        xmlns:xlink="http://www.w3.org/1999/xlink"
-      >
-        <!-- 图片描边 -->
-        <defs>
-          <!-- 定义描边滤镜 -->
-          <filter
-            id="outline"
-            x="-10%"
-            y="-10%"
-            width="120%"
-            height="120%"
-          >
-            <!-- 扩张图片边缘 -->
-            <feMorphology
-              operator="dilate"
-              radius="3"
-              in="SourceAlpha"
-              result="thicker"
-            />
-            <!-- 描边颜色 -->
-            <feFlood
-              flood-color="#ff0000"
-              result="color"
-            />
-            <!-- 合并描边和原图 -->
-            <feComposite
-              in="color"
-              in2="thicker"
-              operator="in"
-              result="outline"
-            />
-            <feComposite
-              in="SourceGraphic"
-              in2="outline"
-              operator="over"
-            />
-          </filter>
-        </defs>
-        <!-- 底色 -->
-        <image
-          v-for="(item, index) in svgConfig.tunnel"
-          :key="index"
-          :href="item.img"
-          :x="item.x"
-          :y="item.y"
-          :width="item.w"
-          :height="item.h"
-          preserveAspectRatio="none"
-        />
-  
-        <!-- 运动对象 -->
-        <g
-          v-for="(item, index) in list"
-          :key="index"
-        >
-          <!-- 存运动路径+动画 -->
-          <g :id="item.pathId" />
-          <!-- 对象 -->
-          <image
-            :id="item.imgId"
-            :href="item.img"
-            :x="item.x"
-            :y="item.y"
-            :width="item.w"
-            :height="item.h"
-            :transform="item.transform"
-            preserveAspectRatio="none"
-            :filter="props.dataCheck === index ? 'url(#outline)':''"
-          />
-        </g>
-      </svg>
-      <!-- 图例 -->
-      <div class="box-leng">
-        <template
-          v-for="(item, index) in svgConfig.leng"
-          :key="index"
-        >
-          <div
-            class="box-leng-item"
-            :style="`left:${item.x}`"
-          >
-            <p>{{ item.name }}</p>
-            <p>{{ item.stake }}</p>
-          </div>
-        </template>
-      </div>
-    </div>
-  </template>
-  
-  <script setup lang='ts'>
-  import {
-    onMounted, reactive, ref, watch
-  } from 'vue'
-  import { mileage2string } from '@/utils/JsFn'
-  import img1 from './img/1.png'
-  import img2 from './img/2.png'
-  
-  const props = withDefaults(defineProps<{
-    data?: { img: string, postions:any[] }[], // 原始数据
-    dataCheck?:number, // 对象选中
-    startAnimate?:boolean, // 显示动画
-    menuItem?:{isIn:boolean, startStake:number, endStake:number, currentStake:number, length:number, stakeType:string},
-  }>(), {
-    menuItem: undefined,
-    data: undefined,
-    startAnimate: false,
-    dataCheck: -1
-  })
-  const emit = defineEmits<{(evt: 'update:startAnimate', value: boolean): void }>()
-  // svg 配置
-  const svgConfig = reactive({
-    width: 600,
-    height: 400,
-    tunnel: [],
-    leng: []
-  } as {[key:string]:any})
-  const list = ref([] as { [key: string]: any }[])
-  const timer = ref()
-  
-  // 计算path 路径
-  function countPath(path: number[]) {
-    let str = 'M'
-    const y = Math.floor(Math.random() * (svgConfig.height / 2)) + (svgConfig.height / 4)
-    for (let k = 0; k < path.length; k++) {
-      const el = path[k]
-      str += ` ${el},${y}`
-    }
-    return str
-  }
-  
-  // 更新数据
-  function setData(data: any[]|undefined) {
-    if (!data || !data.length || !svgConfig.tunnel.length) {
-      list.value = []
-      return
-    }
-  
-    const scale = props.menuItem!.length / 1358 // 1358 dom宽度,比例
-    list.value = data.map((el, index) => {
-      const x = props.startAnimate ? -el.w / 2 : Math.floor(el.postions[el.postions.length - 1].mileage - props.menuItem!.startStake)
-      const y = props.startAnimate ? el.h ? -el.h : -el.w / scale : Math.floor(Math.random() * (svgConfig.height / 2)) + (svgConfig.height / 4)
-      const transform = el.isDevice && !props.menuItem!.isIn ? `translate(${x + (el.w / 2)},${y}) scale(-1, 1) translate(${-(x + (el.w / 2))},${-y})` : ''
-      const obj = {
-        ...el,
-        path: countPath(el.postions.map((es: { mileage: number; }) => Math.floor((es.mileage - props.menuItem!.startStake) * 10) / 10)),
-        pathId: `PATH${index}`,
-        imgId: `IMG${index}`,
-        duration: 8,
-        w: el.w,
-        h: el.h ? el.h : el.w / scale,
-        x,
-        y, // 随机Y
-        transform,
-        callBack() {
-          const g = document.getElementById(this.pathId)
-          // 创建path及动画
-          const pathChild = g?.childNodes
-          if (pathChild!.length) g?.replaceChildren()
-          // 移动目标
-          const img = document.getElementById(this.imgId)
-          const imgChild = img?.childNodes
-          if (imgChild?.length) img?.replaceChildren()
-          if (props.startAnimate) {
-            const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
-            path.setAttribute('d', this.path)
-            path.setAttribute('fill', 'none')
-            path.setAttribute('stroke', '#3498db')
-            path.setAttribute('stroke-width', '1')
-            path.setAttribute('stroke-dashoffset', '0')
-            const pathLength = Math.ceil(path?.getTotalLength())
-            path.setAttribute('stroke-dasharray', `0, ${pathLength}`)
-            const pathAnimate = document.createElementNS('http://www.w3.org/2000/svg', 'animate')
-            pathAnimate.setAttribute('attributeName', 'stroke-dasharray')
-            pathAnimate.setAttribute('begin', '0s')
-            pathAnimate.setAttribute('dur', `${this.duration}s`)
-            pathAnimate.setAttribute('values', `0, ${pathLength}; ${pathLength}, 0`)
-            pathAnimate.setAttribute('calcMode', 'linear')
-            pathAnimate.setAttribute('fill', 'freeze')
-            path.appendChild(pathAnimate)
-            g?.appendChild(path)
-  
-            // 给移动目标创建动画
-            const animateMotion = document.createElementNS('http://www.w3.org/2000/svg', 'animateMotion')
-            animateMotion.setAttribute('dur', `${this.duration}s`)
-            animateMotion.setAttribute('fill', 'freeze')
-            animateMotion.setAttribute('path', this.path)
-            img?.appendChild(animateMotion)
-            animateMotion.beginElement()
-            pathAnimate.beginElement()
-            emit('update:startAnimate', false)
-            setTimeout(() => {
-              path.style.display = 'none'
-            }, this.duration * 1000)
-          }
-        }
-      }
-      return obj
-    })
-    console.log(888, svgConfig, list.value)
-    if (timer.value) clearTimeout(timer.value)
-    timer.value = setTimeout(() => {
-      for (let k = 0; k < list.value.length; k++) {
-        const el = list.value[k]
-        el.callBack()
-      }
-    }, 200)
-  }
-  
-  // init
-  function initSVG() {
-    if (!props.menuItem || !props.menuItem.currentStake) {
-      svgConfig.tunnel = []
-      svgConfig.leng = []
-      window.$notification.warning({ content: `隧道数据配置错误${JSON.stringify(props.menuItem)}`, duration: 5000 })
-      return
-    }
-    svgConfig.width = props.menuItem!.length
-    svgConfig.tunnel = [
-      {
-        x: 0, y: 0, w: props.menuItem!.currentStake - props.menuItem!.startStake, h: 400, img: props.menuItem!.isIn ? img2 : img1
-      },
-      {
-        x: props.menuItem!.currentStake - props.menuItem!.startStake, y: 0, w: props.menuItem!.length - (props.menuItem!.currentStake - props.menuItem!.startStake), h: 400, img: props.menuItem!.isIn ? img1 : img2
-      }
-    ]
-    svgConfig.leng = [
-      { name: '隧道进口', stake: mileage2string(props.menuItem!.startStake, props.menuItem!.stakeType), x: '0%' },
-      { name: '当前掌子面', stake: mileage2string(props.menuItem!.currentStake, props.menuItem!.stakeType), x: `${(props.menuItem!.currentStake - props.menuItem!.startStake) / props.menuItem!.length * 100 - 2.5}%` },
-      { name: '隧道出口', stake: mileage2string(props.menuItem!.endStake, props.menuItem!.stakeType), x: `${props.menuItem!.length / props.menuItem!.length * 100 - 5}%` }
-    ]
-  }
-  
-  watch(() => props.menuItem, (v) => {
-    initSVG()
-  })
-  
-  watch(() => props.data, (v) => {
-    console.log(777, v)
-  
-    setData(v)
-  })
-  onMounted(() => clearTimeout(timer.value))
-  </script>
-  
-  <style lang="less" scoped>
-  .box {
-    width: 100%;
-    height: 100%;
-  
-    svg {
-      width: 100%;
-      height: calc(100% - 98px);
-      z-index: 1;
-    }
-  
-    &-leng {
-      position: relative;
-      width: 100%;
-      height: 98px;
-      left: 0;
-      bottom: 0;
-  
-      &-item {
-        position: absolute;
-        text-align: center;
-        font-size: 0.14rem;
-        top: 50%;
-        transform: translate(0, -50%);
-        &:nth-child(2){
-          top: 0;
-        }
-      }
-    }
-  }
-  </style>