HomeView copy.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. <template>
  2. <div
  3. class="home"
  4. >
  5. <div class="bg-mask" />
  6. <Transition name="fade-out">
  7. <Startup
  8. v-if="!store.state.haveShownStartup"
  9. class="startup"
  10. />
  11. </Transition>
  12. <!-- 标题 -->
  13. <div
  14. class="title-wrap"
  15. :style="{
  16. opacity: titleOpacity,
  17. }"
  18. >
  19. <img
  20. class="title"
  21. src="@/assets/images/home-title.png"
  22. alt=""
  23. draggable="false"
  24. >
  25. <div class="sub-text">
  26. 南京博物院<br>
  27. 绢本 墨笔<br>
  28. 元 李衎<br>
  29. </div>
  30. </div>
  31. <!-- 画作 -->
  32. <div
  33. class="painting-wrap"
  34. :style="{
  35. top: `${paintingTop / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  36. width: `${paintingWidth / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  37. height: `${paintingHeight / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  38. }"
  39. >
  40. <div
  41. class="size-sign-h"
  42. :style="{
  43. opacity: sizeOpacity,
  44. }"
  45. >
  46. <img
  47. class=""
  48. src="@/assets/images/size-sign-h.png"
  49. alt=""
  50. draggable="false"
  51. >
  52. <span>100.6cm</span>
  53. </div>
  54. <div
  55. class="size-sign-v"
  56. :style="{
  57. opacity: sizeOpacity,
  58. }"
  59. >
  60. <img
  61. class=""
  62. src="@/assets/images/size-sign-v.png"
  63. alt=""
  64. draggable="false"
  65. >
  66. <span>151.7cm</span>
  67. </div>
  68. <img
  69. class="painting-border"
  70. src="@/assets/images/painting-border-new.png"
  71. alt=""
  72. draggable="false"
  73. >
  74. <img
  75. class="painting"
  76. src="@/assets/images/home-painting.jpg"
  77. alt=""
  78. draggable="false"
  79. >
  80. <img
  81. class="painting-stem"
  82. :style="{
  83. opacity: stemOpacity,
  84. }"
  85. src="@/assets/images/home-painting-stem.png"
  86. alt=""
  87. draggable="false"
  88. >
  89. <img
  90. class="painting-leaf"
  91. :style="{
  92. opacity: leafOpacity,
  93. }"
  94. src="@/assets/images/home-painting-leaf.png"
  95. alt=""
  96. draggable="false"
  97. >
  98. <img
  99. class="painting-stone"
  100. :style="{
  101. opacity: stoneOpacity,
  102. }"
  103. src="@/assets/images/home-painting-stone.png"
  104. alt=""
  105. draggable="false"
  106. >
  107. </div>
  108. <!-- 热点层 -->
  109. <div
  110. class="hotspot-wrap"
  111. :style="{
  112. top: `${paintingTop / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`
  113. }"
  114. >
  115. <HotspotForHomepage
  116. v-show="isShowHotspot"
  117. class="hotspot-1"
  118. @click="isShowHotspotDetail1 = true"
  119. />
  120. <HotspotForHomepage
  121. v-show="isShowHotspot"
  122. class="hotspot-2"
  123. @click="showBigPainting"
  124. />
  125. <HotspotForHomepage
  126. v-show="isShowHotspot"
  127. class="hotspot-3"
  128. @click="isShowHotspotDetail3 = true"
  129. />
  130. </div>
  131. <!-- 文字介绍 -->
  132. <div
  133. ref="longDesc"
  134. class="long-desc"
  135. :style="{
  136. top: `${(paintingTop + paintingHeight + 53) / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  137. opacity: longDescOpacity,
  138. }"
  139. >
  140. <h3>作品简介:</h3>
  141. <p
  142. v-for="(item, index) in homepagePaintingDesc"
  143. :key="index"
  144. >
  145. {{ item }}
  146. </p>
  147. <h3>作者简介:</h3>
  148. <p
  149. v-for="(item, index) in homepageAuthorDesc"
  150. :key="index"
  151. >
  152. {{ item }}
  153. </p>
  154. </div>
  155. <div
  156. class="fixed-desc detail-desc-stem"
  157. :style="{
  158. top: `${(paintingTop + 550) / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  159. opacity: stemOpacity,
  160. }"
  161. >
  162. {{ detailDescStem }}
  163. </div>
  164. <div
  165. class="fixed-desc detail-desc-leaf"
  166. :style="{
  167. top: `${(paintingTop + 550) / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  168. opacity: leafOpacity,
  169. }"
  170. >
  171. {{ detailDescLeaf }}
  172. </div>
  173. <div
  174. class="fixed-desc detail-desc-stone"
  175. :style="{
  176. top: `${(paintingTop + 550) / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  177. opacity: stoneOpacity,
  178. }"
  179. >
  180. {{ detailDescStone }}
  181. </div>
  182. <div
  183. class="fixed-desc summary-desc"
  184. :style="{
  185. top: `${(paintingTop + 550) / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
  186. opacity: summaryOpacity,
  187. }"
  188. >
  189. {{ summaryDesc }}
  190. </div>
  191. <div
  192. class="progress-bar"
  193. >
  194. <div class="bar-artwork-desc" />
  195. <img
  196. class="progress-bar-node-1"
  197. src="@/assets/images/progress-bar-node-1.png"
  198. alt=""
  199. draggable="false"
  200. >
  201. <div class="bar-author-desc" />
  202. <img
  203. class="progress-bar-node-2"
  204. src="@/assets/images/progress-bar-node-2.png"
  205. alt=""
  206. draggable="false"
  207. >
  208. <div class="bar-artwork-enjoy" />
  209. <img
  210. class="progress-bar-node-3"
  211. src="@/assets/images/progress-bar-node-3.png"
  212. alt=""
  213. draggable="false"
  214. >
  215. <div
  216. class="mask"
  217. :style="{
  218. width: `${(1 - scrollerElScrollTop / summaryHideAt) * 100}%`,
  219. }"
  220. />
  221. </div>
  222. <OperationTip
  223. v-if="isStartupOver"
  224. class="operation-tip"
  225. text="了解作品"
  226. :is-show="isShowOperationTip"
  227. />
  228. <div
  229. ref="scrollerEl"
  230. class="scroller"
  231. >
  232. <div
  233. class="inner"
  234. :style="{
  235. height: summaryHideAt + windowHeight + 'px',
  236. }"
  237. />
  238. </div>
  239. <!-- 热点详情页 -->
  240. <Transition name="fade-in-out">
  241. <HotspotDetail1
  242. v-if="isShowHotspotDetail1"
  243. class="hotspot-detail"
  244. @close="isShowHotspotDetail1 = false"
  245. />
  246. </Transition>
  247. <!-- <Transition name="fade-in-out">
  248. <PaintingDetail
  249. v-if="isShowPaintingDetail"
  250. :thumb="require(`@/assets/images/home-painting.jpg`)"
  251. :title="'修篁树石图'"
  252. :author="'李衎'"
  253. :age="'元'"
  254. :subtitle="'轴 绢本 墨笔'"
  255. :location="'南京博物院藏'"
  256. :painting-desc="homepagePaintingDesc.join('\n\n')"
  257. :author-desc="homepageAuthorDesc.join('\n\n')"
  258. :big-painting="require(`@/assets/images/home-painting-big.jpg`)"
  259. :need-operation-tip="true"
  260. class="hotspot-detail painting-detail"
  261. @close="isShowPaintingDetail = false"
  262. />
  263. </Transition> -->
  264. <Transition name="fade-in-out">
  265. <HotspotDetail3
  266. v-if="isShowHotspotDetail3"
  267. class="hotspot-detail"
  268. @close="isShowHotspotDetail3 = false"
  269. />
  270. </Transition>
  271. <Transition name="fade-in">
  272. <video
  273. v-if="isShowVideoFadeToNextPage"
  274. ref="videoFadeToNextPageEl"
  275. class="fade-to-next-page"
  276. src="@/assets/videos/fade-from-home-to-more-content.mp4"
  277. playsinline
  278. muted
  279. webkit-playsinline="true"
  280. x5-video-player-type="h5"
  281. @ended="router.replace({
  282. name: 'MoreContent',
  283. })"
  284. />
  285. </Transition>
  286. <Transition name="fade-in">
  287. <BtnSkip
  288. v-if="isShowSkip"
  289. @click="router.replace({
  290. name: 'MoreContent',
  291. })"
  292. />
  293. </Transition>
  294. <BtnClickMe
  295. class="go-next-page"
  296. text="点击继续"
  297. :is-show="isShowBtnGoNextPage"
  298. @click="onClickGoNextPage"
  299. />
  300. </div>
  301. </template>
  302. <script setup>
  303. import { ref, computed, watch, onMounted, inject, onBeforeUnmount, onUnmounted, nextTick } from "vue"
  304. import { useRoute, useRouter } from "vue-router"
  305. import { useStore } from "vuex"
  306. import Startup from '@/views/StartupView.vue'
  307. import useSizeAdapt from "@/useFunctions/useSizeAdapt"
  308. import HotspotDetail1 from '@/views/HotspotDetail1.vue'
  309. // import PaintingDetail from '@/views/PaintingDetail.vue'
  310. import HotspotDetail3 from '@/views/HotspotDetail3.vue'
  311. import { api as viewerApi } from 'v-viewer'
  312. import { useWindowSize } from '@vueuse/core'
  313. const { width: windowWidth, height: windowHeight } = useWindowSize()
  314. const route = useRoute()
  315. const router = useRouter()
  316. const store = useStore()
  317. const $env = inject('$env')
  318. const {
  319. windowSizeInCssForRef,
  320. windowSizeWhenDesignForRef,
  321. } = useSizeAdapt()
  322. const homepagePaintingDesc = configText.homepagePaintingDesc
  323. const homepageAuthorDesc = configText.homepageAuthorDesc
  324. const detailDescStem = configText.homepagePaintingDetailDescStem
  325. const detailDescLeaf = configText.homepagePaintingDetailDescLeaf
  326. const detailDescStone = configText.homepagePaintingDetailDescStone
  327. const summaryDesc = configText.homepagePaintingSummary
  328. const scrollerEl = ref(null)
  329. const scrollerElScrollTop = ref(0)
  330. function onScroll() {
  331. scrollerElScrollTop.value = scrollerEl.value.scrollTop
  332. }
  333. onMounted(() => {
  334. scrollerEl.value.addEventListener('scroll', onScroll)
  335. })
  336. onBeforeUnmount(() => {
  337. scrollerEl.value.removeEventListener('scroll', onScroll)
  338. })
  339. const isShowOperationTip = ref(true)
  340. watch(scrollerElScrollTop, (v) => {
  341. if (v > 0) {
  342. isShowOperationTip.value = false
  343. }
  344. })
  345. const haveShownStartup = computed(() => {
  346. return store.state.haveShownStartup
  347. })
  348. const isStartupOver = ref(false)
  349. const unwatch = watch(haveShownStartup, (v) => {
  350. if (v) {
  351. setTimeout(() => {
  352. isStartupOver.value = true
  353. }, 2000)
  354. unwatch()
  355. }
  356. })
  357. const titleHideAt = window.innerHeight * 0
  358. const titleHideFinishAt = window.innerHeight * 0.75
  359. const titleOpacity = computed(() => {
  360. let ret = null
  361. if (scrollerElScrollTop.value <= titleHideAt) {
  362. ret = 1
  363. } else {
  364. ret = 1 - (scrollerElScrollTop.value - titleHideAt) / (titleHideFinishAt - titleHideAt)
  365. }
  366. return ret
  367. })
  368. const paintingMoveUpAt = window.innerHeight * 0
  369. const paintingTopInitial = 236
  370. const paintingMoveUpFinishAt = paintingMoveUpAt + window.innerHeight * 1
  371. const paintingTopMovedUp = 41
  372. const paintingMoveDownAt = paintingMoveUpFinishAt + window.innerHeight * 0.5
  373. const paintingMoveDownFinishAt = paintingMoveDownAt + window.innerHeight * 0.25
  374. const paingtingTopMovedDown = 90
  375. const paintingTop = computed(() => {
  376. let ret = null
  377. if (scrollerElScrollTop.value <= paintingMoveUpAt) {
  378. ret = paintingTopInitial
  379. } else if (scrollerElScrollTop.value > paintingMoveUpAt && scrollerElScrollTop.value <= paintingMoveUpFinishAt) {
  380. ret = (scrollerElScrollTop.value - paintingMoveUpAt) / (paintingMoveUpFinishAt - paintingMoveUpAt) * (paintingTopMovedUp - paintingTopInitial) + paintingTopInitial
  381. } else if (scrollerElScrollTop.value > paintingMoveUpFinishAt && scrollerElScrollTop.value <= paintingMoveDownAt) {
  382. ret = paintingTopMovedUp
  383. } else if (scrollerElScrollTop.value > paintingMoveDownAt && scrollerElScrollTop.value <= paintingMoveDownFinishAt) {
  384. ret = (scrollerElScrollTop.value - paintingMoveDownAt) / (paintingMoveDownFinishAt - paintingMoveDownAt) * (paingtingTopMovedDown - paintingTopMovedUp) + paintingTopMovedUp
  385. } else {
  386. ret = paingtingTopMovedDown
  387. }
  388. return ret
  389. })
  390. const paintingWidthInitial = 308
  391. const paintingWidthMovedUp = 250
  392. const paintingWidthMovedDown = 308
  393. const paintingWidth = computed(() => {
  394. let ret = null
  395. if (scrollerElScrollTop.value <= paintingMoveUpAt) {
  396. ret = paintingWidthInitial
  397. } else if (scrollerElScrollTop.value > paintingMoveUpAt && scrollerElScrollTop.value <= paintingMoveUpFinishAt) {
  398. ret = (scrollerElScrollTop.value - paintingMoveUpAt) / (paintingMoveUpFinishAt - paintingMoveUpAt) * (paintingWidthMovedUp - paintingWidthInitial) + paintingWidthInitial
  399. } else if (scrollerElScrollTop.value > paintingMoveUpFinishAt && scrollerElScrollTop.value <= paintingMoveDownAt) {
  400. ret = paintingWidthMovedUp
  401. } else if (scrollerElScrollTop.value > paintingMoveDownAt && scrollerElScrollTop.value <= paintingMoveDownFinishAt) {
  402. ret = (scrollerElScrollTop.value - paintingMoveDownAt) / (paintingMoveDownFinishAt - paintingMoveDownAt) * (paintingWidthMovedDown - paintingWidthMovedUp) + paintingWidthMovedUp
  403. } else {
  404. ret = paintingWidthMovedDown
  405. }
  406. return ret
  407. })
  408. const paintingHeightInitial = 523
  409. const paintingHeightMovedUp = 425
  410. const paintingHeightMovedDown = 523
  411. const paintingHeight = computed(() => {
  412. let ret = null
  413. if (scrollerElScrollTop.value <= paintingMoveUpAt) {
  414. ret = paintingHeightInitial
  415. } else if (scrollerElScrollTop.value > paintingMoveUpAt && scrollerElScrollTop.value <= paintingMoveUpFinishAt) {
  416. ret = (scrollerElScrollTop.value - paintingMoveUpAt) / (paintingMoveUpFinishAt - paintingMoveUpAt) * (paintingHeightMovedUp - paintingHeightInitial) + paintingHeightInitial
  417. } else if (scrollerElScrollTop.value > paintingMoveUpFinishAt && scrollerElScrollTop.value <= paintingMoveDownAt) {
  418. ret = paintingHeightMovedUp
  419. } else if (scrollerElScrollTop.value > paintingMoveDownAt && scrollerElScrollTop.value <= paintingMoveDownFinishAt) {
  420. ret = (scrollerElScrollTop.value - paintingMoveDownAt) / (paintingMoveDownFinishAt - paintingMoveDownAt) * (paintingHeightMovedDown - paintingHeightMovedUp) + paintingHeightMovedUp
  421. } else {
  422. ret = paintingHeightMovedDown
  423. }
  424. return ret
  425. })
  426. const longDesc = ref(null)
  427. const longDescShowFinishAt = window.innerHeight * 0.25
  428. const longDescHideAt = longDescShowFinishAt + window.innerHeight * 1
  429. const longDescHideFinishAt = longDescHideAt + window.innerHeight * 0.25
  430. const longDescOpacity = computed(() => {
  431. let ret = null
  432. if (scrollerElScrollTop.value <= longDescShowFinishAt) {
  433. ret = 1 - (longDescShowFinishAt - scrollerElScrollTop.value) / (longDescShowFinishAt)
  434. } else if (scrollerElScrollTop.value > longDescShowFinishAt && scrollerElScrollTop.value < longDescHideAt) {
  435. ret = 1
  436. } else {
  437. ret = 1 - (scrollerElScrollTop.value - longDescHideAt) / (longDescHideFinishAt - longDescHideAt)
  438. }
  439. return ret
  440. })
  441. watch(scrollerElScrollTop, (vNew, vOld) => {
  442. if (vNew > paintingMoveUpFinishAt) {
  443. longDesc.value.scrollTop = vNew - paintingMoveUpFinishAt
  444. } else if (vNew < vOld && vNew <= paintingMoveUpFinishAt) {
  445. longDesc.value.scrollTop = 0
  446. }
  447. })
  448. const stemShowAt = longDescHideFinishAt + window.innerHeight * 0
  449. const stemShowFinishAt = stemShowAt + window.innerHeight * 0.25
  450. const stemHideAt = stemShowFinishAt + window.innerHeight * 0.3
  451. const stemHideFisishAt = stemHideAt + window.innerHeight * 0.25
  452. const stemOpacity = computed(() => {
  453. let ret = null
  454. if (scrollerElScrollTop.value <= stemShowAt) {
  455. ret = 0
  456. } else if (scrollerElScrollTop.value > stemShowAt && scrollerElScrollTop.value < stemShowFinishAt) {
  457. ret = (scrollerElScrollTop.value - stemShowAt) / (stemShowFinishAt - stemShowAt)
  458. } else if (scrollerElScrollTop.value >= stemShowFinishAt && scrollerElScrollTop.value <= stemHideAt) {
  459. ret = 1
  460. } else if (scrollerElScrollTop.value > stemHideAt && scrollerElScrollTop.value < stemHideFisishAt) {
  461. ret = 1 - (scrollerElScrollTop.value - stemHideAt) / (stemHideFisishAt - stemHideAt)
  462. } else {
  463. ret = 0
  464. }
  465. return ret
  466. })
  467. const leafShowAt = stemHideFisishAt + (0 * window.innerHeight)
  468. const leafShowFinishAt = leafShowAt + (0.25 * window.innerHeight)
  469. const leafHideAt = leafShowFinishAt + (0.3 * window.innerHeight)
  470. const leafHideFisishAt = leafHideAt + (0.25 * window.innerHeight)
  471. const leafOpacity = computed(() => {
  472. let ret = null
  473. if (scrollerElScrollTop.value <= leafShowAt) {
  474. ret = 0
  475. } else if (scrollerElScrollTop.value > leafShowAt && scrollerElScrollTop.value < leafShowFinishAt) {
  476. ret = (scrollerElScrollTop.value - leafShowAt) / (leafShowFinishAt - leafShowAt)
  477. } else if (scrollerElScrollTop.value >= leafShowFinishAt && scrollerElScrollTop.value <= leafHideAt) {
  478. ret = 1
  479. } else if (scrollerElScrollTop.value > leafHideAt && scrollerElScrollTop.value < leafHideFisishAt) {
  480. ret = 1 - (scrollerElScrollTop.value - leafHideAt) / (leafHideFisishAt - leafHideAt)
  481. } else {
  482. ret = 0
  483. }
  484. return ret
  485. })
  486. const stoneShowAt = leafHideFisishAt + (0 * window.innerHeight)
  487. const stoneShowFinishAt = stoneShowAt + (0.25 * window.innerHeight)
  488. const stoneHideAt = stoneShowFinishAt + (0.3 * window.innerHeight)
  489. const stoneHideFinishAt = stoneHideAt + (0.25 * window.innerHeight)
  490. const stoneOpacity = computed(() => {
  491. let ret = null
  492. if (scrollerElScrollTop.value <= stoneShowAt) {
  493. ret = 0
  494. } else if (scrollerElScrollTop.value > stoneShowAt && scrollerElScrollTop.value < stoneShowFinishAt) {
  495. ret = (scrollerElScrollTop.value - stoneShowAt) / (stoneShowFinishAt - stoneShowAt)
  496. } else if (scrollerElScrollTop.value >= stoneShowFinishAt && scrollerElScrollTop.value <= stoneHideAt) {
  497. ret = 1
  498. } else if (scrollerElScrollTop.value > stoneHideAt && scrollerElScrollTop.value < stoneHideFinishAt) {
  499. ret = 1 - (scrollerElScrollTop.value - stoneHideAt) / (stoneHideFinishAt - stoneHideAt)
  500. } else {
  501. ret = 0
  502. }
  503. return ret
  504. })
  505. const summaryShowAt = stoneHideFinishAt + window.innerHeight * 0
  506. const summaryShowFinishAt = summaryShowAt + window.innerHeight * 0.25
  507. const summaryHideAt = summaryShowFinishAt + window.innerHeight * 0.3
  508. const summaryHideFisishAt = summaryHideAt + window.innerHeight * 0.25
  509. const summaryOpacity = computed(() => {
  510. let ret = null
  511. if (scrollerElScrollTop.value <= summaryShowAt) {
  512. ret = 0
  513. } else if (scrollerElScrollTop.value > summaryShowAt && scrollerElScrollTop.value < summaryShowFinishAt) {
  514. ret = (scrollerElScrollTop.value - summaryShowAt) / (summaryShowFinishAt - summaryShowAt)
  515. } else if (scrollerElScrollTop.value >= summaryShowFinishAt && scrollerElScrollTop.value <= summaryHideAt) {
  516. ret = 1
  517. } else if (scrollerElScrollTop.value > summaryHideAt && scrollerElScrollTop.value < summaryHideFisishAt) {
  518. ret = 1 - (scrollerElScrollTop.value - summaryHideAt) / (summaryHideFisishAt - summaryHideAt)
  519. } else {
  520. ret = 0
  521. }
  522. return ret
  523. })
  524. const sizeShowAt = stemShowAt
  525. const sizeShowFinishAt = stemShowFinishAt
  526. const sizeHideAt = stoneHideAt
  527. const sizeHideFisishAt = stoneHideFinishAt
  528. const sizeOpacity = computed(() => {
  529. let ret = null
  530. if (scrollerElScrollTop.value <= sizeShowAt) {
  531. ret = 0
  532. } else if (scrollerElScrollTop.value > sizeShowAt && scrollerElScrollTop.value < sizeShowFinishAt) {
  533. ret = (scrollerElScrollTop.value - sizeShowAt) / (sizeShowFinishAt - sizeShowAt)
  534. } else if (scrollerElScrollTop.value >= sizeShowFinishAt && scrollerElScrollTop.value <= sizeHideAt) {
  535. ret = 1
  536. } else if (scrollerElScrollTop.value > sizeHideAt && scrollerElScrollTop.value < sizeHideFisishAt) {
  537. ret = 1 - (scrollerElScrollTop.value - sizeHideAt) / (sizeHideFisishAt - sizeHideAt)
  538. } else {
  539. ret = 0
  540. }
  541. return ret
  542. })
  543. const isShowHotspot = computed(() => {
  544. let ret = null
  545. if (scrollerElScrollTop.value <= sizeShowAt) {
  546. ret = false
  547. } else {
  548. return true
  549. }
  550. return ret
  551. })
  552. const isShowHotspotDetail1 = ref(false)
  553. // const isShowPaintingDetail = ref(false)
  554. const isShowHotspotDetail3 = ref(false)
  555. function showBigPainting() {
  556. viewerApi({
  557. images: [require(`@/assets/images/home-painting-big.jpg`)],
  558. })
  559. }
  560. /**
  561. * 跳转新页面
  562. */
  563. const videoFadeToNextPageEl = ref(null)
  564. const isShowVideoFadeToNextPage = ref(false)
  565. const isShowSkip = ref(false)
  566. // const fingerPosYWhenTouchStart = ref(0)
  567. // const isAtBottomWhenTouchStart = ref(false)
  568. // const handletouchstart = (event) => {
  569. // fingerPosYWhenTouchStart.value = event.changedTouches[0].pageY
  570. // if (Math.abs(scrollerEl.value.scrollTop + scrollerEl.value.clientHeight - scrollerEl.value.scrollHeight) <= 1) {
  571. // isAtBottomWhenTouchStart.value = true
  572. // } else {
  573. // isAtBottomWhenTouchStart.value = false
  574. // }
  575. // }
  576. // const touchMove = (event) => {
  577. // let currentY = event.changedTouches[0].pageY
  578. // let tY = currentY - fingerPosYWhenTouchStart.value
  579. // if (tY < -1 && isAtBottomWhenTouchStart.value) {
  580. // isShowVideoFadeToNextPage.value = true
  581. // nextTick(() => {
  582. // videoFadeToNextPageEl.value.play()
  583. // })
  584. // setTimeout(() => {
  585. // isShowSkip.value = true
  586. // }, 2000)
  587. // }
  588. // }
  589. const isShowBtnGoNextPage = ref(false)
  590. watch(scrollerElScrollTop, (v) => {
  591. if (Math.abs(v + windowHeight.value - scrollerEl.value.scrollHeight) < 3) {
  592. isShowBtnGoNextPage.value = true
  593. } else {
  594. isShowBtnGoNextPage.value = false
  595. }
  596. })
  597. function onClickGoNextPage() {
  598. isShowBtnGoNextPage.value = false
  599. isShowVideoFadeToNextPage.value = true
  600. nextTick(() => {
  601. videoFadeToNextPageEl.value.play()
  602. })
  603. setTimeout(() => {
  604. isShowSkip.value = true
  605. }, 2000)
  606. }
  607. </script>
  608. <style lang="less" scoped>
  609. .home {
  610. width: 100%;
  611. height: 100%;
  612. background-image: url(@/assets/images/home-painting-line-small.jpg);
  613. background-size: cover;
  614. background-repeat: no-repeat;
  615. background-position: center center;
  616. // 滚动条,只设置某一项可能导致不生效。
  617. ::-webkit-scrollbar { width: 0; height: 0; }
  618. >.bg-mask{
  619. position: absolute;
  620. left: 0;
  621. top: 0;
  622. width: 100%;
  623. height: 100%;
  624. background: rgba(60, 89, 71, 0.65);
  625. backdrop-filter: blur(calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
  626. }
  627. >.startup{
  628. z-index: 10;
  629. }
  630. >.title-wrap{
  631. position: absolute;
  632. left: 50%;
  633. top: calc(36 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  634. transform: translate(-50%);
  635. width: calc(43 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  636. height: calc(180 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  637. z-index: 5;
  638. >img.title{
  639. position: absolute;
  640. left: 0;
  641. top: 0;
  642. width: 100%;
  643. height: 100%;
  644. }
  645. >.sub-text{
  646. position: absolute;
  647. left: 110%;
  648. top: 46%;
  649. transform: translateY(-50%);
  650. writing-mode: vertical-lr;
  651. font-family: KaiTi, KaiTi;
  652. font-weight: 400;
  653. font-size: calc(18 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  654. color: #FFFFFF;
  655. line-height: calc(21 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  656. white-space: pre;
  657. letter-spacing: 0.2em;
  658. text-align: center;
  659. }
  660. }
  661. >.painting-wrap{
  662. position: absolute;
  663. left: 50%;
  664. transform: translate(-50%, 0);
  665. >.size-sign-h{
  666. position: absolute;
  667. left: 50%;
  668. top: 0;
  669. transform: translate(-50%, -105%);
  670. width: calc(245 / 308 * 100%);
  671. >img{
  672. width: 100%;
  673. }
  674. >span{
  675. position: absolute;
  676. left: 50%;
  677. top: 50%;
  678. transform: translate(-50%, -50%);
  679. font-family: KaiTi, KaiTi;
  680. font-weight: 400;
  681. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  682. color: #FFFFFF;
  683. line-height: calc(23 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  684. text-shadow: 0px 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) #F8DD86;
  685. }
  686. }
  687. >.size-sign-v{
  688. position: absolute;
  689. right: 0;
  690. top: 54%;
  691. transform: translate(80%, -50%);
  692. height: calc(371 / 523 * 100%);
  693. >img{
  694. height: 100%;
  695. }
  696. >span{
  697. position: absolute;
  698. left: 50%;
  699. top: 50%;
  700. transform: translate(-50%, -50%);
  701. font-family: KaiTi, KaiTi;
  702. font-weight: 400;
  703. font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  704. color: #FFFFFF;
  705. line-height: calc(23 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  706. text-shadow: 0px 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) #F8DD86;
  707. writing-mode: vertical-lr;
  708. }
  709. }
  710. >img.painting-border{
  711. position: absolute;
  712. left: 0;
  713. top: 0;
  714. width: 100%;
  715. height: 100%;
  716. }
  717. >img.painting, img.painting-stem, img.painting-leaf, img.painting-stone{
  718. position: absolute;
  719. left: 50%;
  720. top: 54%;
  721. transform: translate(-50%, -50%);
  722. width: calc(245 / 308 * 100%);
  723. }
  724. }
  725. >.hotspot-wrap{
  726. position: absolute;
  727. left: 50%;
  728. transform: translate(-50%, 0);
  729. width: calc(309 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  730. height: calc(522 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  731. z-index: 7;
  732. pointer-events: none;
  733. &>div{
  734. z-index: 100;
  735. }
  736. >.hotspot-1{
  737. position: absolute;
  738. top: calc(54 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  739. right: calc(0 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  740. pointer-events: initial;
  741. }
  742. >.hotspot-2{
  743. position: absolute;
  744. left: calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  745. top: calc(222 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  746. pointer-events: initial;
  747. }
  748. >.hotspot-3{
  749. position: absolute;
  750. bottom: calc(-10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  751. right: calc(-10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  752. pointer-events: initial;
  753. }
  754. }
  755. >.long-desc{
  756. position: absolute;
  757. left: 50%;
  758. bottom: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  759. width: calc(309 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  760. transform: translate(-50%, 0);
  761. color: white;
  762. overflow: auto;
  763. font-family: KaiTi, KaiTi;
  764. color: #FFFFFF;
  765. >h3{
  766. font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  767. margin-bottom: 0.5em;
  768. font-weight: 600;
  769. }
  770. >p{
  771. font-weight: 400;
  772. font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  773. line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  774. text-align: justify;
  775. margin-bottom: 0.5em;
  776. }
  777. }
  778. >.fixed-desc{
  779. position: absolute;
  780. left: 50%;
  781. transform: translateX(-50%);
  782. width: calc(309 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  783. height: 20%;
  784. display: flex;
  785. justify-content: center;
  786. align-items: center;
  787. font-family: KaiTi, KaiTi;
  788. color: #FFFFFF;
  789. font-weight: 400;
  790. font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  791. line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  792. text-align: justify;
  793. }
  794. >.progress-bar{
  795. position: absolute;
  796. left: 0;
  797. bottom: 0;
  798. width: 100%;
  799. height: 15px;
  800. >.bar-artwork-desc{
  801. position: absolute;
  802. left: 0;
  803. bottom: 0;
  804. right: 10px;
  805. height: 3px;
  806. background-color: #A9D185;
  807. }
  808. >img.progress-bar-node-1{
  809. position: absolute;
  810. left: calc(0.6 * v-bind('longDescHideFinishAt') / v-bind('summaryHideAt') * 100%);
  811. bottom: 1px;
  812. width: 2.41px;
  813. height: 10.23px
  814. }
  815. >.bar-author-desc{
  816. position: absolute;
  817. left: 12px;
  818. bottom: 0;
  819. right: calc(v-bind('longDescHideFinishAt') / v-bind('summaryHideAt') * 100%);
  820. height: 3px;
  821. background: #A9D185;
  822. }
  823. >img.progress-bar-node-2{
  824. position: absolute;
  825. left: calc(v-bind('longDescHideFinishAt') / v-bind('summaryHideAt') * 100%);
  826. bottom: 1px;
  827. width: 7.5px;
  828. height: 10.8px
  829. }
  830. >.bar-artwork-enjoy{
  831. position: absolute;
  832. left: calc(v-bind('stoneShowAt') / v-bind('summaryHideAt') * 100%);
  833. bottom: 0;
  834. right: 0;
  835. height: 3px;
  836. background: #A9D185;
  837. }
  838. >img.progress-bar-node-3{
  839. position: absolute;
  840. right: 0;
  841. bottom: 1px;
  842. width: 9.7px;
  843. height: 10.8px
  844. }
  845. > .mask{
  846. position: absolute;
  847. right: 0;
  848. bottom: 0;
  849. height: 15px;
  850. background-color: #6e8175;
  851. }
  852. }
  853. >.operation-tip{
  854. position: absolute;
  855. left: 50%;
  856. bottom: calc(77 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  857. transform: translateX(-50%);
  858. }
  859. >.scroller{
  860. position: absolute;
  861. left: 0;
  862. top: 0;
  863. width: 100%;
  864. height: 100%;
  865. overflow: auto;
  866. >.inner{
  867. width: 100%;
  868. }
  869. }
  870. >.hotspot-detail{
  871. z-index: 10;
  872. }
  873. >.hotspot-detail.painting-detail{
  874. backdrop-filter: blur(calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
  875. }
  876. >video.fade-to-next-page{
  877. position: absolute;
  878. left: 0;
  879. top: 0;
  880. width: 100%;
  881. height: 100%;
  882. object-fit: cover;
  883. z-index: 20;
  884. }
  885. >button.go-next-page{
  886. position: absolute;
  887. left: 50%;
  888. bottom: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  889. z-index: 20;
  890. transform: translate(-50%, 0);
  891. }
  892. }
  893. </style>