chenlei 15 часов назад
Родитель
Сommit
ad979e82eb

Разница между файлами не показана из-за своего большого размера
+ 32 - 16
code/public/myData/data.js


+ 10 - 0
code/src/App.tsx

@@ -16,6 +16,8 @@ const A2show = React.lazy(() => import('./pages/A2show'))
 const A3wear = React.lazy(() => import('./pages/A3wear'))
 const A0model = React.lazy(() => import('./pages/A0model'))
 const A4scene = React.lazy(() => import('./pages/A4scene'))
+const A5ip = React.lazy(() => import('./pages/A5ip'))
+const A5ipDetail = React.lazy(() => import('./pages/A5ip/detail'))
 
 export default function App() {
   // 从仓库中获取查看图片的信息
@@ -51,6 +53,14 @@ export default function App() {
       element: <A4scene />
     },
     {
+      path: '/ip',
+      element: <A5ip />
+    },
+    {
+      path: '/ip/detail',
+      element: <A5ipDetail />
+    },
+    {
       index: true,
       element: <A1home />
     },

BIN
code/src/assets/img/icon-caidan1-min.png


+ 1 - 0
code/src/components/Z1titie/index.module.scss

@@ -4,6 +4,7 @@
   justify-content: center;
   align-items: center;
   position: relative;
+  z-index: 99;
 
   :global {
     .Z1_1 {

+ 1 - 1
code/src/pages/A0model/A0btn/index.tsx

@@ -55,7 +55,7 @@ function A0btn({ cutModelFu }: Props) {
     <>
       {/* 顶部 */}
       <div className={styles.A0top}>
-        <Z1titie title={infoObj.title} backFu={() => history.push('/show')} />
+        <Z1titie title={infoObj.title} toHome={() => history.push('/?mask=1')} />
         <div className='A0topTit'>{infoObj.text}</div>
       </div>
 

+ 10 - 1
code/src/pages/A1home/index.tsx

@@ -1,10 +1,19 @@
-import React, { useState } from 'react'
+import React, { useEffect, useState } from 'react'
+import { useSearchParams } from 'react-router-dom'
 import styles from './index.module.scss'
 import Z1titie from '@/components/Z1titie'
 import history from '@/utils/history'
 
 function A1home() {
   const [showMask, setShowMask] = useState(false)
+  const [searchParams] = useSearchParams()
+
+  useEffect(() => {
+    const mask = searchParams.get('mask')
+    if (mask) {
+      setShowMask(true)
+    }
+  }, [searchParams])
 
   const handleStartClick = () => {
     setShowMask(true)

+ 1 - 1
code/src/pages/A2show/index.tsx

@@ -17,7 +17,7 @@ function A2show() {
       className={styles.A2show}
       style={{ backgroundImage: `url(${serverUrl}show/bac.jpg)` }}
     >
-      <Z1titie title='玉柄铁剑' toHome={() => history.push('/')} />
+      <Z1titie title='玉柄铁剑' toHome={() => history.push('/?mask=1')} />
 
       <div className='A2txt'>
         <p>春秋中晚期 | 藏于十堰市博物馆</p>

+ 2 - 2
code/src/pages/A3wear/index.tsx

@@ -28,8 +28,8 @@ function A3wear() {
       <Z1titie
         title={move || tab ? '璏式佩剑法' : '佩带方式'}
         backFu={() => {
-          if (tab) setTab('')
-          else history.push('/show')
+          setMove(false)
+          setTab('')
         }}
       />
       {/* 底部按钮 */}

BIN
code/src/pages/A4scene/images/card-ft-bg-min.png


BIN
code/src/pages/A4scene/images/cover-b.png


BIN
code/src/pages/A4scene/images/cover-t.png


BIN
code/src/pages/A4scene/images/icon-ChangJing.png


BIN
code/src/pages/A4scene/images/icon-ChangJing_1.png


BIN
code/src/pages/A4scene/images/icon-guanbi.png


+ 87 - 31
code/src/pages/A4scene/index.module.scss

@@ -3,46 +3,90 @@
   flex-direction: column;
 
   :global {
-    .A4sceneList {
-      flex: 1;
-      display: flex;
-      flex-direction: column;
-      margin-top: 25px;
-      padding: 0 20px 25px;
-      overflow-y: auto;
-      gap: 20px;
+    .A4sceneCover {
+      position: relative;
+      margin-top: -64px;
+      height: 333px;
+      background-size: cover;
+      background-position: center center;
 
-      .A4sceneCard {
-        flex-shrink: 0;
-        position: relative;
-        height: 188px;
-        overflow: hidden;
-        border-radius: 7px;
-        background-size: cover;
-        background-position: center;
-        background-repeat: no-repeat;
-        box-shadow: 0px 0 7px 0px rgba(0,0,0,0.6);
-      }
-      .A4sceneCardFt {
+      &::before {
+        content: '';
         position: absolute;
+        top: 0;
         left: 0;
         right: 0;
+        height: 98px;
+        background: linear-gradient(to bottom, rgba(25, 12, 0, 0.80), transparent);
+      }
+      &::after {
+        content: '';
+        position: absolute;
         bottom: 0;
-        padding: 0 12px;
+        left: 0;
+        right: 0;
+        height: 43px;
+        background: linear-gradient(to bottom, transparent, rgba(147, 115, 85, 0.80), rgba(94, 54, 16, 1));
+      }
+      .A4sceneCoverFooter {
+        position: absolute;
+        left: 19px;
+        right: 13px;
+        bottom: 7px;
         display: flex;
         align-items: center;
         justify-content: space-between;
-        height: 43px;
-        color: #FCE9AC;
-        font-size: 15px;
-        font-weight: bold;
-        background: url('./images/card-ft-bg-min.png') no-repeat center / cover;
-      
-        &::after {
-          content: '';
+        z-index: 1;
+
+        img {
           width: 23px;
           height: 23px;
-          background: url('./images/play.png') no-repeat center / cover;
+          cursor: pointer;
+        }
+        p {
+          font-weight: bold;
+          font-size: 15px;
+          color: #FCE9AC;
+        }
+      }
+    }
+    .A4sceneDesc {
+      flex: 1;
+      height: 0;
+      overflow-y: auto;
+      margin-top: 18px;
+      padding: 0 19px;
+      font-size: 12px;
+      color: #FCE9AC;
+      line-height: 24px;
+      text-indent: 2em;
+    }
+    .A4sceneList {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding: 18px 17px 43px;
+      gap: 7px;
+
+      li {
+        padding: 0 10px;
+        width: 63px;
+        height: 43px;
+        color: #FFFDDC;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 12px;
+        line-height: 15px;
+        background: url('./images/icon-ChangJing.png') no-repeat center / contain;
+      
+        &.A4sceneListAc {
+          color: #2D0C05;
+          background-image: url('./images/icon-ChangJing_1.png');
+        }
+        p {
+          width: 28px;
+          text-align: center;
         }
       }
     }
@@ -54,11 +98,23 @@
   align-items: center;
   justify-content: center;
   padding: 0 20px;
+  overflow: hidden;
 
   :global {
     video {
-      width: 100%;
+      width: 100vh;
+      height: 100vw;
+      object-fit: contain;
+      transform: rotate(90deg);
+      transform-origin: center center;
       object-fit: cover;
     }
+    img {
+      position: absolute;
+      right: 20px;
+      bottom: 40px;
+      width: 403x;
+      height: 40px;
+    }
   }
 }

+ 30 - 18
code/src/pages/A4scene/index.tsx

@@ -1,12 +1,19 @@
-import React, { useState } from 'react'
+import React, { useMemo, useState } from 'react'
 import styles from './index.module.scss'
 import Z1titie from '@/components/Z1titie'
 import history from '@/utils/history'
 import { Mask } from 'antd-mobile'
+import playIcon from './images/play.png'
+import closeIcon from './images/icon-guanbi.png'
+import classNames from 'classnames'
 
 function A4scene() {
+  const [curIndex, setCurIndex] = useState(0)
   const [visible, setVisible] = useState(false)
-  const [videoPath, setVideoPath] = useState('')
+
+  const detail = useMemo(() => {
+    return VIDEO_LIST[curIndex]
+  }, [curIndex])
 
   return (
     <div
@@ -15,24 +22,22 @@ function A4scene() {
     >
       <Z1titie
         title='使用场景'
-        backFu={() => {
-          history.push('/show')
-        }}
+        toHome={() => history.push('/?mask=1')}
       />
 
+      <div className='A4sceneCover' style={{ backgroundImage: `url(${serverUrl}${detail.coverPath})` }}>
+        <div className='A4sceneCoverFooter'>
+          <p>{detail.name}</p>
+          <img src={playIcon} alt='play' onClick={() => setVisible(true)} />
+        </div>
+      </div>
+
+      <div className='A4sceneDesc' dangerouslySetInnerHTML={{ __html: detail?.desc }} />
+
       <ul className='A4sceneList'>
-        {VIDEO_LIST.map(item => (
-          <li className='A4sceneCard'
-            key={item.name}
-            style={{ backgroundImage: `url(${serverUrl}${item.coverPath})` }}
-            onClick={() => {
-              setVisible(true)
-              setVideoPath(serverUrl + item.videoPath)
-            }}
-          >
-          <div className='A4sceneCardFt'>
-              <p>{item.name}</p>
-            </div>
+        {VIDEO_LIST.map((item, index) => (
+          <li className={classNames(curIndex === index ? 'A4sceneListAc' : '')} key={index} onClick={() => setCurIndex(index)}>
+            <p>{item.name}</p>
           </li>
         ))}
       </ul>
@@ -42,7 +47,14 @@ function A4scene() {
         destroyOnClose
         onMaskClick={() => setVisible(false)}
       >
-        <video src={videoPath} controls autoPlay />
+        <video 
+          src={serverUrl + detail.videoPath} 
+          controls 
+          autoPlay 
+          playsInline
+        />
+
+        <img src={closeIcon} alt='close' onClick={() => setVisible(false)} />
       </Mask>
     </div>
   )

+ 28 - 0
code/src/pages/A5ip/detail.tsx

@@ -0,0 +1,28 @@
+import Z1titie from '@/components/Z1titie'
+import React from 'react'
+import styles from './index.module.scss'
+import history from '@/utils/history'
+import cardImg from './images/card.png'
+import closeIcon from './images/guanbi.png'
+
+function A5ipDetail() {
+  return (
+    <div
+      style={{ backgroundImage: `url(${serverUrl}ip/bac.jpg)` }}
+      className={styles.A5ipDetail}
+    >
+      <Z1titie
+        title='文创产品'
+        toHome={() => history.push('/?mask=1')}
+      />
+
+      <img className='A5ipDetailCard' src={cardImg} alt='card' />
+
+      <img className='A5ipDetailClose' src={closeIcon} alt='close' onClick={() => history.replace('/ip')} />
+    </div>
+  )
+}
+
+const MemoA5ipDetail = React.memo(A5ipDetail)
+
+export default MemoA5ipDetail

BIN
code/src/pages/A5ip/images/card.png


BIN
code/src/pages/A5ip/images/guanbi.png


BIN
code/src/pages/A5ip/images/qrcode.png


BIN
code/src/pages/A5ip/images/title.png


+ 85 - 0
code/src/pages/A5ip/index.module.scss

@@ -0,0 +1,85 @@
+.A5ip {
+  display: flex;
+  flex-direction: column;
+  background-size: cover;
+  background-position: center center;
+
+  &::before {
+    content: '';
+    position: absolute;
+    top: 30px;
+    left: 50%;
+    width: 264px;
+    height: 94px;
+    transform: translateX(-50%);
+    background: url('./images/title.png') no-repeat center / contain;
+  }
+  :global {
+    .Z1_1,
+    .Z1txt,
+    .Z1_1 {
+      display: none;
+    }
+
+    .A5ipContent {
+      flex: 1;
+      margin-top: 105px;
+      padding-bottom: 50px;
+      height: 0;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      overflow-y: auto;
+    }
+    .A5ipImg {
+      padding: 0 22px;
+    }
+    .A5ipTxt {
+      margin: 5px 0 8px;
+      padding: 0 24px;
+      font-size: 12px;
+      color: #FCE9AC;
+      line-height: 22px;
+      text-indent: 2em;
+      text-align: justify;
+    }
+    .A5ipBtn {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+
+      img {
+        width: 86px;
+        height: 87px;
+      }
+      p {
+        font-size: 12px;
+        color: #FDD000;
+        line-height: 24px;
+      }
+    }
+  }
+}
+
+.A5ipDetail {
+  overflow-y: auto;
+  
+  :global {
+    .Z1_1,
+    .Z1txt,
+    .Z1_1 {
+      display: none;
+    }
+    .A5ipDetailCard {
+      margin-top: 60px;
+      padding: 0 24px;
+    }
+    .A5ipDetailClose {
+      display: block;
+      margin: 30px auto;
+      width: 40px;
+      height: 40px;
+      cursor: pointer;
+    }
+  }
+}

+ 33 - 0
code/src/pages/A5ip/index.tsx

@@ -0,0 +1,33 @@
+import Z1titie from '@/components/Z1titie'
+import React from 'react'
+import styles from './index.module.scss'
+import history from '@/utils/history'
+import qrcode from './images/qrcode.png'
+
+function A5ip() {
+  return (
+    <div
+      style={{ backgroundImage: `url(${serverUrl}ip/bac.jpg)` }}
+      className={styles.A5ip}
+    >
+      <Z1titie
+        title='文创产品'
+        toHome={() => history.push('/?mask=1')}
+      />
+
+      <div className='A5ipContent'>
+        <img className='A5ipImg' src={`${serverUrl}ip/img.png`} alt='ip' />
+        <p className='A5ipTxt'>楚国第一玉剑毛绒挂饰,是楚国第一玉剑的萌趣化转译:Q版造型还原古玉剑神韵,绿线刺绣复刻楚式纹饰,可爱里藏满历史细节。便携挂绳适配包挂/车挂/钥匙扣,让千年玉剑变随身小伴。它承楚国第一玉剑文化,有"辟邪、纳福、助胜、过关"的吉祥寓意!</p>
+        
+        <div className='A5ipBtn' onClick={() => history.replace('/ip/detail')}>
+          <img src={qrcode} alt='qrcode' />
+          <p>1.点击保存图片到相册<br />2.打开抖音扫一扫</p>
+        </div>
+      </div>
+    </div>
+  )
+}
+
+const MemoA5ip = React.memo(A5ip)
+
+export default MemoA5ip

+ 1 - 1
code/src/types/declaration.d.ts

@@ -12,4 +12,4 @@ declare const serverUrl: string
 declare const myInfoTemp1
 declare const myInfoTemp2
 declare const MODEL_LIST: { name: string; page: string }[]
-declare const VIDEO_LIST: { name: string; videoPath: string; coverPath: string }[]
+declare const VIDEO_LIST: { name: string; videoPath: string; coverPath: string, desc: string }[]

BIN
静态资源/staticData/ip/bac.jpg


BIN
静态资源/staticData/ip/img.png