Преглед на файлове

fix[krpano]: 切换场景未响应

chenlei преди 1 година
родител
ревизия
a868417c7e

+ 1 - 0
packages/krpano-cli/package.json

@@ -13,6 +13,7 @@
     "node": ">=16"
   },
   "dependencies": {
+    "classnames": "^2.3.2",
     "cli-color": "^2.0.3",
     "cli-progress": "^3.12.0",
     "commander": "^11.0.0",

+ 140 - 0
packages/krpano-cli/template/src/pages/Home/constants.tsx

@@ -0,0 +1,140 @@
+import { View } from "@dage/krpano";
+import { ISceneProps } from "@/types";
+
+const URL = "https://houseoss.4dkankan.com/project/leifeng-transfer";
+
+export const CENTER_SCENE_LIST: ISceneProps[] = [
+  {
+    name: "center1",
+    thumbUrl: URL + "/panos/center1.tiles/thumb.jpg",
+    previewUrl: URL + "/panos/center1.tiles/preview.jpg",
+    imageTagAttributes: {
+      type: "cube",
+      tileSize: 512,
+      multires: true,
+    },
+    images: [
+      {
+        tiledImageWidth: 2624,
+        tiledImageHeight: 2624,
+        url: URL + "/panos/center1.tiles/%s/l3/%v/l3_%s_%v_%h.jpg",
+      },
+      {
+        tiledImageWidth: 1280,
+        tiledImageHeight: 1280,
+        url: URL + "/panos/center1.tiles/%s/l2/%v/l2_%s_%v_%h.jpg",
+      },
+      {
+        tiledImageWidth: 640,
+        tiledImageHeight: 640,
+        url: URL + "/panos/center1.tiles/%s/l1/%v/l1_%s_%v_%h.jpg",
+      },
+    ],
+    children: (
+      <View
+        hlookat={0}
+        vlookat={0}
+        fovType="MFOV"
+        fov={120}
+        maxPixelZoom={2}
+        fovMin={70}
+        fovMax={140}
+        limitView="auto"
+      />
+    ),
+  },
+  {
+    name: "center2",
+    thumbUrl: URL + "/panos/center2.tiles/thumb.jpg",
+    previewUrl: URL + "/panos/center2.tiles/preview.jpg",
+    imageTagAttributes: {
+      type: "cube",
+      tileSize: 512,
+      multires: true,
+    },
+    images: [
+      {
+        tiledImageWidth: 2624,
+        tiledImageHeight: 2624,
+        url: URL + "/panos/center2.tiles/%s/l3/%v/l3_%s_%v_%h.jpg",
+      },
+      {
+        tiledImageWidth: 1280,
+        tiledImageHeight: 1280,
+        url: URL + "/panos/center2.tiles/%s/l2/%v/l2_%s_%v_%h.jpg",
+      },
+      {
+        tiledImageWidth: 640,
+        tiledImageHeight: 640,
+        url: URL + "/panos/center2.tiles/%s/l1/%v/l1_%s_%v_%h.jpg",
+      },
+    ],
+    children: (
+      <View
+        hlookat={0}
+        vlookat={0}
+        fovType="MFOV"
+        fov={120}
+        maxPixelZoom={2}
+        fovMin={70}
+        fovMax={140}
+        limitView="auto"
+      />
+    ),
+  },
+];
+
+export const SERVICE_SCENE_LIST: ISceneProps[] = [
+  {
+    name: "service1",
+    thumbUrl: URL + "/panos/service1.tiles/thumb.jpg",
+    previewUrl: URL + "/panos/service1.tiles/preview.jpg",
+    imageTagAttributes: {
+      type: "cube",
+      tileSize: 512,
+      multires: true,
+    },
+    images: [
+      {
+        tiledImageWidth: 2624,
+        tiledImageHeight: 2624,
+        url: URL + "/panos/service1.tiles/%s/l3/%v/l3_%s_%v_%h.jpg",
+      },
+      {
+        tiledImageWidth: 1280,
+        tiledImageHeight: 1280,
+        url: URL + "/panos/service1.tiles/%s/l2/%v/l2_%s_%v_%h.jpg",
+      },
+      {
+        tiledImageWidth: 640,
+        tiledImageHeight: 640,
+        url: URL + "/panos/service1.tiles/%s/l1/%v/l1_%s_%v_%h.jpg",
+      },
+    ],
+    children: (
+      <View
+        hlookat={0}
+        vlookat={0}
+        fovType="MFOV"
+        fov={120}
+        maxPixelZoom={2}
+        fovMin={70}
+        fovMax={140}
+        limitView="auto"
+      />
+    ),
+  },
+];
+
+export const MENUS = [
+  {
+    title: "长沙国防教育馆",
+    scenes: CENTER_SCENE_LIST,
+  },
+  {
+    title: "游客服务中心",
+    scenes: SERVICE_SCENE_LIST,
+  },
+];
+
+export const ALL_SCENES = [...CENTER_SCENE_LIST, ...SERVICE_SCENE_LIST];

+ 40 - 20
packages/krpano-cli/template/src/pages/Home/index.scss

@@ -4,32 +4,52 @@
   overflow: hidden;
 }
 
