Quellcode durchsuchen

重写一波热点

shaogen1995 vor 8 Monaten
Ursprung
Commit
22322b8f48

+ 1 - 0
Code/public/index.html

@@ -8,6 +8,7 @@
     <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
     <link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
     <script src="./myData/myData.js"></script>
+    <script src="./myData/hot.js"></script>
 
     <style>
       @font-face {

Datei-Diff unterdrückt, da er zu groß ist
+ 200 - 0
Code/public/myData/hot.js


+ 301 - 0
Code/src/components/Zhot/index.module.scss

@@ -0,0 +1,301 @@
+.Zhot {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.6);
+  backdrop-filter: blur(2px);
+  z-index: 9999;
+  display: flex;
+  :global {
+    .ZHll {
+      width: 60%;
+      height: 100%;
+      padding: 3% 3% 1% 3%;
+      // 标题
+      .h2Titele {
+        padding: 0 50px;
+        position: relative;
+        display: inline-block;
+        color: #eacf60;
+        font-size: 26px;
+        & > img {
+          position: absolute;
+          top: 60%;
+          left: 0;
+          transform: translateY(-50%);
+          width: 40px;
+          height: auto;
+        }
+        .h2TimgR {
+          left: auto;
+          right: 0;
+        }
+      }
+
+      .ZH1main {
+        width: 100%;
+        height: calc(100% - 50px);
+        display: flex;
+        align-items: center;
+        position: relative;
+        padding: 12px 0 60px;
+        .ZH1main1 {
+          max-height: 100%;
+          overflow-y: auto;
+          &::-webkit-scrollbar {
+            display: none;
+          }
+          // 一级介绍
+          .ZH1txt {
+            font-size: 14px;
+            line-height: 24px;
+            color: #fffddc;
+            p {
+              font-family: 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI',
+                'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei',
+                sans-serif !important;
+              margin-bottom: 10px;
+            }
+            h3 {
+              color: #eacf60;
+              font-family: 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI',
+                'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei',
+                sans-serif !important;
+              margin-bottom: 8px;
+            }
+          }
+
+          // 二级
+          .ZH1_2 {
+            margin-top: 10px;
+            display: flex;
+            .ZH1_2ll {
+              padding-top: 5px;
+              width: 100px;
+              margin-right: 10px;
+
+              .ZH1_2llRow {
+                margin-bottom: 20px;
+                cursor: pointer;
+                color: #fffddc;
+                font-size: 14px;
+                position: relative;
+                padding-left: 24px;
+                transition: all 0.3s;
+                & > img {
+                  position: absolute;
+                  top: 0;
+                  left: 0;
+                  height: 20px;
+                  &:nth-of-type(2) {
+                    opacity: 0;
+                  }
+                }
+                // &:hover {
+                //   color: #eacf60;
+                //   & > img {
+                //     opacity: 0;
+                //     &:nth-of-type(2) {
+                //       opacity: 1;
+                //     }
+                //   }
+                // }
+              }
+              .ZH1_2llRowAc {
+                color: #eacf60;
+                & > img {
+                  opacity: 0;
+                  &:nth-of-type(2) {
+                    opacity: 1;
+                  }
+                }
+              }
+            }
+            .ZH1_2rr {
+              width: calc(100% - 110px);
+              font-size: 14px;
+              line-height: 24px;
+              color: #fffddc;
+              p {
+                font-family: 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI',
+                  'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei',
+                  sans-serif !important;
+                margin-bottom: 10px;
+              }
+            }
+          }
+
+          // 三级图片
+          .adm-image {
+            width: 90%;
+            margin: 0 auto;
+            height: auto;
+            min-height: 60px;
+            margin-bottom: 10px;
+            .adm-image-tip {
+              min-height: 60px;
+            }
+            img {
+              width: 100%;
+              height: 100%;
+              object-fit: contain !important;
+              max-height: 160px;
+            }
+          }
+        }
+        .ZH1main2 {
+          position: absolute;
+          bottom: 0;
+          left: 0;
+          width: 100%;
+          height: 46px;
+          display: flex;
+          align-items: center;
+          .back1 {
+            position: relative;
+            #BtnRight {
+              top: 0;
+              left: 0;
+              bottom: 0;
+              right: 0;
+              position: relative;
+              width: 46px;
+              height: 46px;
+            }
+          }
+          // 相关文物
+          .ZH1main2rr {
+            margin-left: 10px;
+            height: 36px;
+            width: calc(100% - 60px);
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            .ZH1main2rr1 {
+              color: #eacf60;
+              font-weight: 700;
+              width: 82px;
+            }
+            .ZH1main2rr2 {
+              width: calc(100% - 82px);
+              height: 100%;
+              overflow: auto;
+              white-space: nowrap;
+              &::-webkit-scrollbar {
+                display: none;
+              }
+              .ZH1main2rr2Row {
+                margin: 0 8px;
+                cursor: pointer;
+                width: auto;
+                height: 36px;
+                line-height: 34px;
+                padding: 0 10px;
+                color: #fffddc;
+                display: inline-block;
+                border: 1px solid #fffddc;
+                border-radius: 20px;
+                transition: all 0.3s;
+                &:hover {
+                  background-color: #eacf60;
+                  border-color: transparent;
+                  color: #a55b41;
+                }
+              }
+              .ZH1main2rr2RowAc {
+                background-color: #eacf60;
+                border-color: transparent;
+                color: #a55b41;
+              }
+            }
+          }
+        }
+      }
+    }
+    .ZHrr {
+      width: 40%;
+    }
+
+    // -----------------三级信息
+    .ZH1main1Son {
+      width: 100%;
+      max-height: 100%;
+      overflow: auto;
+      &::-webkit-scrollbar {
+        display: none;
+      }
+
+      // 模型 视频
+      .H2model {
+        width: 100%;
+        height: 200px;
+        .H2modelSon {
+          iframe {
+            width: 100%;
+            height: 100%;
+          }
+        }
+
+        video {
+          // object-fit: fill;
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+
+    // 屏幕>=1200
+    @media screen and (min-width: 1200px) {
+      .ZHll {
+        .h2Titele {
+          font-size: 30px;
+        }
+        .ZH1main {
+          .ZH1main1 {
+            // 一级介绍
+            .ZH1txt {
+              h3 {
+                font-size: 12px;
+              }
+              p {
+                font-size: 10px;
+                line-height: 20px;
+              }
+            }
+          }
+          // 二级
+          .ZH1main1 {
+            .ZH1_2 {
+              .ZH1_2ll {
+                .ZH1_2llRow {
+                  font-size: 10px;
+                }
+              }
+              .ZH1_2rr {
+                p {
+                  font-size: 10px;
+                  line-height: 20px;
+                }
+              }
+            }
+          }
+        }
+      }
+      .ZH1main2rr1 {
+        font-size: 12px !important;
+        width: 66px !important;
+      }
+      .ZHll .ZH1main .ZH1main2 .ZH1main2rr .ZH1main2rr2 {
+        width: calc(100% - 60px);
+        height: 30px;
+        .ZH1main2rr2Row {
+          height: 30px;
+          line-height: 28px;
+          font-size: 12px;
+        }
+      }
+    }
+  }
+}

+ 235 - 0
Code/src/components/Zhot/index.tsx

@@ -0,0 +1,235 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { baseURL, hotInfo, isPc } from '@/utils/http'
+import { HotInvolveType, HotRowType, HotSonType } from './type'
+import BtnRight from '../BtnRight'
+import classNames from 'classnames'
+import LazyImg from '../LazyImg'
+import { useSelector } from 'react-redux'
+import { RootState } from '@/store'
+
+type Props = {
+  name: string
+  closeFu: () => void
+}
+
+function Zhot({ name, closeFu }: Props) {
+  // 二级的选中
+  const [acObj2, setAcObj2] = useState({} as HotSonType)
+
+  const info = useMemo(() => {
+    let info = {} as HotRowType
+    for (const k in hotInfo) {
+      let obj = hotInfo[k as 'cheQi'].find(v => v.name === name)
+      if (obj) {
+        info = obj
+        setAcObj2(obj.data.son[0])
+      }
+    }
+    return info
+  }, [name])
+
+  // 相关文物的滚动
+  const [isFlag, setIsFlag] = useState(false)
+
+  const sroolRef = useRef<HTMLDivElement>(null)
+  const mousemoveFu = useCallback(
+    (ev: any, flag?: boolean) => {
+      if (sroolRef.current) {
+        if (flag && !isFlag) {
+          const nowMove = sroolRef.current.scrollLeft
+          // 滚轮
+          let num = 50
+          if (ev.deltaY < 0) num = -num
+          sroolRef.current.scrollLeft = nowMove + num
+        } else if (isFlag) {
+          const nowMove = sroolRef.current.scrollLeft
+
+          // 鼠标按住移动
+          sroolRef.current.scrollLeft = nowMove - ev.movementX
+        }
+      }
+    },
+    [isFlag]
+  )
+
+  // 第三级选中
+  const [acObj3, setAcObj3] = useState({} as HotInvolveType)
+
+  const rootStyle = useSelector((state: RootState) => state.A0Layout.style)
+
+  const [modelSize, setModelSize] = useState({ ww: 0, hh: 0, wwB: 0, hhB: 0 })
+
+  useEffect(() => {
+    if (acObj3.name) {
+      setTimeout(() => {
+        // 移动到顶部
+        const sroolDom: HTMLDivElement = document.querySelector('.ZH1main1Son')!
+        if (sroolDom) sroolDom.scrollTop = 0
+
+        // 模型重定义尺寸
+        const dom = document.querySelector('.H2model')
+        if (dom) {
+          setModelSize({
+            ww: Number((dom.clientWidth * rootStyle.sizeW).toFixed(2)),
+            hh: Number((dom.clientHeight * rootStyle.sizeH).toFixed(2)),
+            wwB: dom.clientWidth,
+            hhB: dom.clientHeight
+          })
+        }
+      }, 100)
+    }
+  }, [acObj3.name, rootStyle.sizeH, rootStyle.sizeW])
+
+  return (
+    <div className={styles.Zhot} id='HotOpCss'>
+      {/* 左边主体 */}
+      <div className='ZHll'>
+        {/* 标题 */}
+        <div className='h2Titele'>
+          <img src={`${baseURL}Zhot/img-yun1.png`} alt='' />
+          <img className='h2TimgR' src={`${baseURL}Zhot/img-yun2.png`} alt='' />
+          {acObj3.name ? acObj3.name : name}
+        </div>
+
+        {info.data ? (
+          <div className='ZH1main'>
+            <div className='ZH1main1' hidden={!!acObj3.name}>
+              {/* 一级图片 */}
+              {info.data.imgArr1 && info.data.imgArr1.length
+                ? info.data.imgArr1.map(url => <LazyImg src={baseURL + url} key={url} />)
+                : null}
+              {/* 一级介绍 */}
+              <div className='ZH1txt' dangerouslySetInnerHTML={{ __html: info.data.txt }}></div>
+
+              {/* ----------二级----------- */}
+              {info.data.son && info.data.son.length ? (
+                <div className='ZH1_2'>
+                  <div className='ZH1_2ll'>
+                    {info.data.son.map(row2 => (
+                      <div
+                        key={row2.name}
+                        className={classNames(
+                          'ZH1_2llRow sizeNo',
+                          acObj2.name === row2.name ? 'ZH1_2llRowAc' : ''
+                        )}
+                        onClick={() => setAcObj2(row2)}
+                      >
+                        <img src={baseURL + 'Zhot/icon2.png'} alt='' />
+                        <img src={baseURL + 'Zhot/icon2Ac.png'} alt='' />
+                        {row2.name}
+                      </div>
+                    ))}
+                  </div>
+                  <div className='ZH1_2rr'>
+                    {/* 二级图片 */}
+                    {acObj2.imgArr2 && acObj2.imgArr2.length
+                      ? acObj2.imgArr2.map(url => <LazyImg src={baseURL + url} key={url} />)
+                      : null}
+                    <div dangerouslySetInnerHTML={{ __html: acObj2.txt }}></div>
+                  </div>
+                </div>
+              ) : null}
+            </div>
+
+            {/* -----------三级信息------------- */}
+            {acObj3.name ? (
+              <div id='HotOpCss' className='ZH1main1 ZH1main1Son'>
+                {acObj3.type === '图片'
+                  ? acObj3.urlArr.map(url => <LazyImg src={baseURL + url} key={url} />)
+                  : null}
+
+                {['模型', '视频'].includes(acObj3.type) ? (
+                  <div className='H2model' style={{ height: acObj3.text ? '200px' : '280px' }}>
+                    {acObj3.type === '模型' ? (
+                      <div
+                        className='H2modelSon'
+                        style={
+                          isPc && Object.keys(rootStyle).length && modelSize.ww
+                            ? {
+                                position: 'relative',
+                                width: modelSize.ww + 'px',
+                                height: modelSize.hh + 'px',
+                                transform: `translate(${-(modelSize.ww - modelSize.wwB) / 2}px, ${
+                                  -(modelSize.hh - modelSize.hhB) / 2
+                                }px) scale(${1 / rootStyle.sizeW}, ${1 / rootStyle.sizeH})`
+                              }
+                            : { width: '100%', height: '100%' }
+                        }
+                      >
+                        <iframe
+                          title={name}
+                          src={`${baseURL}modelLoding/model.html?u=${acObj3.urlArr[0]}`}
+                          frameBorder='0'
+                        ></iframe>
+                      </div>
+                    ) : (
+                      <video
+                        src={baseURL + acObj3.urlArr[0]}
+                        controls
+                        playsInline
+                        muted
+                        webkit-playsinline='true'
+                        x5-video-player-type='h5'
+                      ></video>
+                    )}
+                  </div>
+                ) : null}
+
+                <div className='ZH1txt' dangerouslySetInnerHTML={{ __html: acObj3.text }}></div>
+              </div>
+            ) : null}
+
+            <div className='ZH1main2'>
+              {/* 返回按钮 */}
+              <div className='back1'>
+                <BtnRight
+                  title='返回'
+                  clickSon={() => {
+                    acObj3.name ? setAcObj3({} as HotInvolveType) : closeFu()
+                  }}
+                  imgName='back'
+                />
+              </div>
+
+              {/* 相关文物 */}
+              {info.data.involve && info.data.involve.length ? (
+                <div className='ZH1main2rr'>
+                  <div className='ZH1main2rr1 sizeNo'>相关文物:</div>
+                  <div
+                    className='ZH1main2rr2'
+                    onMouseDown={() => setIsFlag(true)}
+                    onMouseUp={() => setIsFlag(false)}
+                    onMouseLeave={() => setIsFlag(false)}
+                    onMouseMove={e => mousemoveFu(e)}
+                    onWheel={e => mousemoveFu(e, true)}
+                    style={{ cursor: isFlag ? 'move' : 'default' }}
+                    ref={sroolRef}
+                  >
+                    {info.data.involve.map(row3 => (
+                      <div
+                        onClick={() => setAcObj3(row3)}
+                        className={classNames(
+                          'ZH1main2rr2Row sizeNo',
+                          acObj3.name === row3.name ? 'ZH1main2rr2RowAc' : ''
+                        )}
+                        key={row3.name}
+                      >
+                        {row3.name}
+                      </div>
+                    ))}
+                  </div>
+                </div>
+              ) : null}
+            </div>
+          </div>
+        ) : null}
+      </div>
+      <div className='ZHrr' onClick={closeFu}></div>
+    </div>
+  )
+}
+
+const MemoZhot = React.memo(Zhot)
+
+export default MemoZhot

+ 44 - 0
Code/src/components/Zhot/type.d.ts

@@ -0,0 +1,44 @@
+export type HotRowType = {
+  name: string
+  tubiao: '普通' | '文物'
+  zIndex: number
+  hoverSrc: string
+  // 当前页面的定位(如果是全景图和全景视频 ---没有)
+  locPage: {
+    top: string
+    left: string
+  }
+  // 全景视频和全景图的定位(不是全景图或者全景视频的---没有)
+  panoLoc: {
+    size: number
+    atv: number
+    ath: number
+  }
+  // 热点定位百分比(更多模块的定位--不需要在更多模块中展示的---没有)
+  locMore: {
+    top: string
+    left: string
+  }
+  data: {
+    txt: string
+    imgArr1?: string[]
+    son: HotSonType[]
+    involve: HotInvolveType[]
+  }
+}
+export type HotInvolveType = {
+  name: string
+  type: '图片' | '模型' | '视频'
+  urlArr: string[]
+  text: string
+}
+
+export type HotSonType = {
+  name: string
+  txt: string
+  imgArr2?: string[]
+}
+
+export type HotInfoType = {
+  cheQi: HotRowType[]
+}

+ 3 - 1
Code/src/pages/A1_1base/index.tsx

@@ -170,7 +170,9 @@ function A11base() {
               />
             </div>
 
-            <BtnRight title='返回' clickSon={() => setBiShow(false)} imgName='back' />
+            {txtShow ? null : (
+              <BtnRight title='返回' clickSon={() => setBiShow(false)} imgName='back' />
+            )}
 
             {/* 填完信息出来的文字盒子 */}
             <div

+ 1 - 0
Code/src/pages/B1more/S2mien/index.tsx

@@ -70,6 +70,7 @@ function S2mien({ hidden }: Props) {
             <div
               onClick={() => clickSon(index)}
               className={classNames('S2leftRow', hotInd === index ? 'S2leftRowAc' : '')}
+              // onMouseUp={() => setHotInd(index)}
               key={index}
             >
               {item.name}

+ 15 - 3
Code/src/pages/Text/index.module.scss

@@ -1,8 +1,20 @@
 .Text {
+  overflow: auto;
   :global {
-    iframe {
-      width: 100%;
-      height: 100%;
+    .box1 {
+      padding-bottom: 10px;
+      border-bottom: 4px solid red;
+      .box2 {
+        display: flex;
+        flex-wrap: wrap;
+        & > img {
+          cursor: pointer;
+          height: 30px;
+          width: auto;
+          display: block;
+          margin: 0 20px 20px 0;
+        }
+      }
     }
   }
 }

+ 36 - 5
Code/src/pages/Text/index.tsx

@@ -1,15 +1,46 @@
 /* eslint-disable jsx-a11y/iframe-has-title */
-import React, { useEffect } from 'react'
+import React, { useEffect, useMemo, useState } from 'react'
 import styles from './index.module.scss'
+import { baseURL, hotInfo } from '@/utils/http'
+import { HotRowType } from '@/components/Zhot/type'
+import Zhot from '@/components/Zhot'
+
 function Text() {
   useEffect(() => {}, [])
 
+  const allArr = useMemo(() => {
+    let arr: { oneName: string; arr: HotRowType[] }[] = []
+    for (const k in hotInfo) {
+      arr.push({
+        oneName: k,
+        arr: hotInfo[k as 'cheQi']
+      })
+    }
+    return arr
+  }, [])
+
+  const [acName, setAcName] = useState('')
+
   return (
     <div className={styles.Text}>
-      <iframe
-        src='https://testjp-xspace.4dkankan.com/?m=SG-t-jp-D8De5n2Nn8F&serial=17249031446913'
-        frameBorder='0'
-      ></iframe>
+      {allArr.map(item => (
+        <div key={item.oneName} className='box1'>
+          <h1>{item.oneName}</h1>
+
+          <div className='box2'>
+            {item.arr.map(son => (
+              <img
+                src={baseURL + son.hoverSrc}
+                key={son.name}
+                alt=''
+                onClick={() => setAcName(son.name)}
+              />
+            ))}
+          </div>
+        </div>
+      ))}
+
+      {acName ? <Zhot name={acName} closeFu={() => setAcName('')} /> : null}
     </div>
   )
 }

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

@@ -13,6 +13,7 @@ declare const baseUrlAtl: string
 declare const isPcTemp: boolean
 declare const myDataTemp: MyDataType
 declare const otherUrlTemp: string
+declare const myHotInfo: any
 
 type MyDataType = {
   isLdong: boolean

+ 5 - 0
Code/src/utils/http.ts

@@ -1,3 +1,5 @@
+import { HotInfoType } from '@/components/Zhot/type'
+
 export const isLoc = process.env.NODE_ENV === 'development'
 
 export const baseURL = isLoc ? baseUrlLoc : baseUrlAtl
@@ -10,3 +12,6 @@ export const isPc = isPcTemp
 
 // 全景视频/全景图/unity场景资源地址
 export const otherUrl = otherUrlTemp
+
+// 重新梳理的热点信息
+export const hotInfo: HotInfoType = myHotInfo

BIN
资源/staticData/Zhot/cheQi/icon/taoYuanLuo.png


BIN
资源/staticData/Zhot/cheQi/icon/yongHuYinBin.png


BIN
资源/staticData/Zhot/cheQi/involve/001.gif


BIN
资源/staticData/Zhot/cheQi/involve/002.jpg


BIN
资源/staticData/Zhot/cheQi/involve/1.4dage


BIN
资源/staticData/Zhot/cheQi/involve/1.jpg


BIN
资源/staticData/Zhot/cheQi/involve/1.mp4


BIN
资源/staticData/Zhot/cheQi/involve/2.jpg


BIN
资源/staticData/Zhot/icon2.png


BIN
资源/staticData/Zhot/icon2Ac.png


BIN
资源/staticData/Zhot/img-yun1.png


BIN
资源/staticData/Zhot/img-yun2.png


BIN
资源/staticData/xianJu/1.mp4