bill 5 kuukautta sitten
vanhempi
commit
751b7b6456
3 muutettua tiedostoa jossa 265 lisäystä ja 13 poistoa
  1. 1 0
      src/api/animation.ts
  2. 262 11
      src/sdk/association/animation.ts
  3. 2 2
      src/sdk/sdk.ts

+ 1 - 0
src/api/animation.ts

@@ -55,6 +55,7 @@ export type AnimationModelPath = {
 };
 
 export interface AnimationModel {
+  key?: string
   id: string;
   title: string;
   url: string;

+ 262 - 11
src/sdk/association/animation.ts

@@ -1,16 +1,267 @@
-import { AnimationModel } from "@/api";
-import { AnimationGroup, AnimationModel3D, SDK } from "../sdk";
+import {
+  AnimationModel,
+  AnimationModelAction,
+  AnimationModelFrame,
+  AnimationModelPath,
+} from "@/api";
+import {
+  AnimationGroup,
+  AnimationModel3D,
+  AnimationModelAction3D,
+  AnimationModelFrame3D,
+  AnimationModelPath3D,
+  SDK,
+  sdk as _sdk,
+} from "../sdk";
+import { computed, nextTick, reactive, watch, watchEffect } from "vue";
+import { ams } from "@/store/animation";
+import { mergeFuns } from "@/components/drawing/hook";
+import { getPathNode } from "./path";
 
-export let animationGroup: AnimationGroup
+export let animationGroup: AnimationGroup;
+const getAMKey = (am: AnimationModel) => am.key || am.id;
 
-const amMap: Record<string, AnimationModel3D> = {}
-export const getAM = (data: AnimationModel) => {
-  if (data.id in amMap) {
-    return amMap[data.id]
+const amMap: Record<
+  string,
+  {
+    am?: AnimationModel3D;
+    frames: Record<string, AnimationModelFrame3D>;
+    actions: Record<string, AnimationModelAction3D>;
+    paths: Record<string, AnimationModelPath3D>;
   }
-  amMap[data.id]
-}
+> = reactive({});
+export const addAM = (data: AnimationModel): Promise<AnimationModel3D> => {
+  const key = getAMKey(data);
+  const stopLoad = watch(
+    () => {
+      const exixts = ams.value.some((am) => getAMKey(am) === key);
+      return [key, exixts] as const;
+    },
+    ([key, exixts]) => {
+      if (!exixts) {
+        const des = amMap[key];
+        if (!des) return;
+        Object.values(des.frames || {}).forEach((frame) => frame.destory());
+        Object.values(des.actions || {}).forEach((frame) => frame.destory());
+        Object.values(des.paths || {}).forEach((frame) => frame.destory());
+        des.am?.destory();
+        delete amMap[key];
+      } else if (!amMap[key]) {
+        amMap[key] = {
+          frames: {},
+          actions: {},
+          paths: {},
+        };
+        animationGroup
+          .addAnimationModel(data)
+          .then((am) => (amMap[key].am = am));
+      }
+    },
+    { immediate: true }
+  );
+
+  const stopAttrib = mergeFuns(
+    () =>
+      watchEffect(() =>
+        amMap[key].am?.changeVisibilityRange(
+          data.globalVisibility ? undefined : data.visibilityRange
+        )
+      ),
+    watchEffect(() => amMap[key].am?.changeTitle(data.title)),
+    watchEffect(() => amMap[key].am?.visibilityTitle(data.showTitle)),
+    watchEffect(() => amMap[key].am?.changeFontSize(data.fontSize))
+  );
+
+  const stopWatch = watch(
+    () => ams.value.includes(data),
+    (exists) => {
+      if (!exists) {
+        stopLoad();
+        stopAttrib();
+        stopWatch();
+      }
+    },
+    { flush: "post" }
+  );
+
+  return new Promise((resolve) => {
+    const stopWatch = watchEffect(() => {
+      if (amMap[key]?.am) {
+        resolve(amMap[key]!.am!);
+        nextTick(() => stopWatch());
+      }
+    });
+  });
+};
+
+export const addFrame = (
+  data: AnimationModelFrame
+): Promise<AnimationModelFrame3D> => {
+  const am = ams.value.find((item) =>
+    item.frames.find(({ id }) => id === data.id)
+  );
+  if (!am) {
+    throw "找不到am数据";
+  }
+
+  const key = getAMKey(am);
+  const stopLoad = watch(
+    () => {
+      const exists = am.frames.some(({ id }) => id === data.id);
+      return [amMap[key], exists] as const;
+    },
+    ([map, exists]) => {
+      if (!map.am) return;
+      if (exists && !map.frames[data.id]) {
+        map.frames[data.id] = map.am.addFrame(data);
+      } else if (!exists && map.frames[data.id]) {
+        map.frames[data.id].destory();
+        delete map.frames[data.id];
+      }
+    }
+  );
+
+  const stopAttrib = mergeFuns(() =>
+    watchEffect(() => amMap[key].frames[data.id]?.changeTime(data.time))
+  );
+
+  const stopWatch = watch(
+    () => am.frames.includes(data),
+    (exists) => {
+      if (!exists) {
+        stopLoad();
+        stopAttrib();
+        stopWatch();
+      }
+    },
+    { flush: "post" }
+  );
+
+  return new Promise((resolve) => {
+    const stopWatch = watchEffect(() => {
+      if (amMap[key]?.frames[data.id]) {
+        resolve(amMap[key].frames[data.id]);
+        nextTick(() => stopWatch());
+      }
+    });
+  });
+};
+
+export const addAction = (
+  data: AnimationModelAction
+): Promise<AnimationModelAction3D> => {
+  const am = ams.value.find((item) =>
+    item.actions.find(({ id }) => id === data.id)
+  );
+  if (!am) {
+    throw "找不到am数据";
+  }
+
+  const key = getAMKey(am);
+  const stopLoad = watch(
+    () => {
+      const exists = am.actions.some(({ id }) => id === data.id);
+      return [amMap[key], exists] as const;
+    },
+    ([map, exists]) => {
+      if (!map.am) return;
+      if (exists && !map.actions[data.id]) {
+        map.actions[data.id] = map.am.addAction(data);
+      } else if (!exists && map.actions[data.id]) {
+        map.actions[data.id].destory();
+        delete map.actions[data.id];
+      }
+    }
+  );
+
+  const stopAttrib = mergeFuns(
+    () => watchEffect(() => amMap[key].actions[data.id]?.changeTime(data.time)),
+    () => watchEffect(() => amMap[key].actions[data.id]?.changeAmplitude(data.amplitude)),
+    () => watchEffect(() => amMap[key].actions[data.id]?.changeSpeed(data.speed)),
+    () => watchEffect(() => amMap[key].actions[data.id]?.changeDuration(data.duration)),
+  );
+
+  const stopWatch = watch(
+    () => am.actions.includes(data),
+    (exists) => {
+      if (!exists) {
+        stopLoad();
+        stopAttrib();
+        stopWatch();
+      }
+    },
+    { flush: "post" }
+  );
+
+  return new Promise((resolve) => {
+    const stopWatch = watchEffect(() => {
+      if (amMap[key]?.actions[data.id]) {
+        resolve(amMap[key].actions[data.id]);
+        nextTick(() => stopWatch());
+      }
+    });
+  });
+};
+
+
+export const addPath = (
+  data: AnimationModelPath
+): Promise<AnimationModelPath3D> => {
+  const am = ams.value.find((item) =>
+    item.paths.find(({ id }) => id === data.id)
+  );
+  if (!am) {
+    throw "找不到am数据";
+  }
+  const path = computed(() => data.pathId ? getPathNode(data.pathId) : undefined)
+  const key = getAMKey(am);
+  const stopLoad = watch(
+    () => {
+      const exists = am.paths.some(({ id }) => id === data.id);
+      return [amMap[key], exists, path.value] as const;
+    },
+    ([map, exists, path]) => {
+      if (!map.am || !path) return;
+      if (exists && !map.paths[data.id]) {
+        map.paths[data.id] = map.am.addPath({...data, path});
+      } else if (!exists && map.paths[data.id]) {
+        map.paths[data.id].destory();
+        delete map.paths[data.id];
+      }
+    }
+  );
+
+  const stopAttrib = mergeFuns(
+    () => watchEffect(() => amMap[key].paths[data.id]?.changeTime(data.time)),
+    () => watchEffect(() => amMap[key].paths[data.id]?.changeReverse(data.reverse)),
+    () => watchEffect(() => amMap[key].paths[data.id]?.changeDuration(data.duration)),
+    () => watchEffect(() => amMap[key].paths[data.id]?.changePath(path.value)),
+  );
+
+  const stopWatch = watch(
+    () => am.paths.includes(data),
+    (exists) => {
+      if (!exists) {
+        stopLoad();
+        stopAttrib();
+        stopWatch();
+      }
+    },
+    { flush: "post" }
+  );
+
+  return new Promise((resolve) => {
+    const stopWatch = watchEffect(() => {
+      if (amMap[key]?.paths[data.id]) {
+        resolve(amMap[key].paths[data.id]);
+        nextTick(() => stopWatch());
+      }
+    });
+  });
+};
 
 export const associationAnimation = (sdk: SDK, el: HTMLDivElement) => {
-  animationGroup = sdk.createAnimationGroup()
-}
+  animationGroup = sdk.createAnimationGroup();
+
+  
+};

+ 2 - 2
src/sdk/sdk.ts

@@ -366,7 +366,7 @@ export type AnimationGroup = {
   // 暂停
   pause: () => void;
   // 添加动画模型
-  addAnimationModel: (data: AnimationModel) => AnimationModel3D;
+  addAnimationModel: (data: AnimationModel) => Promise<AnimationModel3D>;
 
   // 设置当前时间, 单位为秒
   setCurrentTime: (s: number) => void
@@ -440,7 +440,7 @@ export type AnimationModelPath3D = {
   // 销毁动画模型路径
   destory: () => void;
   // 修改路径 传入参数为你之前返回的路径对象
-  changePath: (path: Path) => void
+  changePath: (path: Path | undefined) => void
   // 修改播放是否要反向
   changeReverse: (reverse: boolean) => void
   // 修改路径播放时间 单位为秒