Quellcode durchsuchen

feat(start): 开场视频

lanxin vor 8 Monaten
Ursprung
Commit
cd224e1539

+ 5 - 16
src/pages/A0base/component/Panoramic.tsx

@@ -1,15 +1,5 @@
 import React, { useState, useMemo, useEffect } from 'react'
-import {
-  Autorotate,
-  Krpano,
-  Scene,
-  View,
-  HotSpot,
-  Events,
-  SceneProps,
-  ROTATE_DIRECTION,
-  ZOOM_ACTION
-} from '@dage/krpano'
+import { Autorotate, Krpano, Scene, View, HotSpot, Events, SceneProps } from '@dage/krpano'
 import styles from './index.module.scss'
 
 interface ISceneProps extends Partial<SceneProps> {
@@ -25,7 +15,6 @@ const Panoramic = ({
   setIsPreview: (isPreview: [boolean, string]) => void
   isDisolay: boolean
 }) => {
-  // const [currentMenu, setCurrentMenu] = useState(0)
   const [currentScene, setCurrentScene] = useState('center2')
   const [autorotateEnable, setAutorotateEnable] = useState(false)
 
@@ -39,8 +28,8 @@ const Panoramic = ({
     () => [
       {
         name: 'center2',
-        thumbUrl: '/panos/22.tiles/thumb.jpg',
-        previewUrl: '/panos/22.tiles/preview.jpg',
+        thumbUrl: './panos/22.tiles/thumb.jpg',
+        previewUrl: './panos/22.tiles/preview.jpg',
         imageTagAttributes: {
           type: 'cube',
           tileSize: 512,
@@ -60,7 +49,7 @@ const Panoramic = ({
           {
             tiledImageWidth: 640,
             tiledImageHeight: 640,
-            url: '/panos/22.tiles/pano_%s.jpg'
+            url: './panos/22.tiles/pano_%s.jpg'
           }
         ],
         children: (
@@ -197,7 +186,7 @@ const Panoramic = ({
       <Krpano
         className='krpano'
         // xml='/tour.xml'
-        webvrUrl='/webvr.xml'
+        webvrUrl='./webvr.xml'
         currentScene={currentScene}
         // littlePlanetIntro={true}
         passQueryParameters={true}

+ 47 - 0
src/pages/A0base/component/startVideo.tsx

@@ -0,0 +1,47 @@
+import React, { useEffect, useRef } from 'react'
+
+const VideoPlayer = ({ setIsEnd }: { setIsEnd: (isEnd: boolean) => void }) => {
+  const videoRef = useRef<HTMLVideoElement>(null)
+
+  useEffect(() => {
+    const video = videoRef.current
+    if (!video) return
+
+    // 处理视频播放
+    const handlePlay = async () => {
+      try {
+        await video.play()
+      } catch (error) {
+        console.error('视频播放失败:', error)
+      }
+    }
+
+    // 添加播放结束监听
+    const handleEnded = () => setIsEnd(true)
+    video.addEventListener('ended', handleEnded)
+
+    // 现代浏览器自动播放策略处理
+    if (video.paused) {
+      handlePlay()
+    }
+
+    // 清理函数
+    return () => {
+      video.removeEventListener('ended', handleEnded)
+      video.pause()
+    }
+  }, [setIsEnd])
+
+  return (
+    <video
+      ref={videoRef}
+      src={require('../image/video/shenzhen.mp4')}
+      muted
+      playsInline // 添加iOS内联播放支持
+      controls={false}
+      onError={e => console.error('视频加载失败:', e)}
+    />
+  )
+}
+
+export default VideoPlayer

BIN
src/pages/A0base/image/video/shenzhen.mp4


+ 125 - 100
src/pages/A0base/index.tsx

@@ -3,12 +3,7 @@ import styles from './index.module.scss'
 import classNames from 'classnames'
 import http from '@/utils/http'
 import { useHistory } from 'react-router-dom'
-import taohuanyuan from './image/D_taohuayuan.png'
-import taohuanyuanMobile from './image/M_D_taohuayuan.png'
-import xingtong from './image/D_xingtong.png'
-import xingtongMobile from './image/M_D_xingtong.png'
-import xuni from './image/D_xuni.png'
-import address from './image/D_address.png'
+import StartVideo from './component/startVideo'
 import like from './image/icon_like.png'
 import share from './image/icon_share.png'
 import intro from './image/icon_intro.png'
@@ -43,47 +38,47 @@ const imgArrTemp2 = [
   { src: 'nan-6.jpg', title: '会议室' }
 ]
 
-function Diagram({
-  imgSrc,
-  left,
-  top,
-  addressLeft,
-  addressTop,
-  text,
-  handleClick,
-  textLeft,
-  textTop
-}: {
-  imgSrc: any
-  left: number
-  top: number
-  addressLeft: number
-  addressTop: number
-  textLeft?: number
-  textTop?: number
-  text: string
-  handleClick: () => void
-}) {
-  console.log(imgSrc)
-  console.log(taohuanyuan)
-  return (
-    <div
-      className={classNames(styles.diagram, isMobile() && styles.diagramMobile)}
-      style={{ left: `${left}%`, top: `${top}%` }}
-    >
-      <img className='diagram-img' src={imgSrc} onClick={handleClick} alt='' />
-      {isMobile() && (
-        <div className='diagram-text' style={{ left: `${textLeft}%`, top: `${textTop}%` }}>
-          {text}
-        </div>
-      )}
-      <div className='diagram-address' style={{ left: `${addressLeft}%`, top: `${addressTop}%` }}>
-        <img src={address} alt='' />
-        {!isMobile() && <div className='diagram-text'>{text}</div>}
-      </div>
-    </div>
-  )
-}
+// function Diagram({
+//   imgSrc,
+//   left,
+//   top,
+//   addressLeft,
+//   addressTop,
+//   text,
+//   handleClick,
+//   textLeft,
+//   textTop
+// }: {
+//   imgSrc: any
+//   left: number
+//   top: number
+//   addressLeft: number
+//   addressTop: number
+//   textLeft?: number
+//   textTop?: number
+//   text: string
+//   handleClick: () => void
+// }) {
+//   console.log(imgSrc)
+//   console.log(taohuanyuan)
+//   return (
+//     <div
+//       className={classNames(styles.diagram, isMobile() && styles.diagramMobile)}
+//       style={{ left: `${left}%`, top: `${top}%` }}
+//     >
+//       <img className='diagram-img' src={imgSrc} onClick={handleClick} alt='' />
+//       {isMobile() && (
+//         <div className='diagram-text' style={{ left: `${textLeft}%`, top: `${textTop}%` }}>
+//           {text}
+//         </div>
+//       )}
+//       <div className='diagram-address' style={{ left: `${addressLeft}%`, top: `${addressTop}%` }}>
+//         <img src={address} alt='' />
+//         {!isMobile() && <div className='diagram-text'>{text}</div>}
+//       </div>
+//     </div>
+//   )
+// }
 
 function Layout({ setIsFloor }: { setIsFloor: (isFloor: boolean) => void }) {
   const history = useHistory()
@@ -122,6 +117,7 @@ function Layout({ setIsFloor }: { setIsFloor: (isFloor: boolean) => void }) {
 }
 
 function A0Base() {
+  const [isEnd, setIsEnd] = useState(false)
   const [showIntro, setShowIntro] = useState(false)
   const [isFloor, setIsFloor] = useState(false)
   const [isPreview, setIsPreview] = useState<[boolean, string]>([false, ''])
@@ -140,8 +136,26 @@ function A0Base() {
     setShowIntro(isShow)
   }
   const handleShareClick = () => {
-    navigator.clipboard.writeText(window.location.href)
-    message.success('链接已复制到剪贴板')
+    try {
+      if (window.isSecureContext && navigator.clipboard) {
+        navigator.clipboard.writeText(window.location.href).then(() => {
+          message.success('链接已复制到剪贴板')
+        })
+      } else {
+        // 回退到旧方法
+        const textArea = document.createElement('textarea')
+        textArea.value = window.location.href
+        document.body.appendChild(textArea)
+        textArea.select()
+        document.execCommand('copy')
+        document.body.removeChild(textArea)
+        message.success('链接已复制到剪贴板')
+      }
+    } catch (err) {
+      console.error('复制失败:', err)
+      // 可提示用户手动复制
+      message.error('浏览器不支持自动复制,请手动复制当前链接')
+    }
   }
   const handleLikeClick = () => {
     if (isLike) return
@@ -154,63 +168,74 @@ function A0Base() {
     }, 2000)
   }
   return (
-    <div
-      className={classNames(styles.A0base, isMobile() && styles.A0baseMobile)}
-      style={{
-        backgroundImage: isFloor
-          ? isMobile()
-            ? `url(${require('./image/M_bg_floor.png')})`
-            : `url(${require('./image/bg_floor.png')})`
-          : isMobile()
-          ? `url(${require('./image/M_bg_map.png')})`
-          : `url(${require('./image/bg_map.png')})`
-      }}
-    >
-      {isFloor && !showIntro && <Layout setIsFloor={setIsFloor} />}
-      {showIntro &&
-        (isFloor ? (
-          <Intro handleIntroClick={handleIntroClick} />
-        ) : (
-          <MapIntro handleIntroClick={handleIntroClick} />
-        ))}
+    <>
+      {!isEnd ? (
+        <StartVideo setIsEnd={setIsEnd} />
+      ) : (
+        <div
+          className={classNames(styles.A0base, isMobile() && styles.A0baseMobile)}
+          style={{
+            backgroundImage: isFloor
+              ? isMobile()
+                ? `url(${require('./image/M_bg_floor.png')})`
+                : `url(${require('./image/bg_floor.png')})`
+              : isMobile()
+              ? `url(${require('./image/M_bg_map.png')})`
+              : `url(${require('./image/bg_map.png')})`
+          }}
+        >
+          {isFloor && !showIntro && <Layout setIsFloor={setIsFloor} />}
+          {showIntro &&
+            (isFloor ? (
+              <Intro handleIntroClick={handleIntroClick} />
+            ) : (
+              <MapIntro handleIntroClick={handleIntroClick} />
+            ))}
 
-      <Panoramic
-        setIsFloor={setIsFloor}
-        setIsPreview={setIsPreview}
-        isDisolay={!isFloor && !isPreview[0]}
-      />
+          <Panoramic
+            setIsFloor={setIsFloor}
+            setIsPreview={setIsPreview}
+            isDisolay={!isFloor && !isPreview[0]}
+          />
 
-      {isPreview[0] && (
-        <Preview
-          imgArr={isPreview[1] === 'baoan' ? imgArrTemp : imgArrTemp2}
-          setIsPreview={setIsPreview}
-          type={isPreview[1]}
-        />
-      )}
-      <div
-        className='A0_iconBar'
-        style={{ display: isPreview[0] || (isMobile() && showIntro) ? 'none' : 'flex' }}
-      >
-        <div className='A0_icon' onClick={() => handleLikeClick()}>
+          {isPreview[0] && (
+            <Preview
+              imgArr={isPreview[1] === 'baoan' ? imgArrTemp : imgArrTemp2}
+              setIsPreview={setIsPreview}
+              type={isPreview[1]}
+            />
+          )}
           <div
-            className={classNames(isLike ? 'addLikeAc' : '', 'addLike')}
-            style={{ opacity: !isLike ? 0 : 1 }}
+            className='A0_iconBar'
+            style={{ display: isPreview[0] || (isMobile() && showIntro) ? 'none' : 'flex' }}
           >
-            +1
+            <div className='A0_icon' onClick={() => handleLikeClick()}>
+              <div
+                className={classNames(isLike ? 'addLikeAc' : '', 'addLike')}
+                style={{ opacity: !isLike ? 0 : 1 }}
+              >
+                +1
+              </div>
+              <img className='A0_icon_like' src={like} alt='' />
+              <div>{likeCount}次赞</div>
+            </div>
+            <div className='A0_icon'>
+              <img
+                className='A0_icon_intro'
+                onClick={() => setShowIntro(true)}
+                src={intro}
+                alt=''
+              />
+              <div>简介</div>
+            </div>
+            <div className='A0_icon' onClick={() => handleShareClick()}>
+              <img className='A0_icon_share' src={share} alt='' />
+              <div>分享</div>
+            </div>
           </div>
-          <img className='A0_icon_like' src={like} alt='' />
-          <div>{likeCount}次赞</div>
-        </div>
-        <div className='A0_icon'>
-          <img className='A0_icon_intro' onClick={() => setShowIntro(true)} src={intro} alt='' />
-          <div>简介</div>
         </div>
-        <div className='A0_icon' onClick={() => handleShareClick()}>
-          <img className='A0_icon_share' src={share} alt='' />
-          <div>分享</div>
-        </div>
-      </div>
-    </div>
+      )}
+    </>
   )
 }