Home.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <template>
  2. <div class="home">
  3. <div class="main">
  4. <div class="mainCon" v-show="!oneTxt">
  5. <audio
  6. id="myAudio"
  7. v-if="audio"
  8. v-show="isOneAduio"
  9. :src="audio"
  10. controls
  11. ></audio>
  12. <!-- 音频图标 -->
  13. <div
  14. class="audioIcon"
  15. v-if="audio && !isOneAduio"
  16. @click="audioSta = !audioSta"
  17. :title="audioSta ? '关闭音频' : '打开音频'"
  18. >
  19. <img
  20. :src="
  21. require(`@/assets/images/pc/audio${audioSta ? 'Ac' : ''}.png`)
  22. "
  23. alt=""
  24. />
  25. </div>
  26. <!-- 底部的tab -->
  27. <div class="flooTabBox" v-if="flooTab.length > 1">
  28. <div
  29. @click="myType = item.type"
  30. class="tabRow"
  31. :class="{ tabRowAc: myType === item.type }"
  32. v-for="item in flooTab"
  33. :key="item.id"
  34. >
  35. <img
  36. :src="
  37. require(`@/assets/images/pc/icon${item.id}${
  38. myType === item.type ? 'Ac' : ''
  39. }.png`)
  40. "
  41. alt=""
  42. />
  43. {{ item.name }}
  44. <span
  45. v-if="
  46. data[item.type] &&
  47. data[item.type].length &&
  48. data[item.type].length > 1
  49. "
  50. >{{ item.type === myType ? myInd + 1 + "/" : null
  51. }}{{ data[item.type].length }}</span
  52. >
  53. </div>
  54. </div>
  55. <!-- 主要内容 -->
  56. <div class="contenBoxMain">
  57. <div
  58. class="contenBox"
  59. :class="{ contenBoxAc: index === myInd }"
  60. v-for="(item, index) in data[myType]"
  61. :key="myType === 'video' ? item.url : item"
  62. >
  63. <!-- 模型页面 -->
  64. <div class="modelBox" v-if="myType === 'model'">
  65. <iframe
  66. :src="item"
  67. frameborder="0"
  68. v-if="index === myInd"
  69. ></iframe>
  70. </div>
  71. <!-- 视频页面 -->
  72. <div class="videoBox" v-else-if="myType === 'video'">
  73. <video controls :src="item.url" v-if="index === myInd"></video>
  74. </div>
  75. <!-- 图片页面 -->
  76. <div class="imgBox" v-else-if="myType === 'img'">
  77. <div class="smImgBox" @click="lookImg(item)">
  78. <img v-lazy="item" alt="" />
  79. </div>
  80. </div>
  81. </div>
  82. <!-- 左右箭头 -->
  83. <div
  84. @click="cutMyInd(-1, myInd === 0)"
  85. class="leftJJ awccJJ"
  86. :class="{ noClick: myInd === 0 }"
  87. v-if="data[myType] && data[myType].length > 1"
  88. ></div>
  89. <div
  90. @click="cutMyInd(1, myInd === data[myType].length - 1)"
  91. class="rightJJ awccJJ"
  92. :class="{ noClick: myInd === data[myType].length - 1 }"
  93. v-if="data[myType] && data[myType].length > 1"
  94. ></div>
  95. </div>
  96. </div>
  97. <!-- 下面的文字介绍 -->
  98. <div class="flooTxt" :class="{ flooTxtOne: oneTxt }">
  99. <div class="flooTxtBox">
  100. <div class="myTitle">{{ myTitle }}</div>
  101. <!-- 视频的介绍 -->
  102. <div class="myTxt" v-if="myType === 'video' && videoTxt[myInd]">
  103. {{ videoTxt[myInd] }}
  104. </div>
  105. <div class="myTxt" v-if="myType === 'img' && imgTxt[myInd]">
  106. {{ imgTxt[myInd] }}
  107. </div>
  108. <div class="myTxt" v-html="myTxt"></div>
  109. </div>
  110. </div>
  111. </div>
  112. <!-- 查看图片 -->
  113. <viewer class="viewerCla" ref="viewer" :images="lookPics">
  114. <img :src="lookPics[0]" alt="" />
  115. </viewer>
  116. </div>
  117. </template>
  118. <script>
  119. export default {
  120. name: "Home",
  121. data() {
  122. return {
  123. m: this.$route.query.m,
  124. id: this.$route.query.id,
  125. // 音频地址
  126. audio: "",
  127. // 如果只有单独的音频
  128. isOneAduio: false,
  129. // 音频状态
  130. audioSta: false,
  131. data: {
  132. // 模型数组
  133. model: [],
  134. // 视频数组
  135. video: [],
  136. // 图片数组
  137. img: [],
  138. },
  139. // 当前 type
  140. myType: "",
  141. // 底部的tab
  142. flooTab: [],
  143. // 当前索引
  144. myInd: 0,
  145. // 查看图片
  146. lookPics: [],
  147. // 标题
  148. myTitle: "",
  149. // 内容
  150. myTxt: "",
  151. // 视频内容
  152. videoTxt: [],
  153. imgTxt: [],
  154. // 只有标题和文字(没有视频,没有模型,没有图片)
  155. oneTxt: false,
  156. };
  157. },
  158. watch: {
  159. myType() {
  160. this.myInd = 0;
  161. },
  162. // 音频的开启和关闭
  163. audioSta(val) {
  164. const dom = document.querySelector("#myAudio");
  165. if (val) {
  166. dom.play();
  167. dom.onended = () => {
  168. // console.log("----音频播放完毕");
  169. this.audioSta = false;
  170. };
  171. } else dom.pause();
  172. },
  173. },
  174. computed: {},
  175. components: {},
  176. methods: {
  177. // 点击左右箭头
  178. cutMyInd(num, flag) {
  179. if (flag) return;
  180. this.myInd += num;
  181. },
  182. // 点击查看大图
  183. lookImg(url) {
  184. let dom = this.$refs.viewer.$viewer;
  185. this.lookPics = [url];
  186. dom.show();
  187. },
  188. async getData() {
  189. // https://www.4dmodel.com/
  190. let url = `https://super.4dage.com/data/${
  191. this.id
  192. }/hot/js/data.js?time=${Math.random()}`;
  193. let result = (await this.$http.get(url)).data;
  194. const resData = result[this.m];
  195. console.log("----", resData);
  196. if (resData) {
  197. this.audio = resData.backgroundMusic;
  198. // 只有单独的音频上传
  199. if (
  200. resData.backgroundMusic &&
  201. !resData.model &&
  202. !resData.video &&
  203. !resData.images
  204. ) {
  205. this.isOneAduio = true;
  206. }
  207. // 底部的tab
  208. const arr = [];
  209. const obj = {};
  210. if (resData.model) {
  211. obj.model = resData.model;
  212. arr.push({ id: 1, type: "model", name: "模型" });
  213. }
  214. if (resData.video) {
  215. obj.video = resData.video;
  216. arr.push({ id: 2, type: "video", name: "视频" });
  217. }
  218. if (resData.images) {
  219. obj.img = resData.images;
  220. arr.push({ id: 3, type: "img", name: "图片" });
  221. }
  222. this.flooTab = arr;
  223. this.data = obj;
  224. // 当前type的值 应该为
  225. if (resData.model) this.myType = "model";
  226. else if (resData.video) this.myType = "video";
  227. else if (resData.images) this.myType = "img";
  228. this.myTitle = resData.title || "";
  229. this.myTxt = resData.content || "";
  230. this.videoTxt = resData.videosDesc || [];
  231. this.imgTxt = resData.imagesDesc || [];
  232. // 只有 标题和 文字介绍(没有视频,没有模型,没有图片)
  233. if (!obj.model && !obj.video && !obj.img && !resData.backgroundMusic) {
  234. this.oneTxt = true;
  235. }
  236. }
  237. },
  238. },
  239. mounted() {
  240. this.getData();
  241. },
  242. };
  243. </script>
  244. <style lang="less" scoped>
  245. .home {
  246. .viewerCla img {
  247. display: none;
  248. }
  249. width: 100%;
  250. height: 100%;
  251. background-color: rgba(255, 252, 247, 0.6);
  252. backdrop-filter: blur(10px);
  253. position: relative;
  254. #myAudio {
  255. z-index: 11;
  256. position: absolute;
  257. top: 50%;
  258. left: 50%;
  259. transform: translate(-50%, -50%);
  260. width: 500px;
  261. height: 60px;
  262. }
  263. .main {
  264. width: 1200px;
  265. margin: 0 auto;
  266. height: 100%;
  267. padding-top: 40px;
  268. .mainCon {
  269. position: relative;
  270. border-radius: 6px;
  271. overflow: hidden;
  272. width: 100%;
  273. height: calc(100% - 200px);
  274. background: linear-gradient(#929292, #c5c5c5);
  275. .audioIcon {
  276. z-index: 10;
  277. cursor: pointer;
  278. position: absolute;
  279. right: 20px;
  280. bottom: 30px;
  281. }
  282. .flooTabBox {
  283. z-index: 10;
  284. position: absolute;
  285. bottom: 30px;
  286. left: 50%;
  287. transform: translateX(-50%);
  288. display: flex;
  289. .tabRow {
  290. cursor: pointer;
  291. display: flex;
  292. align-items: center;
  293. margin: 0 12px;
  294. font-size: 12px;
  295. background-color: #dedede;
  296. padding: 0px 14px;
  297. height: 36px;
  298. border-radius: 18px;
  299. & > img {
  300. margin-right: 6px;
  301. }
  302. }
  303. .tabRowAc {
  304. background-color: #b90c0c;
  305. pointer-events: none;
  306. color: #d6b970;
  307. }
  308. }
  309. .contenBoxMain {
  310. position: relative;
  311. width: 100%;
  312. height: 100%;
  313. }
  314. .contenBox {
  315. width: 100%;
  316. height: 100%;
  317. position: absolute;
  318. top: 0;
  319. left: 0;
  320. opacity: 0;
  321. pointer-events: none;
  322. transition: all 0.3s;
  323. .modelBox,
  324. .videoBox,
  325. .imgBox {
  326. width: 100%;
  327. height: 100%;
  328. }
  329. .modelBox {
  330. iframe {
  331. width: 100%;
  332. height: 100%;
  333. }
  334. }
  335. .videoBox {
  336. padding: 100px 100px 120px;
  337. video {
  338. width: 100%;
  339. height: 100%;
  340. }
  341. }
  342. .imgBox {
  343. padding: 100px 100px 120px;
  344. .smImgBox {
  345. width: 100%;
  346. height: 100%;
  347. cursor: pointer;
  348. & > img {
  349. pointer-events: none;
  350. width: 100%;
  351. height: 100%;
  352. object-fit: contain;
  353. }
  354. }
  355. }
  356. }
  357. .contenBoxAc {
  358. opacity: 1;
  359. pointer-events: auto;
  360. }
  361. .awccJJ {
  362. cursor: pointer;
  363. position: absolute;
  364. top: 50%;
  365. transform: translateY(-50%);
  366. left: 10px;
  367. width: 37px;
  368. height: 37px;
  369. background-image: url("../assets/images/pc/left.png");
  370. background-size: 100% 100%;
  371. &:focus {
  372. outline: none;
  373. }
  374. }
  375. .rightJJ {
  376. left: auto;
  377. right: 10px;
  378. background-image: url("../assets/images/pc/right.png");
  379. }
  380. .noClick {
  381. cursor: default;
  382. opacity: 0.4;
  383. }
  384. }
  385. .flooTxt {
  386. margin-top: 20px;
  387. width: 100%;
  388. height: 160px;
  389. .flooTxtBox {
  390. width: 100%;
  391. height: 100%;
  392. overflow-y: auto;
  393. .myTitle {
  394. color: #b90c0c;
  395. font-size: 22px;
  396. font-weight: 700;
  397. margin-bottom: 10px;
  398. }
  399. .myTxt {
  400. font-size: 16px;
  401. color: #333333;
  402. line-height: 24px;
  403. }
  404. &::-webkit-scrollbar {
  405. /*滚动条整体样式*/
  406. width: 3px; /*高宽分别对应横竖滚动条的尺寸*/
  407. height: 1px;
  408. }
  409. &::-webkit-scrollbar-thumb {
  410. /*滚动条里面小方块*/
  411. border-radius: 10px;
  412. -webkit-box-shadow: inset 0 0 5px transparent;
  413. background: #b90c0c;
  414. }
  415. &::-webkit-scrollbar-track {
  416. /*滚动条里面轨道*/
  417. -webkit-box-shadow: inset 0 0 5px transparent;
  418. border-radius: 10px;
  419. background: transparent;
  420. }
  421. }
  422. }
  423. .flooTxtOne {
  424. height: 600px;
  425. }
  426. }
  427. }
  428. // 移动端
  429. @media screen and (max-width: 1000px) {
  430. .home {
  431. #myAudio {
  432. width: 90vw;
  433. max-width: 500px;
  434. }
  435. .main {
  436. width: 90%;
  437. height: 94%;
  438. padding: 0;
  439. position: absolute;
  440. top: 50%;
  441. left: 50%;
  442. transform: translate(-50%, -50%);
  443. .mainCon {
  444. border-radius: 8px 8px 0 0;
  445. .audioIcon {
  446. cursor: default;
  447. right: auto;
  448. bottom: auto;
  449. top: 6px;
  450. left: 6px;
  451. & > img {
  452. width: 30px;
  453. }
  454. }
  455. .flooTabBox {
  456. width: 100%;
  457. bottom: 20px;
  458. justify-content: center;
  459. .tabRow {
  460. cursor: default;
  461. margin: 0 6px;
  462. padding: 0 10px;
  463. height: 32px;
  464. & > img {
  465. width: 16px;
  466. }
  467. }
  468. }
  469. .contenBox {
  470. .videoBox {
  471. padding: 0px 0;
  472. position: relative;
  473. video {
  474. width: 96%;
  475. max-height: 100%;
  476. height: auto;
  477. position: absolute;
  478. top: 50%;
  479. left: 2%;
  480. transform: translateY(-50%);
  481. }
  482. }
  483. .imgBox {
  484. padding: 60px 50px 80px;
  485. .smImgBox {
  486. cursor: default;
  487. }
  488. }
  489. }
  490. .awccJJ {
  491. left: 0;
  492. width: 28px;
  493. height: 57px;
  494. cursor: default;
  495. background-image: url("../assets/images/pc/icon-left.png");
  496. }
  497. .rightJJ {
  498. left: auto;
  499. right: 0;
  500. background-image: url("../assets/images/pc/icon-right.png");
  501. }
  502. }
  503. .flooTxt {
  504. margin-top: 0;
  505. padding: 20px 15px 15px;
  506. height: 200px;
  507. background-color: #fff;
  508. border-radius: 0 0 8px 8px;
  509. .flooTxtBox {
  510. .myTitle {
  511. font-size: 18px;
  512. }
  513. .myTxt {
  514. font-size: 14px;
  515. line-height: 22px;
  516. }
  517. }
  518. }
  519. .flooTxtOne {
  520. height: 100%;
  521. }
  522. }
  523. }
  524. }
  525. </style>