list.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <template>
  2. <div class="bar-list"
  3. v-if="show && !((metadata.catalogRoot && metadata.catalogRoot.length == 1) && scenes.length == 1 && secondaryList.length == 1)"
  4. :class="{ barshow: isShowScenesList }">
  5. <div class="top-con">
  6. <div class="swiper-container" id="swScenes" :style="`width:${Math.min(scenesListW, innerW)}px;
  7. padding:${scenesListW > innerW ? '0 15px' : '0'}`" v-if="currentScenesList.length > 0">
  8. <ul class="swiper-wrapper">
  9. <li @click="tabCurrentScene(item)" class="swiper-slide" :class="{
  10. active: currentScene.sceneCode == item.sceneCode,
  11. loopspan: item.sceneTitle.length > spanlength && currentScene.id == item.id,
  12. }" :style="{ backgroundImage: `url(${item.icon})` }" v-for="(item, i) in currentScenesList" :key="i">
  13. <i class="iconfont " :class="item.type == '4dkk' ? 'icon-editor_3d' : 'icon-editor_panoramic'"></i>
  14. <div>
  15. <span v-if="currentScene.id == item.id">{{ item.sceneTitle }}</span>
  16. <span v-else>{{ item.sceneTitle.length > spanlength ? item.sceneTitle.slice(0, spanlength) :
  17. item.sceneTitle
  18. }}</span>
  19. </div>
  20. </li>
  21. </ul>
  22. </div>
  23. <div class="swiper-container" id="swSecondary" :style="`width:${Math.min(secondaryW, innerW)}px;
  24. padding:${secondaryW > innerW ? '0 15px' : '0'}`" v-if="secondaryList.length > 1">
  25. <ul class="swiper-wrapper">
  26. <li class="swiper-slide" @click="tabSecondary(item)" :class="{
  27. active: currentSecondary.id == item.id,
  28. loopspan: item.name.length > spanlength && currentSecondary.id == item.id,
  29. }" v-for="(item, i) in secondaryList" :key="i">
  30. <span v-if="currentSecondary.id == item.id">{{ item.name }}</span>
  31. <span v-else>{{ item.name.length > spanlength ? item.name.slice(0, spanlength) : item.name }}</span>
  32. </li>
  33. </ul>
  34. </div>
  35. </div>
  36. <div class="swiper-container" id="swcatalogRoot" :style="`width:${Math.min(catalogRootW, innerW)}px;
  37. padding:${catalogRootW > innerW ? '0 15px' : '0'}`"
  38. v-if="metadata.catalogRoot.length > 0 && metadata.catalogs.length > 1">
  39. <ul class="swiper-wrapper" v-show="metadata.catalogRoot.length > 1">
  40. <li class="swiper-slide" :class="{
  41. active: currentCatalogRoot.id == item.id,
  42. loopspan: item.name.length > spanlength && currentCatalogRoot.id == item.id,
  43. }" @click="tabRoot(item)" v-for="(item, i) in metadata.catalogRoot" :key="i">
  44. <span v-if="currentCatalogRoot.id == item.id">{{ item.name }}</span>
  45. <span v-else>{{ item.name.length > spanlength ? item.name.slice(0, spanlength) : item.name }}</span>
  46. </li>
  47. </ul>
  48. </div>
  49. </div>
  50. </template>
  51. <script setup>
  52. import { ref, watch, computed, onMounted, nextTick } from "vue";
  53. import { useStore } from "vuex";
  54. import { useApp } from "@/app";
  55. const store = useStore();
  56. const spanlength = ref(5);
  57. const metadata = computed(() => store.getters["scene/metadata"]);
  58. const scenes = computed(() => store.getters["scene/list"]);
  59. const currentScene = computed(() => store.getters["scene/currentScene"]);
  60. const currentCatalogRoot = computed(() => store.getters["scene/currentCatalogRoot"]);
  61. const currentSecondary = computed(() => store.getters["scene/currentSecondary"]);
  62. const secondaryList = computed(() => store.getters["scene/secondaryList"]);
  63. const isShowScenesList = computed(() => store.getters["functions/isShowScenesList"]);
  64. const currentScenesList = computed(() => store.getters["scene/currentScenesList"]);
  65. const swidth = ref({
  66. "swcatalogRoot": 104,
  67. "swSecondary": 84,
  68. "swScenes": 72,
  69. })
  70. const innerW = computed(() => window.innerWidth)
  71. const scenesListW = computed(() => currentScenesList.value.length * (swidth.value['swScenes'] + 10) - 10)
  72. const secondaryW = computed(() => secondaryList.value.length * (swidth.value['swSecondary'] + 10) - 10)
  73. const catalogRootW = computed(() => metadata.value.catalogRoot.length * (swidth.value['swcatalogRoot'] + 10) - 10)
  74. const show = ref(false);
  75. const tabCurrentScene = (data) => {
  76. store.commit("scene/setCurrentScene", data);
  77. };
  78. const tabSecondary = (data) => {
  79. store.commit("scene/setCurrentSecondary", data);
  80. };
  81. const tabRoot = (data) => {
  82. store.commit("scene/setCurrentCatalogRoot", data);
  83. };
  84. const loadList = () => {
  85. nextTick(() => {
  86. let t = setTimeout(() => {
  87. clearTimeout(t);
  88. ["#swcatalogRoot", "#swSecondary", "#swScenes"].forEach((item) => {
  89. let tmp = new Swiper(item, {
  90. slidesPerView: "auto",
  91. centeredSlides: true,
  92. spaceBetween: 10,
  93. centerInsufficientSlides: true,
  94. centeredSlidesBounds: true,
  95. freeMode: true,
  96. observer: true,
  97. observeParents:true
  98. });
  99. if (item == '#swScenes') {
  100. setTimeout(() => {
  101. tmp && tmp.slideTo(0, 80, false)
  102. }, 0);
  103. }
  104. // console.log(tmp.slideTo);
  105. });
  106. }, 100);
  107. });
  108. };
  109. watch(currentSecondary, () => {
  110. loadList();
  111. });
  112. watch(currentScenesList, () => {
  113. loadList();
  114. });
  115. onMounted(() => {
  116. useApp().then(async (app) => {
  117. show.value = true;
  118. loadList();
  119. });
  120. });
  121. </script>
  122. <style lang="scss" scoped>
  123. .bar-list {
  124. position: absolute;
  125. bottom: 88px;
  126. left: 50%;
  127. transform: translateX(-50%);
  128. text-align: center;
  129. overflow: hidden;
  130. max-height: 0;
  131. transition: .3s all ease;
  132. z-index: 9;
  133. width: 100%;
  134. .swiper-container {
  135. width: 100%;
  136. position: relative;
  137. margin: 0 auto;
  138. >ul {
  139. >li {
  140. white-space: nowrap;
  141. >span,
  142. >div>span {
  143. cursor: pointer;
  144. display: inline-block;
  145. color: rgba(255, 255, 255, 0.6);
  146. }
  147. &.loopspan {
  148. >span,
  149. >div>span {
  150. animation: 5s wordsLoop linear infinite normal;
  151. }
  152. }
  153. &.active {
  154. >span,
  155. >div>span {
  156. color: rgba(255, 255, 255, 1);
  157. }
  158. }
  159. }
  160. }
  161. }
  162. .top-con {
  163. margin-bottom: 10px;
  164. padding: 10px 0;
  165. width: 100%;
  166. background: rgba(0, 0, 0, 0.5);
  167. }
  168. #swcatalogRoot {
  169. padding: 0 15px;
  170. >ul {
  171. >li {
  172. width: 104px;
  173. background: rgba(0, 0, 0, 0.5);
  174. border-radius: 4px;
  175. padding: 4px 10px;
  176. border: 1px solid rgba(255, 255, 255, 0.5);
  177. box-sizing: border-box;
  178. overflow: hidden;
  179. >span {
  180. width: 100%;
  181. word-break: keep-all;
  182. }
  183. &.active {
  184. border: 1px solid rgba(255, 255, 255, 1);
  185. }
  186. }
  187. }
  188. }
  189. #swSecondary {
  190. margin: 20px auto 10px;
  191. padding: 0 15px;
  192. >ul {
  193. >li {
  194. width: 84px;
  195. box-sizing: border-box;
  196. overflow: hidden;
  197. padding-bottom: 6px;
  198. >span {
  199. width: 100%;
  200. word-break: keep-all;
  201. }
  202. &.active {
  203. position: relative;
  204. &::before {
  205. content: "";
  206. display: inline-block;
  207. position: absolute;
  208. bottom: 0;
  209. width: 20px;
  210. height: 2px;
  211. z-index: 9999;
  212. left: 50%;
  213. transform: translateX(-50%);
  214. background: var(--colors-primary-base);
  215. }
  216. }
  217. }
  218. }
  219. }
  220. #swScenes {
  221. // padding: 0 15px;
  222. >ul {
  223. >li {
  224. cursor: pointer;
  225. width: 72px;
  226. height: 72px;
  227. border-radius: 6px;
  228. border: 1px solid #ffffff;
  229. background-size: cover;
  230. position: relative;
  231. overflow: hidden;
  232. .iconfont {
  233. position: absolute;
  234. left: 4px;
  235. top: 4px;
  236. z-index: 99;
  237. &::after {
  238. background: rgba(0, 0, 0, 0.3);
  239. content: "";
  240. width: 14px;
  241. height: 14px;
  242. display: inline-block;
  243. position: absolute;
  244. top: 50%;
  245. left: 50%;
  246. transform: translate(-50%, -50%);
  247. z-index: -1;
  248. filter: blur(4px);
  249. }
  250. }
  251. >div {
  252. position: absolute;
  253. bottom: 0;
  254. left: 0;
  255. height: 20px;
  256. background: rgba(0, 0, 0, 0.5);
  257. width: 100%;
  258. overflow: hidden;
  259. >span {
  260. width: 100%;
  261. line-height: 20px;
  262. word-break: keep-all;
  263. }
  264. }
  265. &.active {
  266. border: 1px solid var(--colors-primary-base);
  267. >div {
  268. >span {}
  269. }
  270. }
  271. }
  272. }
  273. }
  274. }
  275. .barshow {
  276. max-height: 190px;
  277. }
  278. @keyframes wordsLoop {
  279. 0% {
  280. transform: translateX(100%);
  281. -webkit-transform: translateX(100%);
  282. }
  283. 100% {
  284. transform: translateX(-100%);
  285. -webkit-transform: translateX(-100%);
  286. }
  287. }
  288. </style>