lanxin 13 saat önce
ebeveyn
işleme
c79551ea43

+ 8 - 0
pano/src/components/Pano/index.module.scss

@@ -174,5 +174,13 @@
     .A0hotspot-distance-3 {
     .A0hotspot-distance-3 {
       transform: rotate(26.3deg);
       transform: rotate(26.3deg);
     }
     }
+
+    @media screen and (max-width: 500px) {
+      // 取消hover
+      .A0hotspot:has(.text:hover) {
+        background-image: url('../../assets/img/hotpot_bg.png');
+        color: rgba(112, 73, 7, 1);
+      }
+    }
   }
   }
 }
 }

BIN
project/public/siji.ts


+ 39 - 19
project/src/pages/A0base/index.tsx

@@ -5,6 +5,7 @@ import A0_home_1 from '@/assets/img/A0_home_1.jpg';
 import A0_home_2 from '@/assets/img/A0_home_2.jpg';
 import A0_home_2 from '@/assets/img/A0_home_2.jpg';
 import A0_home_3 from '@/assets/img/A0_home_3.jpg';
 import A0_home_3 from '@/assets/img/A0_home_3.jpg';
 import homeLogo from '@/assets/img/A0_home_logo.png'; // 推荐直接 import 图片
 import homeLogo from '@/assets/img/A0_home_logo.png'; // 推荐直接 import 图片
+import { baseOssUrl, envFlag } from '@/utils/http';
 
 
 /** 以「页面上真实 img」为准:load + decode + 双 rAF,避免与独立 new Image() 不同步 */
 /** 以「页面上真实 img」为准:load + decode + 双 rAF,避免与独立 new Image() 不同步 */
 function useDomImageReady(
 function useDomImageReady(
@@ -50,9 +51,14 @@ function useDomImageReady(
   }, [ref]);
   }, [ref]);
 }
 }
 
 
+/** 与首页 F_Video('siji.ts') 同源,便于浏览器缓存命中 */
+function getIntroVideoTsUrl(): string {
+  return new URL('siji.ts', !envFlag ? "https://houseoss.4dkankan.com/project/gmlx/" : window.location.origin).href;
+}
+
 function A0base() {
 function A0base() {
   const [currentIndex, setCurrentIndex] = useState(0);
   const [currentIndex, setCurrentIndex] = useState(0);
-  const [progress, setProgress] = useState(0); // 进度 0 ~ 100
+  const [progress, setProgress] = useState(0); // 四图就绪后:0 ~ 100 为视频预加载字节进度
   const [assetsReady, setAssetsReady] = useState(false);
   const [assetsReady, setAssetsReady] = useState(false);
   const images = useMemo(() => [A0_home_1, A0_home_2, A0_home_3], []);
   const images = useMemo(() => [A0_home_1, A0_home_2, A0_home_3], []);
 
 
@@ -76,29 +82,43 @@ function A0base() {
   useEffect(() => {
   useEffect(() => {
     if (!assetsReady) return;
     if (!assetsReady) return;
 
 
-    const interval = setInterval(() => {
-      setProgress(prev => {
-        const next = prev + 1;
-        if (next >= 100) {
-          clearInterval(interval);
-          setTimeout(() => {
-            history.push('/home');
-          }, 1500);
-          return 100;
-        }
-        return next;
-      });
-    }, 50); // 每 50ms 增加 1%
+    const url = getIntroVideoTsUrl();
+    const xhr = new XMLHttpRequest();
+    xhr.open('GET', url, true);
+    xhr.responseType = 'blob';
+
+    xhr.onprogress = (e) => {
+      if (e.lengthComputable && e.total > 0) {
+        setProgress(Math.min(100, Math.round((e.loaded / e.total) * 100)));
+      }
+    };
+
+    xhr.onload = () => {
+      setProgress(100);
+      setTimeout(() => {
+        history.push('/home');
+      }, 1500);
+    };
+
+    xhr.onerror = () => {
+      setProgress(100);
+      setTimeout(() => {
+        history.push('/home');
+      }, 1500);
+    };
+
+    xhr.send();
 
 
-    return () => clearInterval(interval);
+    // 不 abort:避免 Strict Mode / 快速重挂载导致重复请求、进度异常
+    return () => {};
   }, [assetsReady]);
   }, [assetsReady]);
 
 
-  // 根据进度切换图片
+  // 根据进度切换图片(进度条在四图就绪后才会从 0 增长)
   useEffect(() => {
   useEffect(() => {
     if (progress >= 65) {
     if (progress >= 65) {
-      setCurrentIndex(2); 
+      setCurrentIndex(2);
     } else if (progress >= 30) {
     } else if (progress >= 30) {
-      setCurrentIndex(1); 
+      setCurrentIndex(1);
     } else {
     } else {
       setCurrentIndex(0);
       setCurrentIndex(0);
     }
     }
@@ -128,4 +148,4 @@ function A0base() {
 
 
 const MemoA0base = React.memo(A0base);
 const MemoA0base = React.memo(A0base);
 
 
-export default MemoA0base;
+export default MemoA0base;

+ 33 - 11
project/src/pages/A1home/index.tsx

@@ -13,6 +13,7 @@ function A1home() {
   const [activeIndex, setActiveIndex] = useState(-1)
   const [activeIndex, setActiveIndex] = useState(-1)
 
 
   const scrollRef = useRef<HTMLDivElement>(null)
   const scrollRef = useRef<HTMLDivElement>(null)
+  const videoRef = useRef<any>(null)
   const sceneList = myDataTemp.sceneList
   const sceneList = myDataTemp.sceneList
   const totalScenes = sceneList.length
   const totalScenes = sceneList.length
 
 
@@ -29,18 +30,39 @@ function A1home() {
     }
     }
   }, [])
   }, [])
 
 
-    // 初始视频
-    useEffect(() => {
-      const params = {
-        objectFit: 'cover', // 视频的object-fit样式, 默认 cover
-        loop: true, // 是否循环, 默认false
-        autoplay: true, // 自动播放, 默认false
-        onSourceEstablished: () => { } //有足够的数据可以播放了
+  // 初始视频:进入全景时及时销毁,避免继续占用解码资源
+  useEffect(() => {
+    const dom = document.querySelector('.baseVideo')
+    if (!dom) return
+
+    if (isOpenPano) {
+      if (videoRef.current?.destroy) {
+        videoRef.current.destroy()
       }
       }
-      const videoInit = F_Video('siji.ts', params)
-      const dom = document.querySelector('.baseVideo')!
-      dom.append(videoInit.domElement)
-    }, [])
+      videoRef.current = null
+      dom.innerHTML = ''
+      return
+    }
+
+    const params = {
+      objectFit: 'cover', // 视频的object-fit样式, 默认 cover
+      loop: true, // 是否循环, 默认false
+      autoplay: true, // 自动播放, 默认false
+      onSourceEstablished: () => {} //有足够的数据可以播放了
+    }
+
+    const videoInit = F_Video('siji.ts', params)
+    videoRef.current = videoInit
+    dom.append(videoInit.domElement)
+
+    return () => {
+      if (videoRef.current?.destroy) {
+        videoRef.current.destroy()
+      }
+      videoRef.current = null
+      dom.innerHTML = ''
+    }
+  }, [isOpenPano])
 
 
   const handleItemClick = (item: any, index: number) => {
   const handleItemClick = (item: any, index: number) => {
     setCurrentSceneIndex(index)
     setCurrentSceneIndex(index)