浏览代码

fix[krpano]: 热点初始加载不显示

chenlei 1 年之前
父节点
当前提交
b52cd61bf7

+ 10 - 5
packages/krpano/src/KrpanoActionProxy.ts

@@ -32,10 +32,14 @@ export class KrpanoActionProxy {
     this.dynamicTagWaitQueue = new PromiseQueue();
   }
 
-  waitIncludeLoad() {
+  /**
+   * 等待 include 标签加载完成
+   */
+  waitIncludeLoaded(push?: boolean) {
     return this.syncTagsLoaded
       ? Promise.resolve()
-      : this.dynamicTagWaitQueue.push();
+      : // 先进后出
+        this.dynamicTagWaitQueue[push ? "push" : "unshift"]();
   }
 
   /**
@@ -70,7 +74,7 @@ export class KrpanoActionProxy {
       nexttick = true;
     }
 
-    await this.waitIncludeLoad();
+    await this.waitIncludeLoaded();
 
     this.call(
       buildKrpanoTagSetterActions(name ? `${tag}[${name}]` : tag, attrs),
@@ -203,10 +207,11 @@ export class KrpanoActionProxy {
     });
   }
 
-  addHotspot(
+  async addHotspot(
     name: string,
     attrs: Record<string, string | boolean | number | undefined>
-  ): void {
+  ) {
+    await this.waitIncludeLoaded();
     this.call(buildKrpanoAction("addhotspot", name), true);
     this.setTag("hotspot", name, attrs);
   }

+ 5 - 0
packages/krpano/src/PromiseQueue.ts

@@ -14,6 +14,11 @@ export class PromiseQueue<T> {
       this.queue.push({ resolve, reject });
     });
   };
+  unshift = () => {
+    return new Promise<T>((resolve, reject) => {
+      this.queue.unshift({ resolve, reject });
+    });
+  };
 
   /**
    * 清空队列, 正常结束

+ 26 - 15
packages/krpano/src/components/Krpano.tsx

@@ -1,8 +1,7 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
+import React, { useCallback, useEffect, useState } from "react";
 import { KrpanoActionProxy } from "../KrpanoActionProxy";
-import { useEventCallback } from "../hooks";
+import { useMounted, useEventCallback } from "../hooks";
 import { IKrpanoConfig, NativeKrpanoRendererObject } from "../types";
-import { useKrpano } from "../hooks/useKrpano";
 import { CurrentSceneContext, KrpanoRendererContext } from "../contexts";
 import { buildKrpanoAction } from "../utils";
 import { WebVR } from "./WebVR";
@@ -31,7 +30,6 @@ export const Krpano: React.FC<KrpanoProps> = ({
   ...rest
 }) => {
   const [renderer, setRenderer] = useState<KrpanoActionProxy | null>(null);
-  const restRef = useEventCallback(rest);
   const onReadyRef = useEventCallback(onReady);
   const onReadyCallback = useCallback(
     (obj: NativeKrpanoRendererObject) => {
@@ -45,16 +43,6 @@ export const Krpano: React.FC<KrpanoProps> = ({
     },
     [onReadyRef]
   );
-  const krpanoConfig = useMemo(
-    () => ({
-      target,
-      onready: onReadyCallback,
-      ...restRef.current,
-    }),
-    [target, restRef, onReadyCallback]
-  );
-
-  useKrpano(krpanoConfig);
 
   useEffect(() => {
     if (!renderer) return;
@@ -79,11 +67,34 @@ export const Krpano: React.FC<KrpanoProps> = ({
   useEffect(() => {
     if (!renderer || !currentScene) return;
 
-    renderer.waitIncludeLoad().then(() => {
+    renderer.waitIncludeLoaded(true).then(() => {
       renderer.loadScene(currentScene);
     });
   }, [renderer, currentScene]);
 
+  const initKrpano = () => {
+    const defaultConfig: Partial<IKrpanoConfig> = {
+      html5: "auto",
+      xml: null,
+      mobilescale: 1,
+    };
+
+    if (typeof window.embedpano === "function") {
+      window.embedpano({
+        ...defaultConfig,
+        target,
+        onready: onReadyCallback,
+        ...rest,
+      });
+    } else {
+      throw new Error("Krpano required");
+    }
+  };
+
+  useMounted(() => {
+    initKrpano();
+  });
+
   return (
     <KrpanoRendererContext.Provider value={renderer}>
       <CurrentSceneContext.Provider value={currentScene || null}>

+ 1 - 0
packages/krpano/src/hooks/index.ts

@@ -1 +1,2 @@
 export * from "./useEventCallback";
+export * from "./useCreate";

+ 12 - 0
packages/krpano/src/hooks/useCreate.ts

@@ -0,0 +1,12 @@
+import { useEffect, useRef } from "react";
+
+export function useMounted(cb: Function) {
+  const initialized = useRef(false);
+
+  useEffect(() => {
+    if (!initialized.current) {
+      initialized.current = true;
+      cb();
+    }
+  }, []);
+}

+ 0 - 27
packages/krpano/src/hooks/useKrpano.ts

@@ -1,27 +0,0 @@
-import { useEffect, useRef } from "react";
-import { IKrpanoConfig } from "../types";
-
-export const useKrpano = (config: IKrpanoConfig): void => {
-  const isCreated = useRef(false);
-
-  useEffect(() => {
-    const defaultConfig: Partial<IKrpanoConfig> = {
-      html5: "auto",
-      xml: null,
-      mobilescale: 1,
-    };
-    const embedpano = () => {
-      if (typeof window.embedpano === "function") {
-        window.embedpano({ ...defaultConfig, ...config });
-      }
-    };
-
-    if (typeof window.embedpano === "function") {
-      (config.xml || !isCreated.current) && embedpano();
-
-      isCreated.current = true;
-    } else {
-      throw new Error("Krpano required");
-    }
-  }, [config]);
-};