list.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. <template>
  2. <div class="list" :style="{'max-width':isW ? '1396px':'100%'}">
  3. <div class="l-con" :class="showList ? 'active' : ''" v-if="!(showInfo.catalogRoot.length == 1 && scenes.length == 1 && showInfo.catalogs.length == 1)">
  4. <div class="pic-con">
  5. <div class="clip-scroller" ref="sw" v-swiper:mySwiper="swiperOptions" v-if="scenes.length > 0">
  6. <ul class="pic-list swiper-wrapper">
  7. <li class="swiper-slide" :title="item.sceneTitle" @click="handleVR(item,i)" v-for="(item, i) in scenes" :key="i">
  8. <div :class="{ active: selected.sceneCode == item.sceneCode }">
  9. <img :src="item.icon + `?${Math.random()}`" alt="" />
  10. <i class="iconfont iconedit_type_3d" :class="{ iconedit_type_panorama: item.type !== '4dkk' }"></i>
  11. <rollName :offset="20" :active="selected.sceneCode == item.sceneCode" class="pic-name" :myref="'subw' + item.id" :name="item.sceneTitle" />
  12. </div>
  13. </li>
  14. </ul>
  15. </div>
  16. <div class="clip-scroller" ref="sw1" v-swiper:mySwipera="swiperOptions" v-if="childTab.length > 1">
  17. <ul class="pp-tap swiper-wrapper">
  18. <li class="swiper-slide" @click="handleTabtow(item,i)" v-for="(item, i) in childTab" :key="i">
  19. <rollName
  20. :offset="30"
  21. :mgin="20"
  22. :active="item.id == tabtowActive.id"
  23. class="btn pic-rect"
  24. :class="{ active: item.id == tabtowActive.id }"
  25. :myref="'ww' + item.id"
  26. :name="item.name"
  27. />
  28. </li>
  29. </ul>
  30. </div>
  31. </div>
  32. <div class="clip-scroller" ref="sw2" v-swiper:mySwiperb="swiperOptions" v-if="showInfo.catalogRoot.length > 0 && showInfo.catalogs.length > 1">
  33. <ul class="tap swiper-wrapper" v-if="showInfo.catalogRoot.length > 1">
  34. <li class="swiper-slide" @click="handleTabone(item,i)" :class="{ active: item.id == taboneActive.id }" v-for="(item, i) in showInfo.catalogRoot" :key="i">
  35. <rollName
  36. :offset="30"
  37. :mgin="20"
  38. :active="item.id == taboneActive.id"
  39. class="btn"
  40. :class="{ active: item.id == taboneActive.id }"
  41. :myref="'zw' + item.id"
  42. :name="item.name"
  43. />
  44. </li>
  45. </ul>
  46. </div>
  47. </div>
  48. <div class="btn dl" :class="{deepbg:showList}" v-if="!(showInfo.catalogRoot.length == 1 && scenes.length == 1 && showInfo.catalogs.length == 1)" @click="showList = !showList"><i class="iconfont " :class="showList ? 'iconnav_scene_down' : 'iconnav_scene_up'"></i>场景导航</div>
  49. </div>
  50. </template>
  51. <script>
  52. import { mapGetters } from "vuex";
  53. import config from "@/config";
  54. import rollName from "@/components/rollName";
  55. import { directive } from "vue-awesome-swiper";
  56. // import style (<= Swiper 5.x)
  57. import "swiper/css/swiper.css";
  58. let isW = window.innerWidth > 1400;
  59. console.log(window.innerWidth);
  60. export default {
  61. props: ["select"],
  62. components: { rollName },
  63. directives: {
  64. swiper: directive,
  65. },
  66. data() {
  67. return {
  68. taboneActive: { children: [] },
  69. tabtowActive: "",
  70. childTab: [],
  71. scenes: [],
  72. showList: true,
  73. isW,
  74. loadFirst: true,
  75. menuWidth: 0,
  76. sceneNum: config.sceneNum,
  77. SlyArr:[]
  78. };
  79. },
  80. computed: {
  81. ...mapGetters({
  82. showInfo: "showInfo",
  83. }),
  84. selected() {
  85. return { ...this.select };
  86. },
  87. swiperOptions() {
  88. return {
  89. slidesPerView: "auto",
  90. // initialSlide:0,
  91. // observer:true,
  92. // observeParents: true,
  93. centeredSlides : true,
  94. centerInsufficientSlides: true,
  95. centeredSlidesBounds: true,
  96. freeMode:true
  97. };
  98. },
  99. },
  100. methods: {
  101. getCWidth(ref) {
  102. if (this.$refs[ref]) {
  103. return this.$refs[ref][0].clientWidth;
  104. }
  105. },
  106. fixPosit(ref,i,prenum,nexnum){
  107. if (i!==null) {
  108. let acidx = this.$refs[ref].swiper.activeIndex
  109. if (i - acidx > nexnum ) {
  110. this.$refs[ref].swiper.slideNext()
  111. }
  112. if (acidx - i > prenum ) {
  113. this.$refs[ref].swiper.slidePrev()
  114. }
  115. }
  116. },
  117. handleTabtow(item,i=null){
  118. this.tabtowActive = item
  119. this.fixPosit('sw1',i,3,3)
  120. },
  121. handleTabone(item,i=null){
  122. this.taboneActive = item
  123. let pp = this.isW ? 5 : 4
  124. let nn = this.isW ? 5 : 4
  125. this.fixPosit('sw2',i,pp,nn)
  126. },
  127. handleVR(item,i=null) {
  128. history.replaceState(null, null, "".concat(window.location.pathname, "?").concat(`id=${this.showInfo.id}&vr=${item.sceneCode}`));
  129. this.sceneNum = item.sceneCode;
  130. let pp = this.isW ? 7 : 5
  131. let nn = this.isW ? 7 : 5
  132. this.fixPosit('sw',i,pp,nn)
  133. },
  134. },
  135. mounted() {
  136. },
  137. watch: {
  138. taboneActive: {
  139. handler: function(newVal) {
  140. let temp = [];
  141. newVal.children &&
  142. newVal.children.forEach((item) => {
  143. this.showInfo.catalogs.forEach((sub) => {
  144. if (item == sub.id) {
  145. temp.push(sub);
  146. }
  147. });
  148. });
  149. this.childTab = temp;
  150. if (!this.loadFirst) {
  151. this.tabtowActive = "";
  152. }
  153. },
  154. },
  155. tabtowActive: {
  156. deep: true,
  157. handler: function(newVal) {
  158. if (!newVal) {
  159. this.tabtowActive = this.childTab[0];
  160. } else {
  161. let arr = this.showInfo.scenes.filter((item) => {
  162. return newVal.id == item.category;
  163. });
  164. this.scenes = arr.sort((a, b) => a.weight - b.weight);
  165. }
  166. },
  167. },
  168. sceneNum: {
  169. deep: true,
  170. immediate: true,
  171. handler: function(newVal) {
  172. if (!newVal) {
  173. let tmp = this.showInfo.firstScene || this.showInfo.scenes[0];
  174. this.handleVR(tmp);
  175. return;
  176. }
  177. let val = this.showInfo.scenes.find((item) => item.sceneCode == newVal);
  178. let tmp = this.showInfo.catalogs.find((item) => item.id == val.category);
  179. let rootTmp = this.showInfo.catalogRoot.find((item) => {
  180. return item.children.indexOf(tmp.id) > -1;
  181. });
  182. this.taboneActive = rootTmp;
  183. this.tabtowActive = tmp;
  184. setTimeout(() => {
  185. this.$emit("select", val);
  186. this.loadFirst = false;
  187. });
  188. },
  189. },
  190. selected: {
  191. handler: function(newVal) {
  192. this.handleVR(newVal);
  193. if (newVal.type == "4dkk") {
  194. this.showList = false;
  195. }
  196. },
  197. },
  198. },
  199. };
  200. </script>
  201. <style lang="less" scoped>
  202. .btn {
  203. display: inline-block;
  204. margin: 0 auto;
  205. padding: 0 20px;
  206. height: 26px;
  207. line-height: 26px;
  208. background: rgba(0, 0, 0, 0.5);
  209. border: 1px solid rgba(255, 255, 255, 0.5);
  210. color: rgba(255, 255, 255, 0.5);
  211. border-radius: 4px;
  212. cursor: pointer;
  213. word-break: keep-all;
  214. max-width: 150px;
  215. text-overflow: ellipsis;
  216. overflow: hidden;
  217. white-space: nowrap;
  218. &.active {
  219. border: 1px solid rgba(255, 255, 255, 1);
  220. color: rgba(255, 255, 255, 1);
  221. }
  222. }
  223. .pic-rect {
  224. border-radius: 4px;
  225. height: 24px;
  226. line-height: 24px;
  227. padding: 0;
  228. padding-bottom: 10px;
  229. background: none;
  230. border: none;
  231. &.active {
  232. border: none;
  233. color: rgba(255, 255, 255, 1);
  234. position: relative;
  235. &::before {
  236. content: "";
  237. display: inline-block;
  238. position: absolute;
  239. bottom: 0;
  240. width: 20px;
  241. height: 2px;
  242. z-index: 9999;
  243. left: 50%;
  244. transform: translateX(-50%);
  245. background: #0076f6;
  246. }
  247. }
  248. }
  249. .line {
  250. background: #0076f6;
  251. width: 100%;
  252. height: 0.1px;
  253. opacity: 0.5;
  254. }
  255. .list {
  256. position: fixed;
  257. bottom: 10px;
  258. left: 50%;
  259. transform: translateX(-50%);
  260. z-index: 999;
  261. text-align: center;
  262. // width: 100%;
  263. max-width: 1396px;
  264. pointer-events: none;
  265. .dl {
  266. background: rgba(0, 0, 0, 0.3);
  267. border-radius: 18px;
  268. border: 1px solid rgba(255, 255, 255, 0.2);
  269. pointer-events: auto;
  270. margin-top: 18px;
  271. height: 38px;
  272. line-height: 38px;
  273. color: #fff;
  274. > i {
  275. margin-right: 8px;
  276. vertical-align: bottom;
  277. font-size: 18px;
  278. }
  279. }
  280. .deepbg{
  281. background: rgba(0, 0, 0, 0.5);
  282. }
  283. .l-con {
  284. width: 100%;
  285. transition: all ease 0.3s;
  286. max-height: 0px;
  287. overflow: hidden;
  288. pointer-events: auto;
  289. .pic-con {
  290. background: rgba(0, 0, 0, 0.5);
  291. border-radius: 4px;
  292. padding: 0 20px;
  293. }
  294. .clip-scroller{
  295. position: relative;
  296. border-radius: 4px;
  297. }
  298. ul {
  299. // display: inline-block;
  300. white-space: nowrap;
  301. position: relative;
  302. li {
  303. margin: 0 5px;
  304. display: inline-block;
  305. }
  306. }
  307. .pp-tap {
  308. padding: 8px 0 18px;
  309. > li {
  310. width: 84px;
  311. margin: 0 10px;
  312. }
  313. }
  314. .tap {
  315. padding: 10px 0 0;
  316. > li {
  317. position: relative;
  318. width: 104px;
  319. .btn{
  320. width: 100%;
  321. padding: 0;
  322. }
  323. // &.active {
  324. // @size:5px;
  325. // &::before {
  326. // content: "";
  327. // display: inline-block;
  328. // width: 0;
  329. // height: 0;
  330. // border-left: @size * 1.5 solid transparent;
  331. // border-right: @size * 1.5 solid transparent;
  332. // border-top: @size*2 solid rgba(0, 0, 0, 0.5);
  333. // position: absolute;
  334. // top: -20px;
  335. // left: 50%;
  336. // transform: translateX(-50%);
  337. // }
  338. // }
  339. }
  340. }
  341. .pic-list {
  342. padding: 10px 0;
  343. > li {
  344. cursor: pointer;
  345. width: 72px;
  346. height: 72px;
  347. > div {
  348. width: 100%;
  349. height: 100%;
  350. border: 2px solid #ffffff;
  351. opacity: 1;
  352. border-radius: 4px;
  353. overflow: hidden;
  354. position: relative;
  355. cursor: pointer;
  356. .pic-name {
  357. background: rgba(0, 0, 0, 0.5);
  358. position: absolute;
  359. left: 0;
  360. bottom: 0;
  361. }
  362. > img {
  363. position: absolute;
  364. top: 50%;
  365. left: 50%;
  366. transform: translate(-50%, -50%);
  367. z-index: -1;
  368. }
  369. .iconfont {
  370. position: absolute;
  371. left: 4px;
  372. top: 4px;
  373. z-index: 99;
  374. &::after{
  375. background: rgba(0, 0, 0, 0.3);
  376. content: '';
  377. width: 14px;
  378. height: 14px;
  379. display: inline-block;
  380. position: absolute;
  381. top: 50%;
  382. left: 50%;
  383. transform: translate(-50%,-50%);
  384. z-index: -1;
  385. filter: blur(4px);
  386. }
  387. }
  388. > span {
  389. display: inline-block;
  390. background: rgba(0, 0, 0, 0.5);
  391. position: absolute;
  392. text-overflow: ellipsis;
  393. overflow: hidden;
  394. white-space: nowrap;
  395. left: 0;
  396. bottom: 0;
  397. width: 100%;
  398. }
  399. &.active {
  400. border: 2px solid #0076f6;
  401. }
  402. }
  403. }
  404. }
  405. .onecls {
  406. background: rgba(0, 0, 0, 0.3);
  407. display: inline-block;
  408. width: 100%;
  409. }
  410. .towcls {
  411. background: rgba(0, 0, 0, 0.3);
  412. }
  413. &.active {
  414. max-height: 250px;
  415. }
  416. }
  417. }
  418. </style>