HomeWeb.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. <template>
  2. <div class="hotspot-home">
  3. <audio
  4. ref="bg-audio"
  5. class="bg-audio"
  6. :src="bgAudioUrl"
  7. loop
  8. autoplay
  9. />
  10. <button
  11. class="close"
  12. @click="onClickClose"
  13. >
  14. <img
  15. src="@/assets/images/close.png"
  16. alt="关闭"
  17. draggable="false"
  18. >
  19. </button>
  20. <div
  21. class="bg-wrapper"
  22. :style="{
  23. backgroundImage: `url(${bgImg})`,
  24. }"
  25. >
  26. <h1
  27. :title="hotspotData.title"
  28. :style="{
  29. backgroundImage: `url(${titleBottomLine})`,
  30. }"
  31. v-html="hotspotData.title"
  32. />
  33. <div
  34. class="desc"
  35. v-html="descForShow"
  36. />
  37. <menu>
  38. <button
  39. v-if="bgAudioUrl"
  40. @click="isBgAudioMuted = !isBgAudioMuted"
  41. >
  42. <img
  43. v-show="isBgAudioMuted"
  44. class="bg-audio-control"
  45. src="@/assets/images/bg-audio.png"
  46. alt=""
  47. draggable="false"
  48. >
  49. <img
  50. v-show="!isBgAudioMuted"
  51. class="bg-audio-control"
  52. src="@/assets/images/bg-audio-muted.png"
  53. alt=""
  54. draggable="false"
  55. >
  56. </button>
  57. <!-- <button @click="onClickLike">
  58. <img
  59. class="like"
  60. src="@/assets/images/like.png"
  61. alt=""
  62. draggable="false"
  63. >
  64. <transition name="bubble">
  65. <div
  66. v-if="isShowPlusOne"
  67. class="plus-one"
  68. >
  69. +1
  70. </div>
  71. </transition>
  72. </button> -->
  73. <button @click="onClickShare">
  74. <img
  75. class="share"
  76. src="@/assets/images/share.png"
  77. alt=""
  78. draggable="false"
  79. >
  80. </button>
  81. </menu>
  82. <div
  83. v-if="isShowVideos"
  84. v-show="!isShowShare"
  85. class="swiper-wrapper-mine video-wrap"
  86. >
  87. <div
  88. class="swiper-root"
  89. >
  90. <div
  91. class="swiper-wrapper"
  92. >
  93. <div
  94. v-for="(item, index) in hotspotData.video"
  95. :key="index"
  96. class="swiper-slide"
  97. >
  98. <video
  99. ref="video"
  100. :src="item.url"
  101. controls
  102. controlslist="nodownload"
  103. disablePictureInPicture
  104. />
  105. </div>
  106. </div>
  107. <div class="swiper-pagination">
  108. <!-- <span class="cur">{{ currentSlideIdx + 1 }}</span> / <span>{{ typesForShow[currentTabIdx].list.length }}</span> -->
  109. </div>
  110. <div class="swiper-button-prev" />
  111. <div class="swiper-button-next" />
  112. </div>
  113. </div>
  114. <!-- <div
  115. v-if="typesForShow[currentTabIdx].name === '模型'"
  116. class="swiper-wrapper-mine model-wrap"
  117. >
  118. <div
  119. class="swiper-root"
  120. >
  121. <div
  122. class="swiper-wrapper"
  123. >
  124. <iframe
  125. v-for="(item, index) in typesForShow[currentTabIdx].list"
  126. :key="index"
  127. :src="item.url"
  128. frameborder="0"
  129. class="swiper-slide"
  130. />
  131. </div>
  132. <div class="swiper-pagination">
  133. <span class="cur">{{ currentSlideIdx + 1 }}</span> / <span>{{ typesForShow[currentTabIdx].list.length }}</span>
  134. </div>
  135. <div class="swiper-button-prev" />
  136. <div class="swiper-button-next" />
  137. </div>
  138. </div> -->
  139. <!-- <div
  140. v-if="isShowAudios"
  141. v-show="!isShowShare"
  142. class="swiper-wrapper-mine audio-wrap"
  143. >
  144. <div
  145. class="swiper-root"
  146. >
  147. <div
  148. class="swiper-wrapper"
  149. >
  150. <div
  151. v-for="(item, index) in hotspotData.audio"
  152. :key="index"
  153. class="swiper-slide"
  154. >
  155. <audio
  156. ref="audio"
  157. :src="item.url"
  158. controls
  159. controlslist="nodownload"
  160. disablePictureInPicture
  161. />
  162. </div>
  163. </div>
  164. <div class="swiper-pagination">
  165. </div>
  166. <div class="swiper-button-prev" />
  167. <div class="swiper-button-next" />
  168. </div>
  169. </div> -->
  170. <div
  171. v-if="isShowImages"
  172. v-show="!isShowShare"
  173. class="swiper-wrapper-mine image-wrap"
  174. >
  175. <div
  176. class="swiper-root"
  177. >
  178. <div
  179. v-viewer="{
  180. button: true,
  181. navbar: false,
  182. title: false,
  183. toolbar: false,
  184. tooltip: false,
  185. movable: true,
  186. zoomable: true,
  187. rotatable: true,
  188. scalable: true,
  189. transition: false,
  190. fullscreen: false,
  191. keyboard: true,
  192. loop: false,
  193. }"
  194. class="swiper-wrapper"
  195. >
  196. <img
  197. v-for="(item, index) in hotspotData.images"
  198. :key="index"
  199. v-lazy="item"
  200. class="swiper-slide"
  201. alt=""
  202. draggable="false"
  203. >
  204. </div>
  205. <div class="swiper-pagination">
  206. <!-- <span
  207. class="cur"
  208. >
  209. {{ currentSlideIdx + 1 }}
  210. </span>
  211. /
  212. <span>
  213. {{ hotspotData.Images ? hotspotData.images.length : '' }}
  214. </span> -->
  215. </div>
  216. <div class="swiper-button-prev" />
  217. <div class="swiper-button-next" />
  218. </div>
  219. </div>
  220. <div
  221. v-if="isShowShare"
  222. v-click-outside.click="closeCode2d"
  223. class="share-wrap"
  224. >
  225. <img
  226. src="@/assets/images/code2d.png"
  227. alt=""
  228. class="code"
  229. draggable="false"
  230. >
  231. <img
  232. src="@/assets/images/share-tip.png"
  233. alt=""
  234. class="tip"
  235. draggable="false"
  236. >
  237. </div>
  238. </div>
  239. </div>
  240. </template>
  241. <script>
  242. import Swiper from 'swiper/swiper-bundle.esm.js'
  243. import 'swiper/swiper-bundle.css'
  244. import bgImg from "@/assets/images/bg.png"
  245. import titleBottomLine from "@/assets/images/title-bottom-line.png"
  246. // import browser from "@/utils/browser";
  247. export default {
  248. data() {
  249. return {
  250. hotspotData: {}, // 热点数据
  251. bgAudioUrl: "", //背景音频url
  252. isBgAudioMuted: false,
  253. isShowImages: false,
  254. isShowVideos: false,
  255. isShowAudios: false,
  256. currentSlideIdx: 0,
  257. bgImg,
  258. titleBottomLine,
  259. isShowPlusOne: false,
  260. isShowShare: false,
  261. }
  262. },
  263. computed: {
  264. descForShow() {
  265. if (this.isShowImages) {
  266. return this.hotspotData.imagesDesc[this.currentSlideIdx] || this.hotspotData.content
  267. } else if (this.isShowVideos) {
  268. return this.hotspotData.videosDesc[this.currentSlideIdx] || this.hotspotData.content
  269. } else {
  270. return this.hotspotData.content
  271. }
  272. },
  273. },
  274. watch: {
  275. isBgAudioMuted: {
  276. handler(vNew) {
  277. if (vNew) {
  278. this.$refs['bg-audio'].pause() // or toggle静音?
  279. } else {
  280. this.$refs['bg-audio'].play() // or toggle静音?
  281. }
  282. }
  283. }
  284. },
  285. async mounted() {
  286. await this.getData()
  287. this.$nextTick(() => {
  288. const that = this
  289. new Swiper('.swiper-root', {
  290. pagination: {
  291. el: '.swiper-pagination',
  292. },
  293. navigation: {
  294. nextEl: '.swiper-button-next',
  295. prevEl: '.swiper-button-prev',
  296. },
  297. on: {
  298. // 自动播放
  299. afterInit: function (e) {
  300. if (that.isShowVideos) {
  301. that.$nextTick(() => {
  302. that.$refs.video[0].play()
  303. })
  304. }
  305. if (that.isShowAudios) {
  306. that.$nextTick(() => {
  307. that.$refs.audio[0].play()
  308. })
  309. }
  310. },
  311. slideChange: function(e) {
  312. that.currentSlideIdx = e.activeIndex
  313. // 自动播放
  314. if (that.isShowVideos) {
  315. for (let index = 0; index < that.$refs.video.length; index++) {
  316. if (index !== that.currentSlideIdx) {
  317. that.$refs.video[index].pause()
  318. } else {
  319. that.$refs.video[index].play()
  320. }
  321. }
  322. }
  323. if (that.isShowAudios) {
  324. for (let index = 0; index < that.$refs.audio.length; index++) {
  325. if (index !== that.currentSlideIdx) {
  326. that.$refs.audio[index].pause()
  327. } else {
  328. that.$refs.audio[index].play()
  329. }
  330. }
  331. }
  332. }
  333. }
  334. })
  335. })
  336. },
  337. methods: {
  338. async getData() {
  339. let url = `https://super.4dage.com/data/${this.$route.query.id}/hot/js/data.js?time=${Math.random()}`
  340. let result = (await this.$http.get(url)).data
  341. this.hotspotData = result[this.$route.query.m]
  342. if (!this.hotspotData) {
  343. return alert("热点解析错误")
  344. }
  345. console.log('热点数据:', this.hotspotData)
  346. this.bgAudioUrl = this.hotspotData.backgroundMusic
  347. if (this.hotspotData.images && this.hotspotData.images.length) {
  348. this.isShowImages = true
  349. } else if (this.hotspotData.video && this.hotspotData.video.length) {
  350. this.isShowVideos = true
  351. // } else if (false) {
  352. // this.isShowAudios = true
  353. // this.hotspotData.audio = ...
  354. }
  355. },
  356. onClickClose() {
  357. window.parent.document.getElementById('closepop').click()
  358. },
  359. // onClickLike() {
  360. // const res = globalApi.like()
  361. // if (res && res.then) {
  362. // res.then(() => {
  363. // this.isShowPlusOne = true
  364. // setTimeout(() => {
  365. // this.isShowPlusOne = false
  366. // }, 1000)
  367. // })
  368. // }
  369. // },
  370. onClickShare() {
  371. setTimeout(() => {
  372. this.isShowShare = true
  373. }, 200)
  374. },
  375. closeCode2d() {
  376. if (this.isShowShare) {
  377. this.isShowShare = false
  378. }
  379. }
  380. }
  381. }
  382. </script>
  383. <style lang="less" scoped>
  384. .hotspot-home {
  385. position: absolute;
  386. left: 50%;
  387. top: 50%;
  388. transform: translate(-50%, -50%);
  389. width: 1350px;
  390. height: 810px;
  391. padding: 0 70px 0 0;
  392. color: #F1F3F4;
  393. > .bg-audio {
  394. display: none;
  395. }
  396. > button.close {
  397. position: absolute;
  398. top: 10px;
  399. right: 0px;
  400. width: 58px;
  401. height: 58px;
  402. > img {
  403. width: 100%;
  404. height: 100%;
  405. }
  406. }
  407. > .bg-wrapper {
  408. width: 100%;
  409. height: 100%;
  410. position: relative;
  411. background-size: contain;
  412. background-repeat: no-repeat;
  413. background-position: center center;
  414. > h1 {
  415. position: absolute;
  416. top: 211px;
  417. left: 44px;
  418. max-width: 418px;
  419. font-size: 28px;
  420. font-family: DFLiShuW7;
  421. overflow: hidden;
  422. white-space: pre;
  423. text-overflow: ellipsis;
  424. letter-spacing: 5px;
  425. padding-left: 10px;
  426. padding-right: 10px;
  427. padding-bottom: 24px;
  428. background-size: contain;
  429. background-repeat: no-repeat;
  430. background-position: center bottom;
  431. }
  432. > .desc {
  433. position: absolute;
  434. top: 347px;
  435. left: 55px;
  436. width: 390px;
  437. font-size: 16px;
  438. line-height: 26px;
  439. font-family: Adobe Heiti Std;
  440. overflow: auto;
  441. height: 300px;
  442. }
  443. > menu {
  444. position: absolute;
  445. right: 817px;
  446. bottom: 90px;
  447. > button {
  448. display: inline-block;
  449. width: 48px;
  450. height: 48px;
  451. margin-left: 24px;
  452. position: relative;
  453. img {
  454. width: 100%;
  455. height: 100%;
  456. }
  457. // .plus-one {
  458. // position: absolute;
  459. // top: 0;
  460. // right: 0;
  461. // transform: translate(50%, -50%);
  462. // }
  463. }
  464. }
  465. .swiper-wrapper-mine {
  466. position: absolute;
  467. top: 50%;
  468. right: 30px;
  469. width: 720px;
  470. height: 476px;
  471. transform: translateY(-50%);
  472. .swiper-root {
  473. overflow: hidden;
  474. height: 100%;
  475. width: 100%;
  476. .swiper-wrapper {
  477. }
  478. .swiper-pagination {
  479. position: absolute;
  480. top: 100%;
  481. left: 50%;
  482. transform: translateX(-50%);
  483. font-size: 1.33rem;
  484. font-family: Inter-Regular, Inter;
  485. .cur {
  486. }
  487. }
  488. .swiper-button-prev {
  489. left: -30px;
  490. width: 30px;
  491. background-image: url(../assets/images/arrow-left.png);
  492. background-size: contain;
  493. background-repeat: no-repeat;
  494. background-position: center;
  495. &::after {
  496. content: '';
  497. }
  498. }
  499. .swiper-button-next {
  500. right: -30px;
  501. width: 30px;
  502. background-image: url(../assets/images/arrow-right.png);
  503. background-size: contain;
  504. background-repeat: no-repeat;
  505. background-position: center;
  506. &::after {
  507. content: '';
  508. }
  509. }
  510. }
  511. }
  512. .swiper-wrapper-mine.video-wrap {
  513. .swiper-root {
  514. .swiper-wrapper {
  515. .swiper-slide {
  516. > video {
  517. width: 100%;
  518. height: 100%;
  519. background: #000;
  520. }
  521. }
  522. }
  523. }
  524. }
  525. .swiper-wrapper-mine.model-wrap {
  526. .swiper-root {
  527. .swiper-wrapper {
  528. }
  529. }
  530. }
  531. .swiper-wrapper-mine.audio-wrap {
  532. .swiper-root {
  533. .swiper-wrapper {
  534. .swiper-slide {
  535. > audio {
  536. position: absolute;
  537. top: 50%;
  538. width: 100%;
  539. transform: translateY(-50%);
  540. padding: 10px;
  541. background: #7d3226;
  542. border-radius: 5px;
  543. }
  544. }
  545. }
  546. }
  547. }
  548. .swiper-wrapper-mine.image-wrap {
  549. .swiper-root {
  550. .swiper-wrapper {
  551. > img {
  552. width: 100%;
  553. height: 100%;
  554. object-fit: contain;
  555. }
  556. }
  557. }
  558. }
  559. .share-wrap {
  560. position: absolute;
  561. top: 50%;
  562. transform: translateY(-50%);
  563. right: 244px;
  564. > img.code {
  565. width: 300px;
  566. height: 300px;
  567. }
  568. > img.tip {
  569. position: absolute;
  570. left: 50%;
  571. top: calc(100% + 10px);
  572. transform: translateX(-50%);
  573. width: 150px;
  574. }
  575. }
  576. }
  577. }
  578. /deep/.swiper-pagination-bullet-active {
  579. background: #a10e0c;
  580. }
  581. // .bubble-enter {
  582. // opacity: 0;
  583. // top: 1rem !important;
  584. // }
  585. // .bubble-enter-to {
  586. // opacity: 1;
  587. // top: 0 !important;
  588. // }
  589. // .bubble-enter-active {
  590. // transition: all 0.5s;
  591. // }
  592. // .bubble-leave {
  593. // opacity: 1;
  594. // top: 0 !important;
  595. // }
  596. // .bubble-leave-to {
  597. // opacity: 0;
  598. // top: -1rem !important;
  599. // }
  600. // .bubble-leave-active {
  601. // transition: all 0.5s;
  602. // }
  603. </style>