index.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. <script setup lang="ts">
  2. import "swiper/swiper-bundle.css";
  3. import Tabbar from "@/components/Tabbar.vue";
  4. // import Music from "@/components/Music.vue";
  5. import ModelList, { baseURL } from "@/assets/data/Model";
  6. import Swiper from "swiper";
  7. // import { baseURL } from "@/assets/data/Model";
  8. import DownIcon from "@/assets/img/map/down.png";
  9. import UpIcon from "@/assets/img/map/up.png";
  10. import { useMap } from "@/store/Map";
  11. const route = useRoute();
  12. // 隐藏轮播
  13. const isShow = ref(true);
  14. const store = useMap()
  15. const swiperRef = ref({});
  16. const router = useRouter();
  17. const goDetail = (code: string) => {
  18. router.push({
  19. path: "/bldgMap/detail",
  20. query: {
  21. code: code,
  22. },
  23. });
  24. };
  25. const viewTop = ref("");
  26. const viewLeft = ref("");
  27. const startY = ref();
  28. const startX = ref();
  29. // 手指滑动
  30. const touchMove = (event: any) => {
  31. let moveEndX = event.changedTouches[0].pageX;
  32. let X = moveEndX - startX.value; //如果值为正,则代表手指下滑,反则则为上滑,为0则表示点击
  33. let moveEndY = event.changedTouches[0].pageY;
  34. let Y = moveEndY - startY.value; //如果值为正,则代表手指下滑,反则则为上滑,为0则表示点击
  35. // console.log(X, Y);
  36. if (X > 20) {
  37. viewTop.value = parseFloat(viewTop.value) - 0.6 + "%";
  38. }
  39. if (X < -20) {
  40. viewTop.value = parseFloat(viewTop.value) + 0.6 + "%";
  41. }
  42. if (Y > 20) {
  43. // console.log("上滑", viewTop.value, viewLeft.value);
  44. viewLeft.value = parseFloat(viewLeft.value) - 0.6 + "%";
  45. }
  46. if (Y < -20) {
  47. // console.log("下滑", viewTop.value, viewLeft.value);
  48. viewLeft.value = parseFloat(viewLeft.value) + 0.6 + "%";
  49. }
  50. };
  51. // 开始滑动
  52. const handletouchstart = (event: any) => {
  53. startX.value = event.changedTouches[0].pageX;
  54. startY.value = event.changedTouches[0].pageY;
  55. };
  56. const getAssetURL = (image: string) => {
  57. return new URL(`../../assets/img/map/nornal/${image}`, import.meta.url).href;
  58. };
  59. const goChange = () => {
  60. router.push({
  61. name: "modelChange",
  62. });
  63. };
  64. const currentScene = ref(ModelList[0]);
  65. onMounted(() => {
  66. const swiperRef = new Swiper(".swiper-container", {
  67. slidesPerView: 1.7,
  68. spaceBetween: 20,
  69. effect: "coverflow",
  70. centeredSlides: true,
  71. navigation: {
  72. nextEl: ".swiper-button-next",
  73. prevEl: ".swiper-button-prev",
  74. },
  75. initialSlide: store.currentIndex ? store.currentIndex : 0,
  76. pagination: {
  77. el: ".swiper-pagination",
  78. clickable: true,
  79. },
  80. on: {
  81. slideChange: function (swiper: any) {
  82. nextTick(() => {
  83. currentScene.value = ModelList[swiper.activeIndex];
  84. store.currentIndex = swiper.activeIndex;
  85. viewTop.value = currentScene.value.viewTop;
  86. viewLeft.value = currentScene.value.viewLeft;
  87. });
  88. },
  89. },
  90. });
  91. if (route.query.name) {
  92. viewLeft.value = "80%";
  93. viewTop.value = "40%";
  94. } else {
  95. viewLeft.value = ModelList[0].viewLeft;
  96. viewTop.value = ModelList[0].viewTop;
  97. }
  98. });
  99. </script>
  100. <template>
  101. <div id="background" class="map" :style="{
  102. backgroundPosition: `${viewTop} ${viewLeft}`,
  103. }" @touchmove="touchMove" @touchstart="handletouchstart">
  104. <!-- 头部 -->
  105. <!-- <div class="map-top">芜湖市优秀文物建筑</div> -->
  106. <!-- 行政区选择 -->
  107. <div class="region-btn" @click="goChange()">
  108. <div class="region-btn-name">镜湖区</div>
  109. <div class="region-btn-dics">[选择行政区]</div>
  110. </div>
  111. <!-- 轮播图 -->
  112. <div class="swiper-box" v-show="isShow">
  113. <div class="swiper-container" ref="swiperRef">
  114. <div class="swiper-wrapper">
  115. <div class="swiper-slide option-item" v-for="(item, index) in ModelList" :key="index"
  116. @click="goDetail(item.code)">
  117. <!-- 边框图片 -->
  118. <img class="border-img" :src="`${baseURL}/thumbnail/border.png`" alt="" />
  119. <!-- 普通图片 -->
  120. <img class="nornal-img" :src="getAssetURL(`${item.name}.png`)" alt="" />
  121. <div class="disc-box">
  122. <div class="disc-box-title">
  123. <span>·</span>{{ item.fullName }}
  124. </div>
  125. <div class="disc-box-content">{{ item.disc }}</div>
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. </div>
  131. <img class="img-icon" :src="isShow ? DownIcon : UpIcon" alt="" @click="() => {
  132. isShow = !isShow;
  133. }
  134. " />
  135. <!-- 建筑列表 -->
  136. <!-- <img
  137. class="architecture-img"
  138. :src="getAssetURL(`${item.name}.png`)"
  139. alt=""
  140. v-for="(item, index) in MapData"
  141. :key="index"
  142. :style="{ top: item.mapTop, left: item.mapLeft }"
  143. /> -->
  144. </div>
  145. <Tabbar />
  146. <!-- <Music /> -->
  147. </template>
  148. <style lang="less" scoped>
  149. .map {
  150. min-width: 100%;
  151. min-height: 100vh;
  152. height: 100vh;
  153. height: calc(var(--vh, 1vh) * 100);
  154. background-image: url(../../assets/img/map/home/mapBg2.jpg);
  155. background-size: 450%;
  156. // background-position: 20% 0%;
  157. overflow: hidden;
  158. position: relative;
  159. -webkit-user-drag: element;
  160. user-drag: element;
  161. &-top {
  162. width: 100%;
  163. height: 8vh;
  164. background: var(--color-bg);
  165. font-size: 1rem;
  166. text-align: center;
  167. line-height: 8vh;
  168. letter-spacing: 3px;
  169. color: #4d4d4d;
  170. }
  171. .region-btn {
  172. width: 45%;
  173. margin: 10px;
  174. height: 5vh;
  175. background-image: url(/src\assets\img\map\regionBg.jpg);
  176. background-size: 100% 100%;
  177. display: flex;
  178. justify-content: center;
  179. align-items: center;
  180. &-name {
  181. font-size: 0.9rem;
  182. font-weight: bold;
  183. color: #62573f;
  184. margin-right: 5px;
  185. letter-spacing: 2px;
  186. }
  187. &-dics {
  188. font-size: 0.6rem;
  189. color: #948973;
  190. font-weight: 600;
  191. letter-spacing: 2px;
  192. }
  193. }
  194. .swiper-box {
  195. width: 100%;
  196. background: linear-gradient(to top, #0c0c0c45, #ffffff00);
  197. position: fixed;
  198. bottom: 0;
  199. img {
  200. width: 100%;
  201. height: 100%;
  202. // object-fit: cover;
  203. position: absolute;
  204. top: 0;
  205. left: 0;
  206. }
  207. .border-img {
  208. width: 100%;
  209. height: 100%;
  210. z-index: 2;
  211. }
  212. .nornal-img {
  213. border-radius: 40px;
  214. }
  215. .disc-box {
  216. width: 85%;
  217. // background: red;
  218. color: white;
  219. position: absolute;
  220. font-size: 0.6rem;
  221. bottom: 5vw;
  222. left: 8%;
  223. &-title {
  224. font-weight: bold;
  225. font-size: 1rem;
  226. span {
  227. font-size: 1.5rem;
  228. margin-right: 5px;
  229. }
  230. }
  231. // &-title:before {
  232. // content: "";
  233. // position: absolute;
  234. // left: -10px;
  235. // top: 6%;
  236. // transform: translateY(-6%);
  237. // width: 10px;
  238. // height: 10px;
  239. // border-radius: 50%;
  240. // background: blue;
  241. // }
  242. &-content {
  243. width: 100%;
  244. word-break: break-all;
  245. text-overflow: ellipsis;
  246. overflow: hidden;
  247. display: -webkit-box;
  248. -webkit-box-orient: vertical;
  249. -webkit-line-clamp: 4;
  250. /* 这里是超出几行省略 */
  251. letter-spacing: 2px;
  252. }
  253. }
  254. }
  255. .img-icon {
  256. width: 8vw;
  257. height: 8vw;
  258. position: fixed;
  259. bottom: 100px;
  260. left: 50%;
  261. transform: translateX(-50%);
  262. }
  263. }
  264. .architecture-img {
  265. width: 20%;
  266. position: relative;
  267. }
  268. .swiper-container {
  269. width: 100%;
  270. height: 80vw;
  271. margin: 0;
  272. padding: 0;
  273. perspective: 1200px;
  274. }
  275. .swiper-slide {
  276. // background: #fff;
  277. border-radius: 10px;
  278. // box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
  279. transform-style: preserve-3d;
  280. transform-origin: center bottom;
  281. transition: transform 0.5s;
  282. }
  283. .swiper-slide-active {
  284. transform: translate3d(0, -130px, 0);
  285. // height: 43vh;
  286. }
  287. .swiper-slide-next,
  288. .swiper-slide-prev {
  289. opacity: 0.6;
  290. // height: 40vh;
  291. transform: translate3d(0, 0, -200px);
  292. }
  293. .swiper-pagination {
  294. position: absolute;
  295. bottom: 10px;
  296. left: 50%;
  297. transform: translateX(-50%);
  298. }
  299. .swiper-button-next,
  300. .swiper-button-prev {
  301. position: absolute;
  302. top: 50%;
  303. transform: translateY(-50%);
  304. width: 40px;
  305. height: 40px;
  306. border-radius: 50%;
  307. background: #fff;
  308. box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
  309. display: flex;
  310. align-items: center;
  311. justify-content: center;
  312. cursor: pointer;
  313. }
  314. .swiper-button-next {
  315. right: 10px;
  316. }
  317. .swiper-button-prev {
  318. left: 10px;
  319. }
  320. </style>