lanxin 12 ore fa
parent
commit
f8ed423daf

+ 1 - 0
project/public/myData/myData.js

@@ -55,6 +55,7 @@ const myDataTemp = {
             thumbUrl: '',
         }
     ],
+    architectureAnimation: 'myData/media/bgVideo.mp4',
     memberList: [
         {
             name:'台灯',

BIN
project/src/assets/img/A4_member_btn.png


BIN
project/src/assets/img/A6_life_intro.png


BIN
project/src/assets/img/A6_life_intro_title.png


+ 63 - 0
project/src/components/Zvideo/index.module.scss

@@ -0,0 +1,63 @@
+.Zvideo {
+  width: 100%;
+  height: 100%;
+  :global{
+    .custom-media-controller {
+      width: 100%;
+      height: 100%;
+      & > video {
+        width: 100%;
+        height: 100%;
+        object-fit: fill;
+      }
+      & > media-control-bar {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 70%;
+        gap: 10px;
+        margin: 0 auto;
+      }
+      media-play-button {
+        width: 40px;
+        height: 40px;
+        border-radius: 50%;
+        background-color: rgba(167, 31, 30, 1);
+        border: none;
+        display: flex;
+        align-self: center;
+      }
+      .progress {
+        width: 70%;
+        height: 50px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        flex-direction: column;
+        & > media-time-range {
+          width: 100%;
+          height: 10px;
+          --media-range-bar-color: rgba(167, 31, 30, 1);
+          --media-range-track-background: rgba(230, 203, 160, 1); // 未播放部分背景
+          border-radius: 5px;
+          --media-range-track-fill-background: rgba(167, 31, 30, 1);
+        }
+        cursor: pointer;
+      }
+      .time {
+        display: flex;
+        justify-content: flex-end;
+        width: 80px;
+        color: rgba(230, 203, 160, 1);
+        align-items: center;
+        media-time-display,
+        media-duration-display {
+          font-size: 16px;
+          background: none;
+          color: rgba(230, 203, 160, 1);
+        }
+      }
+    }
+  }
+  
+}

+ 27 - 0
project/src/components/Zvideo/index.tsx

@@ -0,0 +1,27 @@
+import React, { useRef } from 'react'
+import styles from './index.module.scss'
+import 'media-chrome'
+function Zvideo({ src }: { src: string }) {
+  const videoRef = useRef<HTMLVideoElement>(null)
+  return (
+    <div className={styles.Zvideo}>
+      <media-controller class='custom-media-controller'>
+        <video ref={videoRef} slot='media' src={src} className='modal-video'></video>
+        <media-control-bar>
+          <media-play-button></media-play-button>
+          <div className='progress'>
+            <media-time-range></media-time-range>
+          </div>
+          <div className='time'>
+            <media-time-display></media-time-display>/
+            <media-duration-display></media-duration-display>
+          </div>
+        </media-control-bar>
+      </media-controller>
+    </div>
+  )
+}
+
+const MemoZvideo = React.memo(Zvideo)
+
+export default MemoZvideo

+ 4 - 17
project/src/pages/A3architecture/index.tsx

@@ -1,26 +1,13 @@
-import React, { useRef } from 'react'
+import React from 'react'
 import styles from './index.module.scss'
-import 'media-chrome'
 import MenuSider from '@/components/MenuSider'
+import Zvideo from '@/components/Zvideo'
 function A3architecture() {
-  const videoRef = useRef<HTMLVideoElement>(null)
-  const currentVideoSrc = 'myData/media/bgVideo.mp4'
+  const currentVideoSrc = myDataTemp.architectureAnimation
 
   return (
     <div className={styles.A3architecture}>
-      <media-controller class='custom-media-controller'>
-        <video ref={videoRef} slot='media' src={currentVideoSrc} className='modal-video'></video>
-        <media-control-bar>
-          <media-play-button></media-play-button>
-          <div className='progress'>
-            <media-time-range></media-time-range>
-          </div>
-          <div className='time'>
-            <media-time-display></media-time-display>/
-            <media-duration-display></media-duration-display>
-          </div>
-        </media-control-bar>
-      </media-controller>
+      <Zvideo src={currentVideoSrc} />
       <MenuSider isSidebarOpen={false} />
     </div>
   )

+ 23 - 0
project/src/pages/A4member/index.module.scss

@@ -62,6 +62,17 @@
           }
         }
 
+        .btnBox {
+          position: absolute;
+          bottom: 0;
+          left: 0;
+          transform: translate(72%, -56%);
+          width: 5vw;
+          height: 18vh;
+          cursor: pointer;
+          display: none;
+        }
+
         .imgBox {
           position: absolute;
           right: 0;
@@ -228,6 +239,9 @@
               2px 2px 4px rgba(0, 0, 0, 0.6);
           }
         }
+        .btnBox {
+          display: block;
+        }
       }
 
       .imgShow {
@@ -254,4 +268,13 @@
       }
     }
   }
+
+  .videoBox {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    z-index: 100;
+  }
 }

