Hot.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. <template>
  2. <div class="Hot" :class="{ active: show }" @click.stop="">
  3. <div class="close" @click="$emit('hotClose')">
  4. <img src="../assets/img/hotClose.png" alt="" />
  5. </div>
  6. <!-- 查看图片 -->
  7. <viewer class="viewerCla" ref="viewer" :images="lookPics">
  8. <img :src="lookPics[0]" alt="" />
  9. </viewer>
  10. <!-- 轮播图 -->
  11. <div class="swBox">
  12. <div class="swiper-container" ref="mySwiper" :key="type">
  13. <div class="swiper-wrapper">
  14. <div class="swiper-slide" v-for="(item, index) in data" :key="index">
  15. <div
  16. class="infoTxt"
  17. :class="{ videoAc: type === 'video' }"
  18. v-if="item.title || hotIdOrName.name"
  19. >
  20. <h3>{{ hotIdOrName.name }}</h3>
  21. <div v-html="item.content" v-show="type !== 'video'"></div>
  22. </div>
  23. <!-- 图片 -->
  24. <template
  25. v-if="type === 'img' || type === '2d' || type === 'article'"
  26. >
  27. <img
  28. @click="
  29. lookImg(`${hotBaseUrl}${hotIdOrName.id}/${type}/${item.id}`)
  30. "
  31. v-lazy="`${hotBaseUrl}${hotIdOrName.id}/${type}/${item.id}`"
  32. alt=""
  33. />
  34. </template>
  35. <!-- 视频 -->
  36. <template v-else-if="type === 'video'">
  37. <div class="videoBox">
  38. <div>
  39. <!-- 线上开发加上 -->
  40. <!-- :src="`https://4dkk.4dage.com/scene_edit_data/${KKNum}/user/${item.media.video[0].src}`" -->
  41. <!-- 本地化加上 -->
  42. <!-- :src="`scene_view_data/${KKNum}/user/${item.media.video[0].src}`" -->
  43. <video
  44. v-if="item.media && item.media.video[0]"
  45. controls
  46. :src="`https://4dkk.4dage.com/scene_edit_data/${KKNum}/user/${item.media.video[0].src}`"
  47. ></video>
  48. </div>
  49. </div>
  50. </template>
  51. <!-- 模型 -->
  52. <template v-else-if="type === 'link'">
  53. <!-- 线上开发加上 -->
  54. <!-- :src="item.media.link[0].src" -->
  55. <!-- 本地化加上 -->
  56. <!-- :src="item.media.link[0].src.replace('https://4dscene.4dage.com/culturalrelics','')" -->
  57. <div class="ifrBox">
  58. <iframe
  59. v-if="item.media && item.media.link[0]"
  60. :src="item.media.link[0].src"
  61. frameborder="0"
  62. ></iframe>
  63. </div>
  64. </template>
  65. <!-- 音乐 -->
  66. <template v-else>
  67. <!-- 线上开发加上 -->
  68. <!-- :audioSrc="`https://4dkk.4dage.com/scene_edit_data/${KKNum}/user/${item.media.audio[0].src}`" -->
  69. <!-- 本地化加上 -->
  70. <!-- :audioSrc="`scene_view_data/${KKNum}/user/${item.media.audio[0].src}`" -->
  71. <Audio
  72. :Aid="item.media.audio[0].src"
  73. v-if="item.media && item.media.audio[0] && audioIndex === index"
  74. :audioSrc="`https://4dkk.4dage.com/scene_edit_data/${KKNum}/user/${item.media.audio[0].src}`"
  75. />
  76. </template>
  77. </div>
  78. </div>
  79. <div class="swiper-pagination" v-show="data.length > 1"></div>
  80. <div
  81. class="swiper-button-prev swiper-button-white"
  82. v-show="data.length > 1"
  83. :class="{ noneAc: true }"
  84. ></div>
  85. <div
  86. class="swiper-button-next swiper-button-white"
  87. v-show="data.length > 1"
  88. :class="{ noneAc: true }"
  89. ></div>
  90. </div>
  91. </div>
  92. <!-- 查看图片的详细名称 -->
  93. <div
  94. class="imgNameBox"
  95. v-show="type === 'img'"
  96. :class="{ hideImgNameBox: !imgNameBox }"
  97. >
  98. <div class="imgNameBox_Row">
  99. <div
  100. @click="cutNameFu(index)"
  101. class="row"
  102. :class="{ rowAc: index === imgInd }"
  103. :title="item.name"
  104. v-for="(item, index) in data"
  105. :key="item.id"
  106. >
  107. {{ item.name }}
  108. </div>
  109. </div>
  110. <!-- 收起按钮 -->
  111. <div class="hideName" @click="imgNameBox = false">
  112. <i class="el-icon-caret-right"></i>
  113. </div>
  114. </div>
  115. <!-- 右下角的按钮 -->
  116. <div class="mainrr">
  117. <div
  118. class="row"
  119. v-show="item.show"
  120. v-for="item in rightList"
  121. :key="item.id"
  122. @click="type = item.type"
  123. :class="{ active: item.type === type }"
  124. >
  125. <img
  126. :src="
  127. require(`@/assets/img/Hot/inco${item.id}${
  128. item.type === type ? 'Ac' : ''
  129. }.png`)
  130. "
  131. alt=""
  132. />
  133. <!-- 图片类型才有的展开按钮 -->
  134. <div
  135. class="showName"
  136. v-show="item.type === 'img' && !imgNameBox"
  137. @click="imgNameBox = true"
  138. >
  139. <i class="el-icon-caret-top"></i>
  140. </div>
  141. <p>
  142. {{ item.name }}{{ info[item.type] && info[item.type].length
  143. }}{{ myinfo[item.type] && myinfo[item.type].length }}
  144. </p>
  145. </div>
  146. </div>
  147. </div>
  148. </template>
  149. <script>
  150. import { hotData, hotBaseUrl } from "./data";
  151. // 过滤不显示的 数据
  152. const hotDataRes = [...hotData];
  153. hotDataRes.forEach((v) => {
  154. if (v["img"] && v["img"].length) {
  155. v["img"] = v["img"].filter((v) => !v.show);
  156. }
  157. if (v["2d"] && v["2d"].length) {
  158. v["2d"] = v["2d"].filter((v) => !v.show);
  159. }
  160. if (v["article"] && v["article"].length) {
  161. v["article"] = v["article"].filter((v) => !v.show);
  162. }
  163. });
  164. // console.log("----------", hotDataRes);
  165. import Audio from "./Audio.vue";
  166. import Swiper from "./swiper.js";
  167. export default {
  168. props: {
  169. info: {
  170. type: Object,
  171. default: () => {},
  172. },
  173. hotIdOrName: {
  174. type: Object,
  175. default: () => {},
  176. },
  177. },
  178. name: "Hot",
  179. components: { Audio },
  180. data() {
  181. //这里存放数据
  182. return {
  183. hotBaseUrl, //热点图片的前缀 url
  184. lookPics: [],
  185. show: false,
  186. data: [],
  187. type: "",
  188. rightList: [
  189. { name: "三维", id: 2, show: false, type: "link" },
  190. { name: "二维", id: 5, show: false, type: "2d" },
  191. { name: "音频", id: 3, show: false, type: "audio" },
  192. { name: "视频", id: 1, show: false, type: "video" },
  193. // 定制化
  194. { name: "文章", id: 6, show: false, type: "article" },
  195. { name: "图片", id: 4, show: false, type: "img" },
  196. ],
  197. Swiper: null,
  198. KKNum: window.KKNum,
  199. audioIndex: 0,
  200. myinfo: {},
  201. imgInd: 0,
  202. imgNameBox: true,
  203. };
  204. },
  205. //监听属性 类似于data概念
  206. computed: {},
  207. //监控data中的数据变化
  208. watch: {
  209. type(val) {
  210. // console.log('-----------',val);
  211. if (val === "video") {
  212. this.$nextTick(() => {
  213. setTimeout(() => {
  214. let videoDoms = document.querySelectorAll(".Hot video");
  215. videoDoms[0].play();
  216. }, 200);
  217. });
  218. } else if (val === "audio") this.audioIndex = 0;
  219. this.Swiper = null;
  220. // 定制化
  221. this.imgInd = 0;
  222. this.imgNameBox = true;
  223. const flag = ["img", "2d", "article"];
  224. if (flag.includes(val)) {
  225. this.data = this.myinfo[val];
  226. } else this.data = this.info[val];
  227. this.$nextTick(() => {
  228. setTimeout(() => {
  229. this.Swiper = new Swiper(".Hot .swiper-container", {
  230. slidesPerView: 1,
  231. // 如果需要前进后退按钮
  232. navigation: {
  233. nextEl: ".swiper-button-next",
  234. prevEl: ".swiper-button-prev",
  235. },
  236. pagination: {
  237. el: ".swiper-pagination",
  238. type: "fraction",
  239. },
  240. on: {
  241. slideChange: () => {
  242. if (val === "video") {
  243. let dom = document.querySelectorAll(
  244. ".Hot .swiper-pagination-bullet"
  245. );
  246. let index;
  247. dom.forEach((v, i) => {
  248. if (v.className.includes("swiper-pagination-bullet-active"))
  249. index = i;
  250. });
  251. this.$nextTick(() => {
  252. setTimeout(() => {
  253. let videoDoms = document.querySelectorAll(".Hot video");
  254. videoDoms.forEach((v, i) => {
  255. if (i === index) v.play();
  256. else v.pause();
  257. });
  258. }, 200);
  259. });
  260. }
  261. if (val === "audio") this.audioIndex = this.Swiper.activeIndex;
  262. if (flag.includes(val)) {
  263. this.imgInd = this.Swiper.activeIndex;
  264. }
  265. },
  266. },
  267. });
  268. }, 100);
  269. });
  270. },
  271. info: {
  272. handler(val) {
  273. // 通过id获取配置化信息
  274. // console.log("------------------------", this.hotIdOrName);
  275. const myinfo = hotDataRes.find((v) => v.hotId === this.hotIdOrName.id);
  276. this.info = val;
  277. let obj = {
  278. video: 3,
  279. link: 0,
  280. audio: 2,
  281. image: 5,
  282. };
  283. for (const k in val) {
  284. if (val[k].length) this.rightList[obj[k]].show = true;
  285. }
  286. // 定制化
  287. if (myinfo) {
  288. this.myinfo = myinfo;
  289. if (myinfo.img && myinfo.img.length) this.rightList[5].show = true;
  290. if (myinfo["2d"] && myinfo["2d"].length)
  291. this.rightList[1].show = true;
  292. if (myinfo["article"] && myinfo["article"].length)
  293. this.rightList[4].show = true;
  294. }
  295. if (val["link"] && val["link"].length) this.type = "link";
  296. else if (myinfo && myinfo["2d"] && myinfo["2d"].length)
  297. this.type = "2d";
  298. else if (val["audio"] && val["audio"].length) this.type = "audio";
  299. else if (val["video"] && val["video"].length) this.type = "video";
  300. else if (myinfo && myinfo["article"] && myinfo["article"].length)
  301. this.type = "article";
  302. else if (myinfo && myinfo.img && myinfo.img.length) this.type = "img";
  303. // if (val["image"] && val["image"].length) this.type = "image";
  304. },
  305. immediate: true,
  306. },
  307. },
  308. //方法集合
  309. methods: {
  310. // 点击查看大图
  311. lookImg(url) {
  312. let dom = this.$refs.viewer.$viewer;
  313. this.lookPics = [url];
  314. dom.show();
  315. },
  316. // 点击右下角 的 名字 切换轮播图
  317. cutNameFu(index) {
  318. if (this.imgInd === index) return;
  319. // console.log('----------');
  320. this.Swiper.slideTo(index);
  321. },
  322. },
  323. //生命周期 - 创建完成(可以访问当前this实例)
  324. created() {},
  325. //生命周期 - 挂载完成(可以访问DOM元素)
  326. mounted() {
  327. setTimeout(() => {
  328. this.show = true;
  329. }, 300);
  330. // 如果有对应的点位音频,删除
  331. this.$nextTick(() => {
  332. let time = -1;
  333. let num = 0;
  334. time = window.setInterval(() => {
  335. const dotAudioDomId = document.querySelector("#dotAudioDomId");
  336. num++;
  337. // console.log("xxxxxxxxxxxx", dotAudioDomId);
  338. if (dotAudioDomId) {
  339. clearInterval(time);
  340. document.body.removeChild(dotAudioDomId);
  341. }
  342. if (num >= 5) clearInterval(time);
  343. }, 800);
  344. });
  345. },
  346. beforeCreate() {}, //生命周期 - 创建之前
  347. beforeMount() {}, //生命周期 - 挂载之前
  348. beforeUpdate() {}, //生命周期 - 更新之前
  349. updated() {}, //生命周期 - 更新之后
  350. beforeDestroy() {}, //生命周期 - 销毁之前
  351. destroyed() {}, //生命周期 - 销毁完成
  352. activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
  353. };
  354. </script>
  355. <style lang='less' scoped>
  356. @import "./swiper.css";
  357. .viewerCla img {
  358. display: none;
  359. }
  360. .Hot {
  361. opacity: 0.3;
  362. pointer-events: none;
  363. transition: opacity 0.3s;
  364. position: absolute;
  365. top: 0;
  366. left: 0;
  367. z-index: 99;
  368. width: 100%;
  369. height: 100%;
  370. background-color: rgba(255, 251, 245, 0.9);
  371. backdrop-filter: blur(4px);
  372. .close {
  373. cursor: pointer;
  374. width: 60px;
  375. position: absolute;
  376. z-index: 10;
  377. top: 45px;
  378. right: 45px;
  379. img {
  380. width: 60px;
  381. }
  382. }
  383. .mainrr {
  384. display: flex;
  385. position: absolute;
  386. bottom: 15px;
  387. right: 20px;
  388. z-index: 10;
  389. .row {
  390. position: relative;
  391. cursor: pointer;
  392. width: 50px;
  393. text-align: center;
  394. margin-left: 15px;
  395. color: #666666;
  396. & > img {
  397. width: 50px;
  398. }
  399. p {
  400. font-size: 12px;
  401. }
  402. .likeMove {
  403. color: #930909;
  404. position: absolute;
  405. top: 10px;
  406. width: 100%;
  407. text-align: center;
  408. }
  409. }
  410. .active {
  411. color: #930909;
  412. font-weight: 700;
  413. p {
  414. font-size: 12px;
  415. }
  416. }
  417. .showName {
  418. position: absolute;
  419. z-index: 998;
  420. top: -20px;
  421. left: 5px;
  422. width: 40px;
  423. height: 40px;
  424. display: flex;
  425. justify-content: center;
  426. cursor: pointer;
  427. }
  428. }
  429. .swBox {
  430. position: absolute;
  431. top: 0;
  432. left: 0;
  433. width: 100%;
  434. height: 100%;
  435. .swiper-container {
  436. cursor: grab;
  437. height: 100%;
  438. .swiper-slide {
  439. position: relative;
  440. .infoTxt {
  441. z-index: 10;
  442. position: absolute;
  443. top: 40px;
  444. left: 40px;
  445. width: 310px;
  446. & > h3 {
  447. font-size: 20px;
  448. color: #930909;
  449. font-weight: 700;
  450. line-height: 28px;
  451. margin-bottom: 15px;
  452. }
  453. & > div {
  454. color: #666666;
  455. font-size: 16px;
  456. }
  457. }
  458. .videoAc {
  459. pointer-events: none;
  460. width: 1200px;
  461. height: 680px;
  462. position: absolute;
  463. top: 50%;
  464. left: 50%;
  465. transform: translate(-50%, -50%);
  466. padding: 74px 0 0 140px;
  467. z-index: 30;
  468. h3 {
  469. color: #ffffff;
  470. }
  471. }
  472. .videoBox {
  473. width: 1200px;
  474. height: 680px;
  475. position: absolute;
  476. top: 50%;
  477. left: 50%;
  478. transform: translate(-50%, -50%);
  479. background-image: url("../assets/img/Hot/videoBac.png");
  480. background-size: 100% 100%;
  481. padding: 135px 90px 0 140px;
  482. & > div {
  483. width: 100%;
  484. height: 100%;
  485. overflow: hidden;
  486. video {
  487. height: 100%;
  488. width: 100%;
  489. }
  490. }
  491. }
  492. .ifrBox {
  493. position: absolute;
  494. top: 0;
  495. left: 0;
  496. width: 100%;
  497. height: 100%;
  498. overflow: hidden;
  499. iframe {
  500. width: 100%;
  501. height: 100%;
  502. }
  503. }
  504. img {
  505. cursor: pointer;
  506. position: absolute;
  507. top: 50%;
  508. left: 50%;
  509. transform: translate(-50%, -50%);
  510. max-width: 900px;
  511. max-height: 700px;
  512. object-fit: cover;
  513. }
  514. }
  515. .swiper-pagination {
  516. bottom: 50px;
  517. }
  518. .swiper-button-next {
  519. // opacity: 1;
  520. // pointer-events: auto;
  521. width: 40px;
  522. height: 60px;
  523. right: 60px;
  524. background-image: url("../assets/img/Hot/right.png");
  525. background-size: 100% 100%;
  526. color: transparent;
  527. }
  528. .swiper-button-prev {
  529. // opacity: 1;
  530. // pointer-events: auto;
  531. width: 40px;
  532. height: 60px;
  533. left: 60px;
  534. background-image: url("../assets/img/Hot/left.png");
  535. background-size: 100% 100%;
  536. color: transparent;
  537. }
  538. /deep/.swiper-pagination-bullet {
  539. width: 70px;
  540. height: 4px;
  541. border-radius: 1px;
  542. opacity: 1;
  543. background-color: #999999;
  544. }
  545. /deep/.swiper-pagination-bullet-active {
  546. background-color: #930909;
  547. }
  548. }
  549. }
  550. .imgNameBox {
  551. opacity: 1;
  552. transition: all 0.3s;
  553. position: absolute;
  554. z-index: 998;
  555. width: 400px;
  556. padding: 10px 0px 20px 30px;
  557. right: 0;
  558. bottom: 100px;
  559. background-color: #930909;
  560. // background-image: url("../assets/img/Hot/nameBac.png");
  561. // background-size: 100% 100%;
  562. border-radius: 6px;
  563. max-height: 700px;
  564. .imgNameBox_Row {
  565. padding-right: 20px;
  566. width: 100%;
  567. height: 100%;
  568. max-height: 640px;
  569. overflow-y: auto;
  570. &::-webkit-scrollbar {
  571. /*滚动条整体样式*/
  572. width: 5px;
  573. /*高宽分别对应横竖滚动条的尺寸*/
  574. height: 1px;
  575. }
  576. &::-webkit-scrollbar-thumb {
  577. /*滚动条里面小方块*/
  578. border-radius: 1px;
  579. -webkit-box-shadow: inset 0 0 5px transparent;
  580. background: #d8b275;
  581. }
  582. &::-webkit-scrollbar-track {
  583. /*滚动条里面轨道*/
  584. -webkit-box-shadow: inset 0 0 5px transparent;
  585. border-radius: 10px;
  586. background: transparent;
  587. }
  588. .row {
  589. width: 100%;
  590. overflow: hidden;
  591. text-overflow: ellipsis;
  592. white-space: nowrap;
  593. color: #fff;
  594. height: 50px;
  595. line-height: 49px;
  596. cursor: pointer;
  597. border-bottom: 1px solid #fff;
  598. &:hover {
  599. color: #d8b275;
  600. }
  601. }
  602. .rowAc {
  603. color: #d8b275;
  604. // pointer-events: none;
  605. }
  606. }
  607. .hideName {
  608. position: absolute;
  609. z-index: 9999;
  610. cursor: pointer;
  611. top: 50%;
  612. left: 0;
  613. transform: translateY(-50%);
  614. width: 40px;
  615. height: 40px;
  616. border-radius: 50%;
  617. display: flex;
  618. align-items: center;
  619. font-size: 20px;
  620. color: yellow;
  621. }
  622. }
  623. .hideImgNameBox {
  624. opacity: 0;
  625. right: -400px;
  626. }
  627. }
  628. .active {
  629. opacity: 1;
  630. pointer-events: auto;
  631. }
  632. </style>