Hot.vue 15 KB

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