+ 33 - 9
project/src/pages/A4member/index.tsx

@@ -1,11 +1,13 @@
 import React, { useRef, useEffect, useState } from 'react'
 import styles from './index.module.scss'
 import MenuSider from '@/components/MenuSider'
-
+import Zvideo from '@/components/Zvideo'
+import Zback from '@/components/Zback'
 function A4Member() {
   const scrollRef = useRef<HTMLDivElement>(null)
   const [currentIndex, setCurrentIndex] = useState(0)
   const [hasHover, setHasHover] = useState(true)
+  const [isShowVideo, setIsShowVideo] = useState(false)
   useEffect(() => {
     const mq = window.matchMedia('(hover: hover)')
     setHasHover(mq.matches)
@@ -32,16 +34,18 @@ function A4Member() {
         {myDataTemp.memberList.map((item, index) => (
           <>
             <div
-                className={`item ${currentIndex === index ? `itemAc itemAc${index + 1}` : ''}`}
-                key={index}
-                onMouseEnter={hasHover ? () => setCurrentIndex(index) : undefined}
-                onClick={!hasHover ? () => setCurrentIndex(index) : undefined}
-              >
+              className={`item ${currentIndex === index ? `itemAc itemAc${index + 1}` : ''}`}
+              key={index}
+              onMouseEnter={hasHover ? () => setCurrentIndex(index) : undefined}
+              onClick={!hasHover ? () => setCurrentIndex(index) : () => setIsShowVideo(true)}
+            >
               <div className='nameBox'>
                 <div className='up'>
                   <img
                     draggable={false}
-                    src={require(`../../assets/img/A4_member_up${currentIndex === index ? '_ac' : ''}.png`)}
+                    src={require(
+                      `../../assets/img/A4_member_up${currentIndex === index ? '_ac' : ''}.png`
+                    )}
                     alt=''
                   />
                 </div>
@@ -49,7 +53,9 @@ function A4Member() {
                 <div className='down'>
                   <img
                     draggable={false}
-                    src={require(`../../assets/img/A4_member_down${currentIndex === index ? '_ac' : ''}.png`)}
+                    src={require(
+                      `../../assets/img/A4_member_down${currentIndex === index ? '_ac' : ''}.png`
+                    )}
                     alt=''
                   />
                 </div>
@@ -71,16 +77,34 @@ function A4Member() {
                 </div>
                 <div className='nameEn'>{item.nameEn}</div>
               </div>
+              {/* 在一体机有按钮 */}
+              {!hasHover ? (
+                <div className='btnBox' onClick={() => setIsShowVideo(true)}>
+                  <img
+                    draggable={false}
+                    src={require('../../assets/img/A4_member_btn.png')}
+                    alt=''
+                  />
+                </div>
+              ) : null}
             </div>
             <div className='split'>
               <img draggable={false} src={require('../../assets/img/A4_member_split.png')} alt='' />
             </div>
           </>
         ))}
-        <div className="item" style={{width: '10%'}}></div>
+        <div className='item' style={{ width: '10%' }}></div>
       </div>
 
       <MenuSider isSidebarOpen={false} />
+
+      {/* 动画 */}
+      {isShowVideo ? (
+        <div className={styles.videoBox}>
+          <Zvideo src={myDataTemp.memberList[currentIndex].videoSrc} />
+          <Zback onBack={() => setIsShowVideo(false)} />
+        </div>
+      ) : null}
     </div>
   )
 }

+ 55 - 2
project/src/pages/A6life/Intro/index.module.scss

@@ -1,4 +1,57 @@
-.AAAAA {
-  :global {
+.Intro {
+  width: 100%;
+  height: 100%;
+  padding: 8% 8% 2% 8%;
+  display: flex;
+  align-items: center;
+  gap: 2%;
+  .imgBox {
+    width: 55%;
+    height: 100%;
+    .imgBoxInner{
+      width: 100%;
+      height: 100%;
+      background-image: url('../../../assets/img/A6_life_intro.png');
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      background-position: center center;
+      & >img {
+        padding: 2.5%;
+        width: 100%;
+        height: 100%;
+        object-fit: fill;
+      }
+    } 
+  }
+  .textBox {
+    width: 45%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    gap: 2vh;
+    .textTop{
+      width: 70%;
+      height: 10vh;
+      background-image: url('../../../assets/img/A6_life_intro_title.png');
+      background-size: contain;
+      background-repeat: no-repeat;
+      background-position: center center;
+      text-align: center;
+      font-size: 1.5vw;
+      line-height: 9.5vh;
+      font-weight: bold;
+      color: rgba(249, 211, 109, 1);
+
+    }
+    .textBottom{
+      width: 90%;
+      height: fit-content;
+      max-height: calc(100% - 12vh);
+      font-size: 1.1vw;
+      line-height: 1.8;
+      color: rgba(78, 47, 23, 1);
+    }
   }
 }

+ 6 - 3
project/src/pages/A6life/Intro/index.tsx

@@ -1,16 +1,19 @@
 import React from "react";
 import styles from "./index.module.scss";
- function Intro({activeIndex}: {activeIndex: number}) {
+import Zback from "@/components/Zback";
+ function Intro({activeIndex, setIsShowIntro}: {activeIndex: number, setIsShowIntro: (isShow: boolean) => void}) {
   
   return (
     <div className={styles.Intro}>
      <div className={styles.imgBox}>
-      <img src={require('../../../assets/img/A6_life_intro.png')} alt="" />
+      <div className={styles.imgBoxInner}><img src={myDataTemp.lifeList[activeIndex].imgSrc} alt="" /></div>
+      
      </div>
      <div className={styles.textBox}>
       <div className={styles.textTop}>{myDataTemp.lifeList[activeIndex].name}</div>
-      <div className={styles.textBottom}>{myDataTemp.lifeList[activeIndex].time}</div>
+      <div className={styles.textBottom}>{myDataTemp.lifeList[activeIndex].desc}</div>
      </div>
+     <Zback onBack={() => setIsShowIntro(false)}/>
     </div>
   )
 }

+ 8 - 0
project/src/pages/A6life/Record/index.module.scss

@@ -0,0 +1,8 @@
+  .Record {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 100;
+}

+ 17 - 0
project/src/pages/A6life/Record/index.tsx

@@ -0,0 +1,17 @@
+import React from "react";
+import styles from "./index.module.scss";
+import Zvideo from "@/components/Zvideo";
+import Zback from "@/components/Zback";
+ function Record({activeIndex, setActiveIndex}: {activeIndex: number, setActiveIndex: (index: number) => void}) {
+  
+  return (
+    <div className={styles.Record}>
+     <Zvideo src={myDataTemp.lifeList[activeIndex].videoSrc || ''} />
+     <Zback onBack={() => setActiveIndex(activeIndex-1)}/>
+    </div>
+  )
+}
+
+const MemoRecord = React.memo(Record);
+
+export default MemoRecord;

+ 4 - 2
project/src/pages/A6life/Swiper/index.tsx

@@ -8,10 +8,12 @@ import 'swiper/css/navigation'
 import { EffectCoverflow, Pagination, Navigation } from 'swiper/modules'
 function SwiperComponent({
   activeIndex,
-  setActiveIndex
+  setActiveIndex,
+  setIsShowIntro
 }: {
   activeIndex: number
   setActiveIndex: (index: number) => void
+  setIsShowIntro: (isShow: boolean) => void
 }) {
   const swiperRef = useRef<any>(null)
   // 是否点击bottom改变了activeIndex
@@ -64,11 +66,11 @@ function SwiperComponent({
         {myDataTemp.lifeList.map((item, index) => (
           <SwiperSlide key={index}>
             <div className={`itemCard ${activeIndex === index ? 'itemCardActive' : ''}`}>
-              {item.name}
               <div className='itemImage'>
                 <img className='itemImageImg' src={item?.imgSrc} alt='' />
                 <img
                   className='detailIcon'
+                  onClick={() => setIsShowIntro(true)}
                   src={require('../../../assets/img/A6_life_look.png')}
                   alt=''
                 />

+ 5 - 2
project/src/pages/A6life/index.tsx

@@ -2,16 +2,18 @@ import React, { useState } from 'react'
 import styles from './index.module.scss'
 import MenuSider from '@/components/MenuSider'
 import SwiperComponent from './Swiper'
+import Intro from './Intro'
+import Record from './Record'
 function A6life() {
   const [activeIndex, setActiveIndex] = useState(0)
+  const [isShowIntro, setIsShowIntro] = useState(false)
   const lifeList = myDataTemp.lifeList
-
   return (
     <div className={styles.A6life}>
       <div className={styles.lifeContent}>
        
         <div className={styles.top}>
-          <SwiperComponent activeIndex={activeIndex} setActiveIndex={setActiveIndex}/>
+          {isShowIntro ? <Intro activeIndex={activeIndex} setIsShowIntro={setIsShowIntro}/> : <SwiperComponent activeIndex={activeIndex} setActiveIndex={setActiveIndex} setIsShowIntro={setIsShowIntro}/>}
         </div>
         <div className={styles.bottom}>
           <div className={styles.timeline}>
@@ -52,6 +54,7 @@ function A6life() {
 
         <MenuSider isSidebarOpen={false} />
       </div>
+      {activeIndex===lifeList.length-1 ? <Record activeIndex={activeIndex} setActiveIndex={setActiveIndex}/> : null}
     </div>
   )
 }

+ 1 - 0
project/src/types/declaration.d.ts

@@ -19,6 +19,7 @@ type MyDataType = {
   isLdong: boolean
   siderData: { title: string; path: string }[]
   sceneList: { id: string; name: string; thumbUrl: string }[]
+  architectureAnimation: string
   memberList: { name: string; nameEn: string; imgSrc: string; imgSrcLight: string; videoSrc: string }[]
   lifeList: { name: string; time: string; imgSrc: string; videoSrc?: string; desc: string }[]
 }