HomeView.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. <script setup>
  2. import { ref, computed, nextTick, onMounted, watch } from "vue"
  3. import { useRouter, useRoute } from "vue-router"
  4. import { useStore } from "vuex"
  5. import Startup from "@/views/StartupView.vue"
  6. import useRollFu from "../rollFu.js"
  7. import HotspotDetail3 from "@/views/HotspotDetail3.vue"
  8. import HotspotDetail1 from "@/views/HotspotDetail1.vue"
  9. import PaintingDetail from '@/views/PaintingDetail.vue'
  10. import DetailImg from '@/assets/images/icon_home_detail-min.png'
  11. import DetailImgAc from '@/assets/images/icon_home_detail-min-ac.png'
  12. import AuthorImg from '@/assets/images/icon_home_author-min.png'
  13. import AuthorImgAc from '@/assets/images/icon_home_author-min-ac.png'
  14. import useSizeAdapt from "@/useFunctions/useSizeAdapt"
  15. const store = useStore()
  16. const router = useRouter()
  17. const route = useRoute()
  18. const { handleScrollThrottle } = useRollFu()
  19. const isShowOperationTip = ref(true)
  20. const isShowHotspotDetail1 = ref(false)
  21. const isShowHotspotDetail3 = ref(false)
  22. const curPageIndex = ref(0)
  23. const longDescText = computed(() => {
  24. return curPageIndex.value == 1
  25. ? configText.homepagePaintingDetailDescStem
  26. : curPageIndex.value == 2
  27. ? configText.homepagePaintingDetailDescLeaf
  28. : curPageIndex.value == 3
  29. ? configText.homepagePaintingDetailDescStone
  30. : curPageIndex.value == 4
  31. ? configText.homepagePaintingSummary
  32. : ""
  33. })
  34. const isShowVideoFadeToNextPage = ref(false)
  35. const isShowSkip = ref(false)
  36. const videoFadeToNextPageEl = ref(null)
  37. const paintingState = ref('1')
  38. const isShowPaintingDetial = ref(false)
  39. const longTitleText = computed(() => {
  40. return curPageIndex.value == 1
  41. ? "三竿修竹"
  42. : curPageIndex.value == 2
  43. ? "竹叶"
  44. : curPageIndex.value == 3
  45. ? "卧石、枯树和灌木"
  46. : ""
  47. })
  48. const isShowHotspot = ref(true)
  49. watch(curPageIndex, (val) => {
  50. if (val == 0 || val == 4) {
  51. setTimeout(() => {
  52. isShowHotspot.value = true
  53. }, 1500)
  54. }
  55. isShowHotspot.value = false
  56. })
  57. // const isShowHotspot = computed(setTimeout(()=> {
  58. // return curPageIndex.value == 0 || curPageIndex.value == 4
  59. // }, 1500))
  60. // 滑动逻辑
  61. const scrollFu = (event, val) => {
  62. console.log('在滚动', val)
  63. if (val == -1) {
  64. // 上滚
  65. // console.log("上滚")
  66. curPageIndex.value =
  67. curPageIndex.value > 0 ? curPageIndex.value - 1 : curPageIndex.value
  68. } else if (val == 1) {
  69. // 下滚
  70. isShowOperationTip.value = false
  71. if (curPageIndex.value < 4) {
  72. curPageIndex.value = curPageIndex.value + 1
  73. } else if (curPageIndex.value == 4) {
  74. // 播放视频
  75. isShowVideoFadeToNextPage.value = true
  76. nextTick(() => {
  77. videoFadeToNextPageEl.value.play()
  78. })
  79. setTimeout(() => {
  80. isShowSkip.value = true
  81. }, 2000)
  82. }
  83. }
  84. }
  85. const hoverIndex = ref(null)
  86. const {
  87. windowSizeInCssForRef,
  88. windowSizeWhenDesignForRef,
  89. } = useSizeAdapt()
  90. onMounted(() => {
  91. if (route.query.page) {
  92. curPageIndex.value = parseInt(route.query.page)
  93. }
  94. })
  95. </script>
  96. <template>
  97. <div class="home">
  98. <!-- 过渡到更多详情页视频 -->
  99. <video
  100. v-show="isShowVideoFadeToNextPage"
  101. ref="videoFadeToNextPageEl"
  102. muted
  103. class="fade-to-next-page"
  104. src="@/assets/videos/fade-from-home-to-more-content.mp4"
  105. @ended="
  106. router.push({
  107. name: 'MoreContent',
  108. })
  109. "
  110. />
  111. <Transition name="fade-in">
  112. <BtnSkip
  113. v-if="isShowSkip"
  114. @click="
  115. router.push({
  116. name: 'MoreContent',
  117. })
  118. "
  119. />
  120. </Transition>
  121. <!-- 滚动区域 -->
  122. <div
  123. ref="scroller"
  124. class="scroller"
  125. @wheel="($event) => handleScrollThrottle($event, ($event) => scrollFu($event,-1),($event) => scrollFu($event,1))"
  126. >
  127. <div class="scroller-content" />
  128. </div>
  129. <!-- 背景 -->
  130. <div class="bg-mask" />
  131. <!-- 开场动画 -->
  132. <Transition name="fade-out">
  133. <Startup
  134. v-if="!store.state.haveShownStartup"
  135. class="startup"
  136. />
  137. <!-- <Startup
  138. v-if="true"
  139. class="startup"
  140. /> -->
  141. </Transition>
  142. <!-- 首页标题 -->
  143. <div
  144. class="title-wrap"
  145. :style="{
  146. opacity: curPageIndex == 0 ? 1 : 0,
  147. }"
  148. >
  149. <img
  150. class="title"
  151. src="@/assets/images/home-title.png"
  152. alt=""
  153. draggable="false"
  154. >
  155. <div class="sub-text">
  156. <!-- 南京博物院<br> -->
  157. 绢本 墨笔<br>
  158. 元 李衎<br>
  159. </div>
  160. </div>
  161. <!-- 作品、作者简介 -->
  162. <div
  163. ref="longDesc"
  164. class="long-desc"
  165. :class="{ 'long-desc-ac': curPageIndex == 0 || curPageIndex == 4 }"
  166. :style="{ opacity: curPageIndex == 0 || curPageIndex == 4 ? 1 : 0 }"
  167. >
  168. <div
  169. class="page2-box"
  170. @mouseenter="hoverIndex = 1"
  171. @mouseleave="hoverIndex = null"
  172. @click="
  173. // () => {
  174. // router.push('/painting-detail?idx=home');
  175. // }
  176. isShowPaintingDetial =true,
  177. paintingState = '1'
  178. "
  179. >
  180. <img
  181. :src="hoverIndex == 1 ? DetailImgAc : DetailImg"
  182. alt=""
  183. >
  184. <div>作品简介</div>
  185. </div>
  186. <div
  187. class="page2-box"
  188. style="margin-top: 10px"
  189. @mouseenter="hoverIndex = 2"
  190. @mouseleave="hoverIndex = null"
  191. @click="
  192. // () => {
  193. // router.push('/painting-detail?idx=home&state=2');
  194. // }
  195. isShowPaintingDetial =true,
  196. paintingState = '2'
  197. "
  198. >
  199. <img
  200. :src="hoverIndex == 2 ? AuthorImgAc : AuthorImg"
  201. alt=""
  202. >
  203. <div>作者简介</div>
  204. </div>
  205. </div>
  206. <!-- 画作 -->
  207. <div
  208. class="painting-wrap"
  209. :class="{
  210. 'painting-wrap2': curPageIndex == 1 || curPageIndex == 3,
  211. 'painting-wrap3': curPageIndex == 2,
  212. }"
  213. @click="
  214. () => {
  215. isShowPaintingDetial = true
  216. }
  217. "
  218. >
  219. <img
  220. class="painting-border"
  221. src="@/assets/images/painting-border-new.png"
  222. alt=""
  223. draggable="false"
  224. >
  225. <img
  226. class="painting-stem"
  227. src="@/assets/images/home-painting1.jpg"
  228. alt=""
  229. draggable="false"
  230. >
  231. <img
  232. class="painting-stem"
  233. src="@/assets/images/home-painting2.jpg"
  234. alt=""
  235. draggable="false"
  236. >
  237. <img
  238. :style="{ opacity: curPageIndex == 1 ? 1 : 0, zIndex: 3 }"
  239. class="painting-stem"
  240. src="@/assets/images/home-painting-stem.jpg"
  241. alt=""
  242. >
  243. <img
  244. class="painting-stem"
  245. src="@/assets/images/img_zhuye-min2.png"
  246. alt=""
  247. :style="{
  248. opacity: curPageIndex == 2 ? 1 : 0,
  249. zIndex: 2,
  250. }"
  251. draggable="false"
  252. >
  253. <img
  254. class="painting-stem"
  255. src="@/assets/images/img_stone_all-min.png"
  256. :style="{
  257. opacity: curPageIndex == 3 ? 1 : 0,
  258. zIndex: 2,
  259. }"
  260. alt=""
  261. draggable="false"
  262. >
  263. </div>
  264. <!-- 热点层1 -->
  265. <div
  266. v-show="isShowHotspot"
  267. class="hotspot-wrap"
  268. >
  269. <HotspotForHomepage
  270. class="hotspot-1"
  271. @click="isShowHotspotDetail1 = true"
  272. />
  273. <HotspotForHomepage
  274. class="hotspot-3"
  275. @click="isShowHotspotDetail3 = true"
  276. />
  277. </div>
  278. <!-- 轴/卷/册热点详情 -->
  279. <Transition name="fade-in-out">
  280. <HotspotDetail3
  281. v-if="isShowHotspotDetail3"
  282. class="hotspot-detail"
  283. @close="isShowHotspotDetail3 = false"
  284. />
  285. </Transition>
  286. <!-- 材质热点详情 -->
  287. <Transition name="fade-in-out">
  288. <HotspotDetail1
  289. v-if="isShowHotspotDetail1"
  290. class="hotspot-detail"
  291. @close="isShowHotspotDetail1 = false"
  292. />
  293. </Transition>
  294. <!-- 滑动提示 -->
  295. <OperationTip
  296. v-show="curPageIndex == 0"
  297. class="operation-tip"
  298. text="向下滑动"
  299. :is-show="isShowOperationTip"
  300. />
  301. <!-- 画作详情 -->
  302. <PaintingDetail
  303. v-if="isShowPaintingDetial"
  304. class="painting-detail"
  305. :idx="'home'"
  306. :state="paintingState"
  307. @close="isShowPaintingDetial = false"
  308. />
  309. <!-- 文字介绍 -->
  310. <div
  311. class="text-box"
  312. :style="{
  313. opacity:
  314. curPageIndex == 1 ||
  315. curPageIndex == 2 ||
  316. curPageIndex == 3 ||
  317. curPageIndex == 4
  318. ? 1
  319. : 0,
  320. left: curPageIndex == 4 ? '4%':''
  321. }"
  322. >
  323. <div class="text-box-title">
  324. {{ longTitleText }}
  325. </div>
  326. <!-- <div v-if="curPageIndex == 2">
  327. 竹子的画法
  328. </div> -->
  329. <div
  330. class="text-box-desc"
  331. v-html="longDescText"
  332. />
  333. </div>
  334. </div>
  335. </template>
  336. <style lang="less" scoped>
  337. .home {
  338. width: 100%;
  339. height: 100%;
  340. > video.fade-to-next-page {
  341. position: absolute;
  342. left: 0;
  343. top: 0;
  344. width: 100%;
  345. height: 100%;
  346. object-fit: cover;
  347. z-index: 20;
  348. }
  349. > .scroller {
  350. width: 100vw;
  351. max-height: 100vh;
  352. overflow: auto;
  353. background: rgba(255, 255, 0, 0);
  354. position: absolute;
  355. top: 0;
  356. z-index: 10;
  357. opacity: 0.001;
  358. .scroller-content {
  359. width: 100%;
  360. height: 200vh;
  361. }
  362. }
  363. > .bg-mask {
  364. position: absolute;
  365. left: 0;
  366. top: 0;
  367. width: 100%;
  368. height: 100%;
  369. // background: rgba(60, 89, 71, 0.65);
  370. background: url(@/assets/images/bg-mask.png);
  371. background-size: 100% 100%;
  372. }
  373. > .startup {
  374. z-index: 20;
  375. }
  376. > .title-wrap {
  377. position: absolute;
  378. right: 25%;
  379. top: 50%;
  380. transform: translateY(-50%);
  381. width: 100px;
  382. height: 45%;
  383. z-index: 5;
  384. transition: opacity 1.5s ease;
  385. > img.title {
  386. position: absolute;
  387. left: 0;
  388. top: 0;
  389. width: 100%;
  390. height: 100%;
  391. }
  392. > .sub-text {
  393. position: absolute;
  394. left: 110%;
  395. top: 46%;
  396. transform: translateY(-50%);
  397. writing-mode: vertical-lr;
  398. font-family: KaiTi;
  399. font-weight: 400;
  400. font-size: 20px;
  401. color: #ffffff;
  402. line-height: 30px;
  403. white-space: pre;
  404. letter-spacing: 0.2em;
  405. text-align: center;
  406. }
  407. }
  408. > .long-desc {
  409. position: absolute;
  410. bottom: 30px;
  411. right: 30px;
  412. color: white;
  413. overflow: hidden;
  414. font-family: KaiTi;
  415. color: #ffffff;
  416. animation: none;
  417. display: flex;
  418. flex-direction: column;
  419. justify-content: space-between;
  420. z-index: 10;
  421. transition: opacity 1.5s ease;
  422. > .page2-box {
  423. display: flex;
  424. flex-direction: column;
  425. justify-content: center;
  426. align-items: center;
  427. cursor: pointer;
  428. > img {
  429. width: 75%;
  430. margin-bottom: 10px;
  431. }
  432. > div {
  433. font-size: calc(
  434. 20 / v-bind("windowSizeWhenDesignForRef") *
  435. v-bind("windowSizeInCssForRef")
  436. );
  437. font-family: KaiTi;
  438. }
  439. }
  440. }
  441. > .painting-wrap {
  442. position: absolute;
  443. left: 50%;
  444. top: 50%;
  445. width: calc(99vh / 937 * 552);
  446. height: 99vh;
  447. transform: translate(-50%, -50%);
  448. z-index: 1;
  449. transition: top 1.5s ease, left 1.5s ease, width 1.5s ease, height 1.5s ease;
  450. > .painting-border {
  451. width: 100%;
  452. height: 100%;
  453. position: absolute;
  454. }
  455. > .painting-stem {
  456. width: 80%;
  457. height: 74%;
  458. // height: calc(
  459. // 671 / v-bind("windowSizeWhenDesignForRef") *
  460. // v-bind("windowSizeInCssForRef")
  461. // );
  462. position: absolute;
  463. left: 50%;
  464. transform: translate(-50%, 24%);
  465. transition: opacity 1.5s ease;
  466. }
  467. }
  468. > .painting-wrap2 {
  469. left: 63%;
  470. top: 45%;
  471. width: calc(125vh / 937 * 552);
  472. height: calc(125vh);
  473. }
  474. > .painting-wrap3 {
  475. left: 60%;
  476. top: -20%;
  477. width: calc(600vh / 937 * 552);
  478. height: 600vh;
  479. }
  480. > .hotspot-wrap {
  481. position: absolute;
  482. left: 50%;
  483. top: 50%;
  484. width: calc(99vh / 937 * 552);
  485. height: 99vh;
  486. transform: translate(-50%, -50%);
  487. pointer-events: none;
  488. will-change: transform;
  489. backface-visibility: hidden;
  490. z-index: 10;
  491. transition: opacity 0.5s ease;
  492. & > div {
  493. z-index: 100;
  494. transition: all 1.5s ease-in-out;
  495. cursor: pointer;
  496. // transition: all 1.5s ease-in-out;
  497. }
  498. > .hotspot-1 {
  499. position: absolute;
  500. top: 11vh;
  501. right: 0;
  502. pointer-events: initial;
  503. }
  504. // > .hotspot-2 {
  505. // position: absolute;
  506. // left: 60px;
  507. // top: 60px;
  508. // pointer-events: initial;
  509. // }
  510. > .hotspot-3 {
  511. position: absolute;
  512. bottom: 0vh;
  513. right: -1vh;
  514. pointer-events: initial;
  515. }
  516. }
  517. > .hotspot-detail {
  518. z-index: 21;
  519. }
  520. > .operation-tip {
  521. position: absolute;
  522. right: 30px;
  523. transform: translateX(-50%);
  524. top: 50%;
  525. transform: translateY(-50%);
  526. }
  527. >.painting-detail{
  528. width: 100%;
  529. height: 100%;
  530. position: absolute;
  531. top: 0;
  532. left: 0;
  533. z-index: 30;
  534. }
  535. > .text-box {
  536. max-width: 450px;
  537. position: absolute;
  538. top: 50%;
  539. transform: translateY(-50%);
  540. left: 10%;
  541. color: #ffffff;
  542. font-size: 25px;
  543. line-height: 38px;
  544. font-family: "KaiTi";
  545. transition: opacity 1.5s ease;
  546. z-index: 10;
  547. transition: left 1.5s ease;
  548. .text-box-title {
  549. font-size: 42px;
  550. line-height: 48px;
  551. margin-bottom: 30px;
  552. }
  553. .text-box-desc{
  554. text-indent: 2em;
  555. }
  556. }
  557. }
  558. </style>