list.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. <template>
  2. <div class="list" :class="{ listHide: incoShow }">
  3. <div class="incoShow" @click="incoShow = !incoShow">
  4. <img src="../../assets/img/menu2.png" alt="" v-if="incoShow" />
  5. <img src="../../assets/img/menu.png" alt="" v-else />
  6. </div>
  7. <!-- 收起之后展开 -->
  8. <div class="topTitBox">
  9. <div
  10. class="oneLi"
  11. @click="handleTabone({ children: [1], id: 100, name: '航拍' }, 0)"
  12. :class="{ activeOne: 100 == taboneActive.id }"
  13. >
  14. 航拍全景
  15. </div>
  16. <div
  17. class="clip-scroller topTit"
  18. ref="sw2"
  19. v-swiper:mySwiperb="swiperOptions"
  20. v-if="showInfo.catalogRoot.length > 0 && showInfo.catalogs.length > 1"
  21. >
  22. <ul class="tap swiper-wrapper" v-if="showInfo.catalogRoot.length > 1">
  23. <li
  24. class="swiper-slide row"
  25. @click="handleTabone(item, i)"
  26. :class="{ active: item.id == taboneActive.id }"
  27. v-show="i !== 0"
  28. v-for="(item, i) in showInfo.catalogRoot"
  29. :key="i"
  30. >
  31. {{ item.name }}
  32. </li>
  33. </ul>
  34. </div>
  35. </div>
  36. <div class="listBac">
  37. <!-- 左右箭头 -->
  38. <div
  39. class="swiper-button-prev"
  40. slot="button-prev"
  41. v-show="scenes.length > 11"
  42. ></div>
  43. <div
  44. class="swiper-button-next"
  45. slot="button-next"
  46. v-show="scenes.length > 11"
  47. ></div>
  48. <div
  49. class="l-con"
  50. :class="showList ? 'active' : ''"
  51. v-if="
  52. !(
  53. showInfo.catalogRoot.length == 1 &&
  54. scenes.length == 1 &&
  55. showInfo.catalogs.length == 1
  56. )
  57. "
  58. >
  59. <div class="pic-con">
  60. <div
  61. class="clip-scroller"
  62. ref="sw"
  63. v-swiper:mySwiper="swiperOptions2"
  64. v-if="scenes.length > 0"
  65. >
  66. <ul class="pic-list swiper-wrapper">
  67. <li
  68. class="swiper-slide"
  69. :title="item.sceneTitle"
  70. @click="handleVR(item, i)"
  71. v-for="(item, i) in scenes"
  72. :key="i"
  73. >
  74. <div
  75. :data-value="i"
  76. :class="{
  77. active: selected.sceneCode == item.sceneCode && !MapShow,
  78. }"
  79. >
  80. <img :src="handleImg(item) + `?${Math.random()}`" alt="" />
  81. <RollName
  82. :offset="20"
  83. :active="selected.sceneCode == item.sceneCode && !MapShow"
  84. class="dWenZi"
  85. :myref="'subw' + item.id"
  86. :name="item.sceneTitle"
  87. />
  88. </div>
  89. </li>
  90. </ul>
  91. <div class="swiper-scrollbar"></div>
  92. </div>
  93. </div>
  94. </div>
  95. </div>
  96. <!-- 右下角的几个按钮 -->
  97. <div class="txtShowBtn2" @click="fullShow">
  98. <img
  99. :src="require(`@/assets/img/Goods/full${isFullscreen ? 'Ac' : ''}.png`)"
  100. alt=""
  101. />
  102. <p :class="{ acFull: isFullscreen }">全屏</p>
  103. </div>
  104. <!-- 左侧返回 -->
  105. <div class="backMap" v-show="!MapShow" @click="handleVrFuToSon">
  106. <img src="@/assets/img/Goods/back.png" alt="" />
  107. <p>返回</p>
  108. </div>
  109. </div>
  110. </template>
  111. <script>
  112. import { mapGetters } from "vuex";
  113. import config from "@/config";
  114. import RollName from "@/components/rollName";
  115. import { directive } from "vue-awesome-swiper";
  116. // import style (<= Swiper 5.x)
  117. import "swiper/css/swiper.css";
  118. let isW = window.innerWidth > 1400;
  119. export default {
  120. props: ["select", "hanpaiID", "MapShow"],
  121. components: { RollName },
  122. directives: {
  123. swiper: directive,
  124. },
  125. data() {
  126. return {
  127. isFullscreen: false,
  128. incoShow: false,
  129. taboneActive: { children: [] },
  130. tabtowActive: "",
  131. childTab: [],
  132. scenes: [],
  133. showList: true,
  134. isW,
  135. loadFirst: true,
  136. menuWidth: 0,
  137. sceneNum: config.sceneNum,
  138. SlyArr: [],
  139. goBackArr: [],
  140. goBackInd: null,
  141. };
  142. },
  143. computed: {
  144. ...mapGetters({
  145. showInfo: "showInfo",
  146. }),
  147. selected() {
  148. return { ...this.select };
  149. },
  150. swiperOptions() {
  151. return {
  152. slidesPerView: "auto",
  153. centeredSlides: true,
  154. centerInsufficientSlides: true,
  155. centeredSlidesBounds: true,
  156. freeMode: true,
  157. };
  158. },
  159. swiperOptions2() {
  160. return {
  161. slidesPerView: "auto",
  162. centeredSlides: true,
  163. centerInsufficientSlides: true,
  164. centeredSlidesBounds: true,
  165. freeMode: true,
  166. navigation: {
  167. prevEl: ".swiper-button-prev",
  168. nextEl: ".swiper-button-next",
  169. },
  170. scrollbar: {
  171. el: ".swiper-scrollbar",
  172. },
  173. };
  174. },
  175. },
  176. methods: {
  177. // 从倾斜摄影进来
  178. incoShowClose() {
  179. this.incoShow = true;
  180. },
  181. // 点击全屏
  182. fullShow() {
  183. let element = document.documentElement;
  184. if (this.isFullscreen) {
  185. if (document.exitFullscreen) {
  186. document.exitFullscreen();
  187. } else if (document.webkitCancelFullScreen) {
  188. document.webkitCancelFullScreen();
  189. } else if (document.mozCancelFullScreen) {
  190. document.mozCancelFullScreen();
  191. } else if (document.msExitFullscreen) {
  192. document.msExitFullscreen();
  193. }
  194. } else {
  195. if (element.requestFullscreen) {
  196. element.requestFullscreen();
  197. } else if (element.webkitRequestFullScreen) {
  198. element.webkitRequestFullScreen();
  199. } else if (element.mozRequestFullScreen) {
  200. element.mozRequestFullScreen();
  201. } else if (element.msRequestFullscreen) {
  202. element.msRequestFullscreen();
  203. }
  204. }
  205. // 改变当前全屏状态
  206. this.isFullscreen = !this.isFullscreen;
  207. },
  208. handleImg(item) {
  209. let url = "";
  210. if (item.type == "4dkk") {
  211. url = `local/4dkk/${item.sceneCode}/wwwroot/images/images${item.sceneCode}/thumbSmallImg.jpg`;
  212. } else {
  213. if (item.icon.indexOf("preview.jpg") > -1) {
  214. url = item.icon.replace(
  215. "https://4dkk.4dage.com/720yun_fd_manage/image/",
  216. `${this.$cdn}local/pano/${item.sceneCode}/`
  217. );
  218. } else {
  219. url = item.icon.replace(
  220. "https://4dkk.4dage.com/720yun_fd_manage/image/",
  221. `${this.$cdn}local/pano/images/`
  222. );
  223. }
  224. }
  225. return url || item.icon;
  226. },
  227. // 给父组件调用控制轮播图的位置
  228. changeSwInd(index) {
  229. this.$refs.sw.swiper.slideTo(index);
  230. },
  231. handleTabone(item, i = null) {
  232. this.taboneActive = item;
  233. // 把底部轮播图回到起点
  234. this.$refs.sw.swiper.slideTo(0);
  235. // 让自己保持居中
  236. this.$refs.sw2.swiper.slideTo(i);
  237. },
  238. handleVrFuToSon() {
  239. if (!this.goBackArr[0].ind) {
  240. // 返回地图页面
  241. this.$emit("openMapShpw");
  242. this.goBackInd=null
  243. } else {
  244. let code = this.goBackArr[0].code;
  245. let ind = this.goBackArr[0].ind;
  246. this.$refs.sw.swiper.slideTo(ind);
  247. history.replaceState(
  248. null,
  249. null,
  250. ""
  251. .concat(window.location.pathname, "?")
  252. .concat(`id=${this.showInfo.id}&vr=${code}`)
  253. );
  254. this.sceneNum = code;
  255. this.goBackArr = this.goBackArr.filter((v, i) => i !== 0);
  256. }
  257. },
  258. handleVR(item, i = null) {
  259. this.goBackArr = this.goBackArr.filter((v) => v.ind !== this.goBackInd);
  260. this.goBackArr.unshift({ code: this.sceneNum, ind: this.goBackInd });
  261. console.log("--------111", this.goBackArr);
  262. this.goBackInd = i;
  263. if (i !== null) {
  264. this.$refs.sw.swiper.slideTo(i);
  265. this.$emit("mapClose");
  266. }
  267. history.replaceState(
  268. null,
  269. null,
  270. ""
  271. .concat(window.location.pathname, "?")
  272. .concat(`id=${this.showInfo.id}&vr=${item.sceneCode}`)
  273. );
  274. this.sceneNum = item.sceneCode;
  275. },
  276. },
  277. mounted() {
  278. // 监听esc事件
  279. document.addEventListener("webkitfullscreenchange", (e) => {
  280. if (!e.currentTarget.webkitIsFullScreen) this.isFullscreen = false;
  281. });
  282. document.addEventListener("fullscreenchange", (e) => {
  283. if (!document.fullscreenElement) this.isFullscreen = false;
  284. });
  285. document.addEventListener("MSFullscreenChange", (e) => {
  286. if (!document.msFullscreenElement) this.isFullscreen = false;
  287. });
  288. document.addEventListener("mozfullscreenchange", (e) => {
  289. if (!document.mozFullScreenElement) this.isFullscreen = false;
  290. });
  291. },
  292. watch: {
  293. taboneActive: {
  294. handler: function (newVal) {
  295. let temp = [];
  296. newVal.children &&
  297. newVal.children.forEach((item) => {
  298. this.showInfo.catalogs.forEach((sub) => {
  299. if (item == sub.id) {
  300. temp.push(sub);
  301. }
  302. });
  303. });
  304. this.childTab = temp;
  305. if (!this.loadFirst) {
  306. this.tabtowActive = "";
  307. }
  308. },
  309. },
  310. tabtowActive: {
  311. deep: true,
  312. handler: function (newVal) {
  313. if (!newVal) {
  314. this.tabtowActive = this.childTab[0];
  315. } else {
  316. let arr = this.showInfo.scenes.filter((item) => {
  317. return newVal.id == item.category;
  318. });
  319. this.scenes = arr.sort((a, b) => a.weight - b.weight);
  320. }
  321. },
  322. },
  323. sceneNum: {
  324. deep: true,
  325. immediate: true,
  326. handler: function (newVal) {
  327. if (!newVal) {
  328. let tmp = this.showInfo.firstScene || this.showInfo.scenes[0];
  329. // this.handleVR(tmp);
  330. return;
  331. }
  332. let val = this.showInfo.scenes.find((item) => item.sceneCode == newVal);
  333. let tmp = this.showInfo.catalogs.find(
  334. (item) => item.id == val.category
  335. );
  336. let rootTmp = this.showInfo.catalogRoot.find((item) => {
  337. return item.children.indexOf(tmp.id) > -1;
  338. });
  339. this.taboneActive = rootTmp;
  340. this.tabtowActive = tmp;
  341. setTimeout(() => {
  342. this.$emit("select", val);
  343. this.loadFirst = false;
  344. });
  345. },
  346. },
  347. selected: {
  348. handler: function (newVal) {
  349. // this.handleVR(newVal);
  350. if (newVal.type == "4dkk") {
  351. this.showList = false;
  352. }
  353. },
  354. },
  355. },
  356. created() {},
  357. };
  358. </script>
  359. <style lang="less" scoped>
  360. .backMap {
  361. color: #333333;
  362. position: fixed;
  363. z-index: 97;
  364. top: 35px;
  365. left: 30px;
  366. cursor: pointer;
  367. width: 50px;
  368. text-align: center;
  369. & > img {
  370. width: 50px;
  371. }
  372. }
  373. .txtShowBtn2 {
  374. position: fixed;
  375. z-index: 15;
  376. top: 35px;
  377. right: 30px;
  378. color: #333333;
  379. width: 50px;
  380. cursor: pointer;
  381. background-size: 100% 100%;
  382. & > img {
  383. width: 100%;
  384. }
  385. .acFull {
  386. color: #930909;
  387. }
  388. }
  389. .list {
  390. transition: bottom 0.5s;
  391. position: absolute;
  392. bottom: 0px;
  393. left: 0;
  394. z-index: 99;
  395. text-align: center;
  396. width: 100%;
  397. height: 200px;
  398. background-color: rgba(234, 229, 211, 0.9);
  399. &::before {
  400. content: "";
  401. position: absolute;
  402. top: -40px;
  403. left: 50%;
  404. transform: translateX(-50%);
  405. width: 80px;
  406. height: 40px;
  407. border-radius: 40px 40px 0 0;
  408. line-height: 40px;
  409. background-color: rgba(234, 229, 211, 0.9);
  410. }
  411. .incoShow {
  412. cursor: pointer;
  413. z-index: 20;
  414. position: absolute;
  415. left: 50%;
  416. transform: translateX(-50%);
  417. width: 40px;
  418. height: 40px;
  419. top: -36px;
  420. display: flex;
  421. justify-content: center;
  422. align-items: center;
  423. & > img {
  424. width: 20px;
  425. height: 18px;
  426. }
  427. }
  428. .topTitBox {
  429. color: #333333;
  430. max-width: 1000px;
  431. z-index: 10;
  432. position: absolute;
  433. top: 7px;
  434. left: 50%;
  435. transform: translateX(-50%);
  436. height: 54px;
  437. padding: 0 0px 0 85px;
  438. .oneLi {
  439. padding: 0 8px;
  440. position: absolute;
  441. z-index: 20;
  442. height: 30px;
  443. top: 3px;
  444. left: 5px;
  445. cursor: pointer;
  446. line-height: 30px;
  447. }
  448. .activeOne {
  449. color: #d00724;
  450. pointer-events: none;
  451. opacity: 1;
  452. margin-right: 15px;
  453. }
  454. }
  455. .topTit {
  456. .row {
  457. cursor: pointer;
  458. margin: 3px 10px 0;
  459. padding: 0 10px;
  460. height: 30px;
  461. line-height: 30px;
  462. width: auto;
  463. }
  464. .active {
  465. color: #d00724;
  466. pointer-events: none;
  467. opacity: 1;
  468. }
  469. }
  470. .listBac {
  471. width: 100%;
  472. height: 140px;
  473. position: absolute;
  474. bottom: 10px;
  475. left: 0;
  476. .swiper-scrollbar {
  477. background-color: #d8b275;
  478. }
  479. /deep/.swiper-scrollbar-drag {
  480. background-color: #930909;
  481. }
  482. .swiper-button-prev {
  483. position: absolute;
  484. left: 30px;
  485. top: 50%;
  486. transform: translateY(-50%);
  487. width: 20px;
  488. height: 30px;
  489. background: url("../../assets/img/left.png") no-repeat;
  490. background-size: 100% 100%;
  491. &::after {
  492. color: transparent;
  493. }
  494. }
  495. .swiper-button-next {
  496. position: absolute;
  497. right: 30px;
  498. top: 50%;
  499. transform: translateY(-50%);
  500. width: 20px;
  501. height: 30px;
  502. background: url("../../assets/img/right.png") no-repeat;
  503. background-size: 100% 100%;
  504. &::after {
  505. color: transparent;
  506. }
  507. }
  508. }
  509. .l-con {
  510. width: 100%;
  511. transition: all ease 0.3s;
  512. overflow: hidden;
  513. pointer-events: auto;
  514. .pic-con {
  515. border-radius: 4px;
  516. padding: 0 70px;
  517. }
  518. .clip-scroller {
  519. position: relative;
  520. border-radius: 4px;
  521. }
  522. ul {
  523. // display: inline-block;
  524. white-space: nowrap;
  525. position: relative;
  526. li {
  527. margin: 0 5px;
  528. display: inline-block;
  529. }
  530. }
  531. .pp-tap {
  532. padding: 8px 0 18px;
  533. > li {
  534. width: 84px;
  535. margin: 0 10px;
  536. }
  537. }
  538. .tap {
  539. padding: 10px 0 0;
  540. > li {
  541. position: relative;
  542. width: 104px;
  543. .btn {
  544. width: 100%;
  545. padding: 0;
  546. }
  547. }
  548. }
  549. .pic-list {
  550. > li {
  551. cursor: pointer;
  552. width: 180px;
  553. height: 140px;
  554. > div {
  555. box-sizing: border-box;
  556. width: 100%;
  557. height: 140px;
  558. opacity: 1;
  559. border-radius: 4px;
  560. position: relative;
  561. cursor: pointer;
  562. .dWenZi {
  563. color: #333333;
  564. width: 100%;
  565. text-align: center;
  566. position: absolute;
  567. left: 0;
  568. bottom: 15px;
  569. z-index: 10;
  570. font-size: 14px;
  571. padding: 0 5px;
  572. overflow: hidden;
  573. text-overflow: ellipsis;
  574. white-space: nowrap;
  575. }
  576. > img {
  577. width: 100%;
  578. height: 100px;
  579. object-fit: cover;
  580. }
  581. .iconfont {
  582. position: absolute;
  583. left: 4px;
  584. top: 4px;
  585. z-index: 99;
  586. }
  587. > span {
  588. display: inline-block;
  589. background: rgba(0, 0, 0, 0.5);
  590. position: absolute;
  591. text-overflow: ellipsis;
  592. overflow: hidden;
  593. white-space: nowrap;
  594. left: 0;
  595. bottom: 0;
  596. width: 100%;
  597. }
  598. &.active {
  599. & > img {
  600. border: 3px solid #930909;
  601. }
  602. .dWenZi {
  603. color: #930909;
  604. }
  605. }
  606. }
  607. }
  608. }
  609. .onecls {
  610. background: rgba(0, 0, 0, 0.3);
  611. display: inline-block;
  612. width: 100%;
  613. }
  614. .towcls {
  615. background: rgba(0, 0, 0, 0.3);
  616. }
  617. &.active {
  618. position: relative;
  619. top: 0px;
  620. }
  621. }
  622. }
  623. .listHide {
  624. bottom: -200px;
  625. }
  626. </style>