-.scene-list {
-  display: flex;
-  flex-direction: row;
+$primaryColor: coral;
+
+.scene-panel {
   position: absolute;
-  bottom: 30px;
+  bottom: 80px;
   left: 50%;
   padding: 10px;
   user-select: none;
   transform: translateX(-50%);
   background: rgba(0, 0, 0, 0.4);
-}
 
-.scene-list-item {
-  margin: 0 5px;
-  flex-shrink: 0;
-  width: 170px;
-  height: 100px;
-  cursor: pointer;
-  border: 2px solid transparent;
-}
-.scene-list-item.active {
-  border-color: coral;
-}
+  &__menu {
+    display: flex;
+    gap: 20px;
+    margin-bottom: 10px;
+    color: white;
+
+    &__item {
+      cursor: pointer;
+
+      &.active {
+        color: $primaryColor;
+        font-weight: bold;
+      }
+    }
+  }
+
+  &__list {
+    display: flex;
+    gap: 10px;
+
+    &__item {
+      flex-shrink: 0;
+      width: 150px;
+      height: 80px;
+      cursor: pointer;
+      border: 2px solid transparent;
 
-.scene-list-item > img {
-  width: 100%;
-  height: 100%;
-  object-fit: cover;
+      &.active {
+        border-color: $primaryColor;
+      }
+      & > img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+    }
+  }
 }

+ 47 - 65
packages/krpano-cli/template/src/pages/Home/index.tsx

@@ -1,56 +1,21 @@
-import { useState } from "react";
-import { Krpano, Scene, View } from "@dage/krpano";
-import { ISceneProps } from "@/types";
+import { useMemo, useState } from "react";
+import classnames from "classnames";
+import { Krpano, Scene } from "@dage/krpano";
+import { ALL_SCENES, MENUS } from "./constants";
 import "./index.scss";
 
-const URL = "https://houseoss.4dkankan.com/project/leifeng-transfer";
-
-const CENTER_SCENE_LIST: ISceneProps[] = [
-  {
-    name: "center1",
-    thumbUrl: URL + "/panos/center1.tiles/thumb.jpg",
-    previewUrl: URL + "/panos/center1.tiles/preview.jpg",
-    imageTagAttributes: {
-      type: "cube",
-      tileSize: 512,
-      multires: true,
-    },
-    images: [
-      {
-        tiledImageWidth: 2624,
-        tiledImageHeight: 2624,
-        url: URL + "/panos/center1.tiles/%s/l3/%v/l3_%s_%v_%h.jpg",
-      },
-      {
-        tiledImageWidth: 1280,
-        tiledImageHeight: 1280,
-        url: URL + "/panos/center1.tiles/%s/l2/%v/l2_%s_%v_%h.jpg",
-      },
-      {
-        tiledImageWidth: 640,
-        tiledImageHeight: 640,
-        url: URL + "/panos/center1.tiles/%s/l1/%v/l1_%s_%v_%h.jpg",
-      },
-    ],
-    children: (
-      <View
-        hlookat={0}
-        vlookat={0}
-        fovType="MFOV"
-        fov={120}
-        maxPixelZoom={2}
-        fovMin={70}
-        fovMax={140}
-        limitView="auto"
-      />
-    ),
-  },
-];
-
 export default function HomePage() {
-  const [currentScene, setCurrentScene] = useState(CENTER_SCENE_LIST[0].name);
+  const [currentMenu, setCurrentMenu] = useState(0);
+  const sceneList = useMemo(() => MENUS[currentMenu].scenes, [currentMenu]);
+  const [currentScene, setCurrentScene] = useState(sceneList[0].name);
+
+  const handleSceneClick = (name: string) => {
+    setCurrentScene(name);
+  };
 
-  const handleClick = (name: string) => () => setCurrentScene(name);
+  const handleMenuClick = (idx: number) => {
+    setCurrentMenu(idx);
+  };
 
   return (
     <div className="home-page">
@@ -59,26 +24,43 @@ export default function HomePage() {
         currentScene={currentScene}
         passQueryParameters={true}
       >
-        {CENTER_SCENE_LIST.map((sc) => (
+        {ALL_SCENES.map((sc) => (
           <Scene key={sc.name} {...sc} />
         ))}
       </Krpano>
 
-      <div className="scene-list">
-        {CENTER_SCENE_LIST.map((sc) => (
-          <div
-            key={sc.name}
-            className={`scene-list-item ${
-              sc.name === currentScene ? "active" : ""
-            }`}
-            onClick={handleClick(sc.name)}
-          >
-            <img
-              src={sc.thumbUrl || sc.images![0].url.replace("%s", "f")}
-              alt={sc.name}
-            />
-          </div>
-        ))}
+      <div className="scene-panel">
+        <div className="scene-panel__menu">
+          {MENUS.map((sc, idx) => (
+            <div
+              key={sc.title}
+              className={classnames([
+                "scene-panel__menu__item",
+                idx === currentMenu && "active",
+              ])}
+              onClick={handleMenuClick.bind(undefined, idx)}
+            >
+              {sc.title}
+            </div>
+          ))}
+        </div>
+
+        <div className="scene-panel__list">
+          {sceneList.map((sc) => (
+            <div
+              key={sc.name}
+              className={`scene-panel__list__item ${
+                sc.name === currentScene ? "active" : ""
+              }`}
+              onClick={handleSceneClick.bind(undefined, sc.name)}
+            >
+              <img
+                src={sc.thumbUrl || sc.images![0].url.replace("%s", "f")}
+                alt={sc.name}
+              />
+            </div>
+          ))}
+        </div>
       </div>
     </div>
   );

+ 0 - 5
packages/krpano/src/components/Scene.tsx

@@ -31,8 +31,6 @@ export interface SceneProps {
   images?: [SceneImage] | SceneImageWithMultires[];
 }
 
-let init = false;
-
 export const Scene: React.FC<SceneProps> = ({
   name,
   previewUrl,
@@ -45,7 +43,6 @@ export const Scene: React.FC<SceneProps> = ({
   const currentScene = useContext(CurrentSceneContext);
 
   useEffect(() => {
-    if (init) return;
     const contentImageMeta: XMLMeta = {
       tag: "image",
       // @ts-ignore
@@ -93,8 +90,6 @@ export const Scene: React.FC<SceneProps> = ({
         }`,
     });
 
-    init = true;
-
     return () => {
       renderer?.removeScene(name);
     };

+ 3 - 0
pnpm-lock.yaml

@@ -362,6 +362,9 @@ importers:
 
   packages/krpano-cli:
     dependencies:
+      classnames:
+        specifier: ^2.3.2
+        version: registry.npmmirror.com/classnames@2.3.2
       cli-color:
         specifier: ^2.0.3
         version: registry.npmmirror.com/cli-color@2.0.3