Forráskód Böngészése

[Feat 0000] SVG风门整体的架构更新、实现方法更新

houzekong 3 napja
szülő
commit
2289d5f6b6

+ 43 - 13
src/hooks/vent/useSvgAnimation.ts

@@ -5,7 +5,9 @@ import { ref } from 'vue';
  *
  * 备注:一个元素的动画仅有两种状态,正常播放、倒放;例如:`triggerAnimation(id1, false)`代表触发id1对应的动画,false代表触发正常播放的动画
  */
-export function useSvgAnimation() {
+export function useSvgAnimation(elementInfo: Map<string, { key: string; transforms: string[] }>) {
+  /** 所有动画元素 */
+  const animationElements = new Map<string, HTMLElement>();
   /** 管理节点是否处于初始状态 */
   const animationManager = ref<{ [id: string]: boolean }>({});
 
@@ -17,7 +19,7 @@ export function useSvgAnimation() {
    * @param id 标识符号(可以在页面中使用元素选择器选择具体元素后查询其id),可以传数组
    * @param reverse 是否需要反向执行动画,如果id传了数组该参数可以传数组以一一匹配,默认为false
    */
-  function triggerAnimation(id: string | string[], reverse: boolean | boolean[] = false) {
+  function triggerAnimation(id: string | string[], reverse: boolean | boolean[] = false, duration = 3000) {
     const idArray = typeof id === 'string' ? [id] : id;
     const reverseArray = typeof reverse === 'boolean' ? idArray.map(() => reverse) : reverse;
 
@@ -27,31 +29,59 @@ export function useSvgAnimation() {
       }
       const unchanged = animationManager.value[id];
 
-      //   const element = document.querySelector(`#${id}`) as SVGElement;
-      //   if (!element) return;
-      //   const group = element.parentElement?.parentElement;
-      //   console.log('debug rrrr', element, group);
-      //   if (!group) return;
-
       const reverse = reverseArray[index] || false;
       // 不指定反向播放且group处于初始状态时播放正常动画
       if (!reverse && unchanged) {
-        // group.classList.remove(`${id}_animate_reverse`);
-        // group.classList.add(`${id}_animate`);
         animationManager.value[id] = false;
+        animateByKey(id, true, duration);
         return;
       }
       if (reverse && !unchanged) {
-        // group.classList.remove(`${id}_animate`);
-        // group.classList.add(`${id}_animate_reverse`);
         animationManager.value[id] = true;
+        animateByKey(id, false, duration);
         return;
       }
     });
   }
 
+  // 直接控制动画的方法
+  const animateElement = (elementId: string, toEnd: boolean, duration: number = 3000) => {
+    const el = animationElements.get(elementId);
+    const info = elementInfo.get(elementId);
+
+    if (el && info && info.transforms.length > 1) {
+      el.style.transition = `transform ${duration}ms`;
+      el.setAttribute('transform', toEnd ? info.transforms[info.transforms.length - 1] : info.transforms[0]);
+    }
+  };
+
+  // 批量控制同一key的所有元素
+  const animateByKey = (key: string, toEnd: boolean, duration: number = 3000) => {
+    animationElements.forEach((__, elementId) => {
+      const info = elementInfo.get(elementId);
+      if (info && info.key === key) {
+        animateElement(elementId, toEnd, duration);
+      }
+    });
+  };
+
+  // watch(
+  //   () => animationManager,
+  //   () => {
+  //     Object.keys(animationManager).forEach((key) => {
+  //       const unchanged = animationManager[key];
+
+  //       // 找到所有属于这个key的元素
+  //       animateByKey(key, !unchanged);
+  //     });
+  //   },
+  //   { deep: true }
+  // );
+
   return {
-    animationManager,
+    animationElements,
     triggerAnimation,
+    animateElement,
+    animateByKey,
   };
 }

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 589 - 0
src/views/vent/monitorManager/gateMonitor/components/gateDualSVG.vue


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 58 - 58
src/views/vent/monitorManager/gateMonitor/components/gateSVG.vue


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 589 - 0
src/views/vent/monitorManager/gateMonitor/components/gateTripleSVG.vue


+ 4 - 2
src/views/vent/monitorManager/gateMonitor/gate.data.ts

@@ -319,12 +319,14 @@ export const chartsColumns = [
 export function getModelComponent(is2DModel: boolean = false, sysOrgCode?: string) {
   // @ts-ignore
   return defineAsyncComponent(() => {
+    // return import('./components/gateTripleSVG.vue');
     if (!is2DModel) return import('./components/entryThree.vue');
     switch (sysOrgCode) {
       // case '000000':
-      //   return import('./components/000000.vue');
+      //   双道风门
+      //   return import('./components/gateDualSVG.vue');
       default:
-        return import('./components/gateSVG.vue');
+        return import('./components/gateTripleSVG.vue');
     }
   });
 }

+ 12 - 20
src/views/vent/monitorManager/gateMonitor/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <component :loading="loading" :manager="animationManager" :is="modelComponent" />
+  <component ref="modelRef" :loading="loading" :is="modelComponent" />
   <div class="scene-box">
     <div class="top-box">
       <div class="top-center row">
@@ -340,7 +340,7 @@
 </template>
 
 <script setup lang="ts">
-  import { onBeforeUnmount, onUnmounted, onMounted, ref, reactive, nextTick, inject, unref, defineAsyncComponent } from 'vue';
+  import { onBeforeUnmount, onUnmounted, onMounted, ref, reactive, nextTick, inject, unref, defineAsyncComponent, provide } from 'vue';
   import MonitorTable from '../comment/MonitorTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
   import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
@@ -374,10 +374,10 @@
   const { sysOrgCode } = useGlobSetting();
   const globalConfig = inject<any>('globalConfig');
 
+  const modelRef = ref();
   /** 模型对应的组件,根据实际情况分为二维三维 */
   const modelComponent = getModelComponent(globalConfig.is2DModel, sysOrgCode);
 
-  const { animationManager, triggerAnimation } = useSvgAnimation();
   const { currentRoute } = useRouter();
   const MonitorDataTable = ref();
   let contrlValue = '';
@@ -978,77 +978,71 @@
     if (selectData.frontGateOpen == '1' && selectData.frontGateClose == '0' && !isFrontOpenRunning) {
       isFrontOpenRunning = true;
       if (frontDeviceState != 1) {
-        // 反转播放前门动画即为播放关门动画
-        triggerAnimation('___L_0_Layer0_0_FILL', true);
-        // 播放后门动画即为播放开门动画
-        triggerAnimation('___R_0_Layer0_0_FILL', false);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(1, timeScale) : play(1);
         play(1, timeScale);
         frontDeviceState = 1;
         frontDoorIsOpen.value = false;
         backDoorIsOpen.value = true;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
 
     if (selectData.frontGateOpen == '0' && selectData.frontGateClose == '0' && !isFrontOpenRunning) {
       isFrontOpenRunning = true;
       if (frontDeviceState != 1) {
-        triggerAnimation('___L_0_Layer0_0_FILL', true);
-        triggerAnimation('___R_0_Layer0_0_FILL', false);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(1, timeScale) : play(1);
         play(1, timeScale);
         frontDeviceState = 1;
         frontDoorIsOpen.value = false;
         backDoorIsOpen.value = true;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
 
     if (selectData.frontGateClose == '1' && selectData.frontGateOpen == '0' && isFrontOpenRunning) {
       isFrontOpenRunning = false;
       if (frontDeviceState != 0) {
-        triggerAnimation('___L_0_Layer0_0_FILL', true);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(2, timeScale) : play(2);
         play(2, timeScale);
         frontDeviceState = 0;
         frontDoorIsOpen.value = false;
         // backDoorIsOpen.value = false
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
     if (selectData.rearGateOpen == '1' && selectData.rearGateClose == '0' && !isRearOpenRunning) {
       isRearOpenRunning = true;
 
       if (rearDeviceState != 1) {
-        triggerAnimation('___L_0_Layer0_0_FILL', false);
-        triggerAnimation('___R_0_Layer0_0_FILL', true);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(3, timeScale) : play(3);
         play(3, timeScale);
         rearDeviceState = 1;
         backDoorIsOpen.value = false;
         frontDoorIsOpen.value = true;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
     if (selectData.rearGateOpen == '0' && selectData.rearGateClose == '0' && !isRearOpenRunning) {
       isRearOpenRunning = true;
 
       if (rearDeviceState != 1) {
-        triggerAnimation('___L_0_Layer0_0_FILL', false);
-        triggerAnimation('___R_0_Layer0_0_FILL', true);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(3, timeScale) : play(3);
         play(3, timeScale);
         rearDeviceState = 1;
         backDoorIsOpen.value = false;
         frontDoorIsOpen.value = true;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
 
     if (selectData.rearGateClose == '1' && selectData.rearGateOpen == '0' && isRearOpenRunning) {
       isRearOpenRunning = false;
       if (rearDeviceState != 0) {
-        triggerAnimation('___R_0_Layer0_0_FILL', true);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(4, timeScale) : play(4);
         play(4, timeScale);
         rearDeviceState = 0;
         backDoorIsOpen.value = false;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
 
@@ -1056,13 +1050,12 @@
       isMidOpenRunning = true;
 
       if (midDeviceState != 1) {
-        triggerAnimation('___L_0_Layer0_0_FILL', false);
-        triggerAnimation('___R_0_Layer0_0_FILL', true);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(3, timeScale) : play(3);
         play(8, timeScale);
         midDeviceState = 1;
         backDoorIsOpen.value = false;
         frontDoorIsOpen.value = true;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
 
@@ -1070,24 +1063,23 @@
       isMidOpenRunning = true;
 
       if (midDeviceState != 1) {
-        triggerAnimation('___L_0_Layer0_0_FILL', false);
-        triggerAnimation('___R_0_Layer0_0_FILL', true);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(3, timeScale) : play(3);
         play(8, timeScale);
         midDeviceState = 1;
         backDoorIsOpen.value = false;
         frontDoorIsOpen.value = true;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
 
     if (selectData.midGateClose == '1' && selectData.midGateOpen == '0' && isMidOpenRunning) {
       isMidOpenRunning = false;
       if (midDeviceState != 0) {
-        triggerAnimation('___R_0_Layer0_0_FILL', true);
         // import.meta.env.VITE_GLOB_IS_SIMULATE ? play(4, timeScale) : play(4);
         play(9, timeScale);
         midDeviceState = 0;
         backDoorIsOpen.value = false;
+        modelRef.value?.animate?.(frontDoorIsOpen.value, midDoorIsOpen.value, backDoorIsOpen.value);
       }
     }
   }

+ 1 - 1
src/views/vent/monitorManager/windowMonitor/components/windowSVG.vue

@@ -1636,7 +1636,7 @@
 
   // 批量控制同一key的所有元素
   const animateByKey = (key: string, toEnd: boolean, duration: number = 3000) => {
-    animElements.forEach((el, elementId) => {
+    animElements.forEach((__, elementId) => {
       const info = elementInfo.get(elementId);
       if (info && info.key === key) {
         animateElement(elementId, toEnd, duration);

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott