HomeMobile.vue 15 KB

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