index.tsx 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import React, { useCallback, useEffect, useRef, useState } from 'react'
  2. import styles from './index.module.scss'
  3. import BaseImg from '@/components/BaseImg'
  4. import { baseURL, hotInfo, myData } from '@/utils/http'
  5. import useLoding from '@/components/ownUse/useLoding'
  6. import CatVideo from '@/components/CatVideo'
  7. import A6PanoVideo from './A6PanoVideo'
  8. import classNames from 'classnames'
  9. import { domDelOwnFu } from '@/utils/utilsSome'
  10. import FloorBtn from '@/components/FloorBtn'
  11. import NextPage from '@/components/NextPage'
  12. import EndVideo from '@/components/EndVideo'
  13. import history from '@/utils/history'
  14. import HotIcon from '@/components/HotIcon'
  15. import Zhot from '@/components/Zhot'
  16. function A6xian() {
  17. // 过度动画
  18. const [cutVideoShow, setCutVideoShow] = useState(false)
  19. // 点击 跳下一个章节
  20. const [lastVideo, setLastVideo] = useState(false)
  21. // 点击继续
  22. const btnStart = useCallback(() => {
  23. setCutVideoShow(true)
  24. }, [])
  25. // 过度动画播放完毕或者点击跳过
  26. const cutEndFu = useCallback(() => {
  27. setCutVideoShow(false)
  28. }, [])
  29. // 先加载背景图 序列帧等 在加载视频
  30. const { imgNow, imgNumFu } = useLoding(3)
  31. // 点击升仙
  32. const [xianShow, setXianShow] = useState(window.location.href.includes('t=xian') ? true : false)
  33. // 滚动
  34. const [isFlag, setIsFlag] = useState(false)
  35. const xianRef = useRef<HTMLDivElement>(null)
  36. // 监听3S没有操作
  37. const [action, setAction] = useState(false)
  38. const actionRef = useRef(-1)
  39. const actionFu = useCallback(
  40. (val?: boolean) => {
  41. if (xianShow || val) {
  42. setAction(false)
  43. clearTimeout(actionRef.current)
  44. actionRef.current = window.setTimeout(() => {
  45. setAction(true)
  46. }, 3000)
  47. }
  48. },
  49. [xianShow]
  50. )
  51. const actionMoveRef = useRef(-1)
  52. useEffect(() => {
  53. if (xianShow) {
  54. clearInterval(actionMoveRef.current)
  55. if (action) {
  56. actionMoveRef.current = window.setInterval(() => {
  57. if (xianRef.current) {
  58. const nowMove = xianRef.current.scrollLeft
  59. xianRef.current.scrollLeft = nowMove + 2
  60. if (xianRef.current.scrollLeft >= 2988) xianRef.current.scrollLeft = 0
  61. }
  62. }, 50)
  63. }
  64. }
  65. }, [action, xianShow])
  66. const mousemoveFu = useCallback(
  67. (ev: any, flag?: boolean) => {
  68. if (xianRef.current) {
  69. if (flag && !isFlag) {
  70. actionFu()
  71. const nowMove = xianRef.current.scrollLeft
  72. // 滚轮
  73. let num = 50
  74. if (ev.deltaY < 0) num = -num
  75. xianRef.current.scrollLeft = nowMove + num
  76. } else if (isFlag) {
  77. actionFu()
  78. const nowMove = xianRef.current.scrollLeft
  79. // 鼠标按住移动
  80. xianRef.current.scrollLeft = nowMove - ev.movementX
  81. }
  82. }
  83. },
  84. [actionFu, isFlag]
  85. )
  86. const videoRef = useRef<HTMLVideoElement>(null)
  87. useEffect(() => {
  88. if (window.location.href.includes('t=xian')) {
  89. setTimeout(() => {
  90. if (videoRef.current) videoRef.current.play()
  91. }, 100)
  92. }
  93. }, [])
  94. // 二级的静态图
  95. const [erImg, setErImg] = useState(false)
  96. // 打开热点
  97. const [acName, setAcName] = useState('')
  98. useEffect(() => {
  99. if (acName) {
  100. clearTimeout(actionRef.current)
  101. clearInterval(actionMoveRef.current)
  102. } else actionFu()
  103. }, [acName, actionFu])
  104. return (
  105. <div className={styles.A6xian}>
  106. {/* 初始静态图 */}
  107. <BaseImg
  108. hidden={window.location.href.includes('t=xian')}
  109. isShow={cutVideoShow}
  110. iconSrc={`${baseURL}xianJu/mulu.png`}
  111. parentFu={() => setErImg(true)}
  112. bgImg={`${baseURL}${myData.xianJu.bgImg}`}
  113. imgNow={imgNow}
  114. imgNumFu={imgNumFu}
  115. num={70}
  116. bird='xianJu'
  117. />
  118. {/* 二级静态图 */}
  119. <div
  120. className='A6erImg'
  121. style={{ opacity: erImg ? '1' : '0', pointerEvents: erImg ? 'auto' : 'none' }}
  122. >
  123. <img src={baseURL + 'xianJu/bg.jpg'} alt='' />
  124. <NextPage
  125. clickSon={() => {
  126. domDelOwnFu('.A6erImg')
  127. btnStart()
  128. }}
  129. txt='开始冥想'
  130. />
  131. {/* 右下角按钮 */}
  132. <FloorBtn unityEnd={() => history.push('unend/end')} />
  133. </div>
  134. {/* 过度动画页面 */}
  135. {imgNow ? (
  136. <CatVideo
  137. isShow={cutVideoShow}
  138. src={baseURL + myData.xianJu.videos[0]}
  139. parentFu={() => cutEndFu()}
  140. />
  141. ) : null}
  142. {/* 全景视频 */}
  143. {imgNow && !window.location.href.includes('t=xian') ? (
  144. <div className={classNames('pvBox', cutVideoShow ? '' : 'pvBoxShow')}>
  145. <A6PanoVideo />
  146. <div
  147. className='pvBtn'
  148. onClick={() => {
  149. domDelOwnFu('.pvBox')
  150. setXianShow(true)
  151. setTimeout(() => {
  152. if (videoRef.current) videoRef.current.play()
  153. }, 100)
  154. // 开启滚动动画
  155. actionFu(true)
  156. }}
  157. >
  158. 升仙之途
  159. </div>
  160. <FloorBtn unityEnd={() => history.push('unend/end')} />
  161. </div>
  162. ) : null}
  163. {/* 点击升仙之途 出来的长 滚动 页面 */}
  164. {imgNow || window.location.href.includes('t=xian') ? (
  165. <div
  166. onTouchStart={() => actionFu()}
  167. onClick={() => actionFu()}
  168. className='A6XimgBox'
  169. style={{ opacity: xianShow ? '1' : '0', pointerEvents: xianShow ? 'auto' : 'none' }}
  170. >
  171. <div className='A6XimgBoxSon'>
  172. <div
  173. className='A6videoBox'
  174. style={{ cursor: isFlag ? 'move' : 'default' }}
  175. ref={xianRef}
  176. onMouseDown={() => setIsFlag(true)}
  177. onMouseUp={() => setIsFlag(false)}
  178. onMouseLeave={() => setIsFlag(false)}
  179. onMouseMove={e => mousemoveFu(e)}
  180. onWheel={e => mousemoveFu(e, true)}
  181. >
  182. <video
  183. ref={videoRef}
  184. playsInline
  185. muted
  186. webkit-playsinline='true'
  187. x5-video-player-type='h5'
  188. loop={true}
  189. >
  190. <source type='video/mp4' src={`${baseURL}xianJu/chang.mp4`} />
  191. Your browser does not support the video tag.
  192. </video>
  193. {/* 热点 */}
  194. {hotInfo.xianJu2.map((item, index) => (
  195. <HotIcon
  196. isModel={item.tubiao === '文物' ? true : false}
  197. style={{
  198. top: item.locPage.top,
  199. left: item.locPage.left
  200. }}
  201. key={index}
  202. index={index}
  203. clickSon={() => setAcName(item.name)}
  204. hoverSrc={item.hoverSrc}
  205. isXiao={0.67}
  206. />
  207. ))}
  208. </div>
  209. </div>
  210. {/* 跳到下一章 */}
  211. <NextPage clickSon={() => setLastVideo(true)} txt='结束冥想' />
  212. {/* 右下角按钮 */}
  213. <FloorBtn unityEnd={() => history.push('unend/end')} />
  214. {/* 底部按钮 */}
  215. <div className='A6XimgBoxBtn'>
  216. <div onClick={() => history.push('/xian?t=xian')}>卜千秋墓中的升仙图</div>
  217. <div onClick={() => history.push('/yun?t=xian')}>四神云气图</div>
  218. </div>
  219. </div>
  220. ) : null}
  221. {/* 最后的视频 */}
  222. <EndVideo
  223. lastVideo={lastVideo}
  224. src={baseURL + 'xianJu/end.mp4'}
  225. path='/end'
  226. delDom='.A22Pano'
  227. />
  228. {acName ? <Zhot name={acName} closeFu={() => setAcName('')} /> : null}
  229. </div>
  230. )
  231. }
  232. const MemoA6xian = React.memo(A6xian)
  233. export default MemoA6xian