MapBox.vue 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  1. <template>
  2. <div id="map" style="width: 100%; height: 100%">
  3. <div class="space-main" id="spaceMain">
  4. <template v-if="mapType == 1">
  5. <div
  6. class="space-box"
  7. v-for="(area, index) in mapData.spaceList"
  8. :style="{
  9. width: area.width + 'px',
  10. height: area.height + 'px',
  11. top: area.top + 'px',
  12. left: area.left + 'px',
  13. }"
  14. :key="'map' + index"
  15. >
  16. <div
  17. class="space"
  18. :id="'space' + area.id"
  19. :class="[
  20. area.canClick ? '' : 'click-disable',
  21. selectArea.spaceId === area.spaceId
  22. ? area.disabled
  23. ? 'select-disable'
  24. : 'select'
  25. : '',
  26. isSetSpace ? 'use-select' : '',
  27. area.disabled ? 'space-disable-box' : 'space-box-bg',
  28. ]"
  29. @click.stop="checkSpace(area)"
  30. :style="{
  31. backgroundColor: area.backgroundColor ? area.backgroundColor : '',
  32. }"
  33. >
  34. <div
  35. class="device"
  36. :class="
  37. selectArea.spaceId === area.spaceId ? 'select-device' : ''
  38. "
  39. v-show="
  40. area.width * displacement.scale > 24 &&
  41. area.height * displacement.scale > 24
  42. "
  43. >
  44. <img
  45. :src="area.icon"
  46. v-if="selectArea.spaceId !== area.spaceId && area.icon"
  47. />
  48. <img :src="area.selectIcon" v-else class="select-icon" alt="" />
  49. <template v-if="area.localName">
  50. <span
  51. v-if="
  52. (area.height > 80 &&
  53. area.localName.length * 12 < area.width) ||
  54. selectArea.spaceId === area.spaceId
  55. "
  56. style="font-size: 12px"
  57. >{{ area.localName }}</span
  58. >
  59. </template>
  60. </div>
  61. </div>
  62. </div>
  63. </template>
  64. <canvas-box
  65. v-else
  66. class="canvasBox"
  67. ref="canvasRef"
  68. :mapData="mapData"
  69. @checkSpace="checkSpace"
  70. ></canvas-box>
  71. </div>
  72. <!--地图右侧的操作按钮-->
  73. <div class="map-toolbar">
  74. <img
  75. :src="parseImgUrl('map-icon', 'icon-search-big.svg')"
  76. @click.stop="goSearch"
  77. class="icon-search"
  78. alt=""
  79. />
  80. <div class="toolbar-item" @click.stop="checkFloor">
  81. <span class="text-hidden">{{ floorItem.localName }}</span>
  82. </div>
  83. <div class="toolbar-item" @click.stop="checkBuilding">
  84. <span class="text-hidden">{{ buildingItem.localName }}</span>
  85. </div>
  86. </div>
  87. <!-- 选择建筑 -->
  88. <van-popup
  89. v-model:show="showBuilding"
  90. teleport="body"
  91. class="buiding-box"
  92. style="width: 40%; height: 100%; padding: 20px"
  93. position="right"
  94. >
  95. <div
  96. class="buiding-item"
  97. :key="item.id"
  98. :class="buildingItem.buildingId === item.id ? 'active' : ''"
  99. @click.stop="comfirmBuilding(item)"
  100. v-for="item in buildingData"
  101. >
  102. {{ item.localName }}
  103. </div>
  104. </van-popup>
  105. <!-- 选择楼层 -->
  106. <van-popup
  107. v-model:show="showFloor"
  108. teleport="body"
  109. class="buiding-box"
  110. style="width: 40%; height: 100%; padding: 20px"
  111. position="right"
  112. >
  113. <div
  114. class="buiding-item"
  115. :key="item.id"
  116. :class="floorItem.id === item.id ? 'active' : ''"
  117. @click.stop="comfirmFloor(item)"
  118. v-for="item in floorData"
  119. >
  120. {{ item.localName }}
  121. </div>
  122. <!-- <div class="buiding-item" @click.stop="comfirmFloor('4555556')">
  123. 4555556
  124. </div> -->
  125. </van-popup>
  126. <!--搜索-->
  127. <van-popup
  128. v-model:show="showSearch"
  129. teleport="body"
  130. class="buiding-box"
  131. style="width: 100%; height: 100%"
  132. position="right"
  133. >
  134. <div style="width: 100%; height: 100%">
  135. <space-search @closeSearch="closeSearch"></space-search>
  136. </div>
  137. </van-popup>
  138. </div>
  139. </template>
  140. <script lang="ts">
  141. import {
  142. defineComponent,
  143. onMounted,
  144. nextTick,
  145. reactive,
  146. toRefs,
  147. ref,
  148. watch,
  149. } from "vue";
  150. import {
  151. getLocalStorageFloor,
  152. getStorageSpaceId,
  153. localStorageFloor,
  154. localStorageSpaceId,
  155. parseImgUrl,
  156. setLocalNewSpaceInfo,
  157. } from "@/utils";
  158. import { Toast, Dialog } from "vant";
  159. import { getBuildingList, getFloorList, getMapInfo } from "@/apis/envmonitor";
  160. import SpaceSearch from "@/views/envmonitor/Search/SpaceSearch.vue";
  161. import CanvasBox from "./CanvasBox.vue";
  162. import { useRouter } from "vue-router";
  163. import { getSpaceType, mapIcon } from "@/utils/mapIcon";
  164. import any = jasmine.any;
  165. export default defineComponent({
  166. props: {
  167. projectId: {
  168. type: String,
  169. default: () => "",
  170. },
  171. spaceData: {
  172. type: Array,
  173. default: () => [],
  174. },
  175. spaceInfo: {
  176. type: Object,
  177. default: () => {},
  178. },
  179. isSetSpace: {
  180. type: Boolean,
  181. default: () => false,
  182. },
  183. floorId: {
  184. type: String,
  185. default: () => "",
  186. },
  187. buildingId: {
  188. type: String,
  189. default: () => "",
  190. },
  191. mapType: {
  192. type: Number,
  193. default: () => 1,
  194. },
  195. },
  196. components: {
  197. SpaceSearch,
  198. CanvasBox,
  199. },
  200. setup(props, contx) {
  201. const router = useRouter();
  202. const mapData: any = {};
  203. const document: any = window.document;
  204. const screenInfo: any = {
  205. screenWidth: document.body.clientWidth,
  206. screenHeight: document.body.clientHeight,
  207. };
  208. const comMapScale: any = 0.8;
  209. const displacement: any = {
  210. scale: 1,
  211. pageX: 0,
  212. pageX2: 0,
  213. originScale: 0,
  214. moveable: false,
  215. };
  216. let buildingData: any = [];
  217. let floorData: any = [];
  218. let floorItem: any = {};
  219. let selectArea: any = {};
  220. let transformData: any = {};
  221. let spaceInfo: any = null;
  222. const canvasRef: any = ref(null);
  223. const proxyData = reactive({
  224. parseImgUrl: parseImgUrl,
  225. mapType: props.mapType,
  226. spaceInfo: spaceInfo,
  227. isSetSpace: props.isSetSpace, // isSetSpace:true 代表为设置常驻空间页面展示
  228. widthMapScale: 1,
  229. tempScale: 0.8,
  230. comMapScale: comMapScale,
  231. heightScale: 1,
  232. showSearch: false,
  233. isSetSearchSpace: false,
  234. showBuilding: false,
  235. showFloor: false,
  236. buildingItem: {
  237. buildingId: "",
  238. localName: "",
  239. },
  240. floorData: floorData,
  241. floorItem: floorItem,
  242. buildingData: buildingData,
  243. mapData: mapData,
  244. copyMapDaata: mapData,
  245. selectArea: selectArea,
  246. displacement: displacement,
  247. screenInfo: screenInfo,
  248. transformData: transformData,
  249. // 切换楼层的时候恢缩放和滚动的样式
  250. clearPreStyle() {
  251. let mapDom = document.querySelector("#map");
  252. mapDom.scrollLeft = 0;
  253. mapDom.scrollTop = 0;
  254. let matrix_box: any = document.querySelector("#spaceMain");
  255. // 记住使用的缩放值
  256. proxyData.displacement.scale = 1;
  257. if (matrix_box) {
  258. matrix_box.style.left = 0 + "px";
  259. matrix_box.style.top = 0 + "px";
  260. }
  261. },
  262. swipe(el: any, options: any) {
  263. //设置开关,监听move事件
  264. let isMove: any = false;
  265. // 设置手指触摸开始的坐标
  266. let startX: any = 0;
  267. let startY: any = 0;
  268. // 设置手指移动的坐标
  269. let moveX: any = 0;
  270. let moveY: any = 0;
  271. //设置指针距离元素的边框的距离
  272. let disX: any = 0;
  273. let disY: any = 0;
  274. // 如果用户未传入参数2,自己定义一个
  275. let fun: any = function () {};
  276. let data: any = {
  277. swipeLeft: fun,
  278. swipeRight: fun,
  279. swipeDown: fun,
  280. swipeUp: fun,
  281. drag: fun,
  282. };
  283. // 判断是否传入参数2,有的话覆盖默认值
  284. Object.assign(data, options);
  285. // 给元素绑定三个事件
  286. el.addEventListener(
  287. "touchstart",
  288. function (e: any) {
  289. console.log(e);
  290. //获取手指开始的坐标
  291. startX = e.touches[0].pageX;
  292. startY = e.touches[0].pageY;
  293. //计算指针距离元素边框的位置
  294. disX = startX - el.offsetLeft;
  295. disY = startY - el.offsetTop;
  296. console.log(el.offsetLeft);
  297. console.log(el.offsetTop);
  298. console.log(e.touches[0].pageX);
  299. },
  300. { passive: true }
  301. );
  302. el.addEventListener(
  303. "touchmove",
  304. function (e: any) {
  305. if (proxyData.displacement.moveable) {
  306. return;
  307. }
  308. console.log(e);
  309. //如果触发了move事件,打开开关
  310. isMove = true;
  311. // 获取移动时的坐标
  312. moveX = e.touches[0].pageX;
  313. moveY = e.touches[0].pageY;
  314. e.mation = {
  315. startX: startX,
  316. startY: startY,
  317. moveX: moveX,
  318. moveY: moveY,
  319. disX: disX,
  320. disY: disY,
  321. };
  322. data.drag.call(el, e);
  323. // 判断是否触发了move事件
  324. if (isMove) {
  325. // 计算水平边长
  326. let absX: any = Math.abs(moveX - startX);
  327. // 计算垂直边长
  328. let absY: any = Math.abs(moveY - startY);
  329. // 判断垂直还是水平滑动
  330. if (absX > absY) {
  331. // console.log('水平滑动');
  332. //再判断是左滑右滑
  333. if (moveX - startX > 0) {
  334. data.swipeRight.call(el, e);
  335. } else {
  336. data.swipeLeft.call(el, e);
  337. }
  338. } else {
  339. // console.log('垂直滑动');
  340. //判断是上滑还是下滑
  341. if (moveY - startX > 0) {
  342. // 下滑
  343. data.swipeDown.call(el, e);
  344. } else {
  345. data.swipeUp.call(el, e);
  346. }
  347. }
  348. }
  349. },
  350. { passive: true }
  351. );
  352. el.addEventListener("touchend", function (e: any) {
  353. isMove = false;
  354. });
  355. },
  356. /**
  357. * 地图滚动
  358. */
  359. mapScroll() {
  360. let matrix_box: any = document.querySelector("#spaceMain");
  361. let houseDesDom = document.querySelector("#houseDes");
  362. let houseHeight: any = houseDesDom ? houseDesDom.offsetHeight : 0;
  363. proxyData.swipe(matrix_box, {
  364. swipeLeft: function (e: any) {
  365. if (!proxyData.displacement.moveable) {
  366. if (matrix_box.offsetWidth < proxyData.screenInfo.screenWidth) {
  367. } else {
  368. let width: any =
  369. matrix_box.offsetWidth -
  370. Math.abs(e.touches[0].pageX - e.mation.disX);
  371. if (width < proxyData.screenInfo.screenWidth) {
  372. matrix_box.style.left =
  373. -(
  374. matrix_box.offsetWidth - proxyData.screenInfo.screenWidth
  375. ) + "px";
  376. } else {
  377. matrix_box.style.left =
  378. e.touches[0].pageX - e.mation.disX + "px";
  379. }
  380. }
  381. }
  382. },
  383. swipeRight: function (e: any) {
  384. if (!proxyData.displacement.moveable) {
  385. if (matrix_box.offsetWidth < proxyData.screenInfo.screenWidth) {
  386. return;
  387. }
  388. if (e.touches[0].pageX - e.mation.disX > 0) {
  389. matrix_box.style.left = 0 + "px";
  390. } else {
  391. matrix_box.style.left =
  392. e.touches[0].pageX - e.mation.disX + "px";
  393. }
  394. }
  395. },
  396. swipeDown: function (e: any) {
  397. if (!proxyData.displacement.moveable) {
  398. let height: any =
  399. proxyData.screenInfo.screenHeight - houseHeight - 20;
  400. let boxHeight: any = matrix_box.offsetHeight;
  401. if (boxHeight < height) {
  402. matrix_box.style.top = 0 + "px";
  403. } else {
  404. if (e.touches[0].pageY - e.mation.disY > 0) {
  405. matrix_box.style.top = 0 + "px";
  406. } else {
  407. matrix_box.style.top =
  408. e.touches[0].pageY - e.mation.disY + "px";
  409. }
  410. }
  411. }
  412. },
  413. swipeUp: function (e: any) {
  414. if (!proxyData.displacement.moveable) {
  415. let houseDesDom = document.querySelector("#houseDes");
  416. let houseHeight: any = houseDesDom ? houseDesDom.offsetHeight : 0;
  417. let height: any =
  418. proxyData.screenInfo.screenHeight - houseHeight - 20;
  419. let boxHeight: any = matrix_box.offsetHeight;
  420. let top: any = e.touches[0].pageY - e.mation.disY;
  421. if (boxHeight < height) {
  422. matrix_box.style.top = 0 + "px";
  423. } else {
  424. if (boxHeight - Math.abs(top) < height / 2) {
  425. matrix_box.style.top = -(boxHeight - height / 2) + "px";
  426. } else {
  427. matrix_box.style.top =
  428. e.touches[0].pageY - e.mation.disY + "px";
  429. }
  430. }
  431. }
  432. },
  433. drag: function (e: any) {},
  434. });
  435. },
  436. /**
  437. * 关闭搜索页面
  438. * @param item
  439. */
  440. closeSearch(item: any) {
  441. proxyData.showSearch = false;
  442. // 搜索页面过来的
  443. if (item) {
  444. proxyData.isSetSearchSpace = true;
  445. proxyData.loadingStart();
  446. let searchSpace: any = {
  447. buildingId: item.buildingId,
  448. buildingName: "",
  449. floorId: item.floorId,
  450. floorName: "",
  451. spaceId: item.id,
  452. };
  453. proxyData.init(searchSpace);
  454. } else {
  455. proxyData.isSetSearchSpace = false;
  456. }
  457. },
  458. /*
  459. 去搜索页面
  460. */
  461. goSearch() {
  462. proxyData.showSearch = true;
  463. // router.push({ path: '/search' })
  464. },
  465. /**
  466. * 设置选中的空间的位置,
  467. */
  468. setSelectSpacePosition(area: any) {
  469. setTimeout(() => {
  470. proxyData.setScrollLeft(area);
  471. proxyData.scrollTop(area);
  472. });
  473. },
  474. /**
  475. * 判断像左还是像右滚动
  476. */
  477. setScrollLeft(area: any) {
  478. let mapBoxEle = document.querySelector("#spaceMain");
  479. let left: any = 0;
  480. if (area.left + area.width >= proxyData.screenInfo.screenWidth / 2) {
  481. left =
  482. area.left - proxyData.screenInfo.screenWidth / 2 + area.width / 2;
  483. left = ~left;
  484. } else {
  485. left = 0;
  486. }
  487. if (left > 0) {
  488. left = 0;
  489. }
  490. if (
  491. Math.abs(left) >
  492. mapBoxEle.offsetWidth - proxyData.screenInfo.screenWidth
  493. ) {
  494. left = -(mapBoxEle.offsetWidth - proxyData.screenInfo.screenWidth);
  495. }
  496. mapBoxEle.style.left = left + "px";
  497. },
  498. /**
  499. * 获取竖着的方向
  500. */
  501. scrollTop(area: any) {
  502. let mapDom = document.querySelector("#map");
  503. let mapBoxEle = document.querySelector("#spaceMain");
  504. let houseDesDom = document.querySelector("#houseDes");
  505. let houseHeight: any = houseDesDom ? houseDesDom.offsetHeight : 0;
  506. let top: any = 0;
  507. if (
  508. area.top + area.width >
  509. (proxyData.screenInfo.screenHeight - houseHeight - 20) / 2
  510. ) {
  511. top =
  512. area.top -
  513. (proxyData.screenInfo.screenHeight - houseHeight) / 2 +
  514. area.height / 2;
  515. } else {
  516. top = 0;
  517. }
  518. top = ~top;
  519. if (top > 0) {
  520. top = 0;
  521. }
  522. mapBoxEle.style.top = top + "px";
  523. },
  524. /**
  525. * 切换空间
  526. */
  527. checkSpace(area: any) {
  528. if (area.disabled) {
  529. // 如果不在
  530. Toast("该空间和平板没绑定,暂不支持查看");
  531. return;
  532. }
  533. proxyData.isSetSearchSpace = false;
  534. if (area && area.canClick) {
  535. if (proxyData.mapType == 1) {
  536. proxyData.setSelectSpacePosition(area);
  537. }
  538. proxyData.selectArea = area;
  539. proxyData.selectArea.buildingId = proxyData.buildingItem.buildingId;
  540. proxyData.setLocalSpaceInfo();
  541. contx.emit("changeSpace", proxyData.selectArea);
  542. } else {
  543. Toast("不可选区域");
  544. }
  545. },
  546. /**
  547. * 确认设置为常驻空间
  548. */
  549. comfirSetSpace(item: any) {
  550. if (item.spaceId === props.spaceInfo.spaceId) {
  551. Dialog.confirm({
  552. title: "取消常驻空间",
  553. confirmButtonColor: "#000000",
  554. cancelButtonColor: "#4D5262",
  555. message: `
  556. 是否取消常驻空间设置 ? `,
  557. })
  558. .then(() => {
  559. contx.emit("delPermanentSpace");
  560. })
  561. .catch(() => {});
  562. } else {
  563. Dialog.confirm({
  564. title: "设置常驻空间",
  565. confirmButtonColor: "#000000",
  566. cancelButtonColor: "#4D5262",
  567. message: `是否将常驻空间设置为${item.localName}?`,
  568. })
  569. .then(() => {
  570. proxyData.selectArea = item;
  571. contx.emit("changeSpaceId", proxyData.selectArea.spaceId);
  572. })
  573. .catch(() => {});
  574. }
  575. },
  576. /**
  577. * 本地缓存最新的空间建筑信息,提供给首次进入页面使用
  578. */
  579. setLocalSpaceInfo() {
  580. localStorageSpaceId(
  581. proxyData.buildingItem.buildingId,
  582. proxyData.floorItem.id,
  583. proxyData.selectArea.spaceId
  584. );
  585. let spaceInfo: any = {
  586. buildingId: proxyData.buildingItem.buildingId,
  587. buildingName: proxyData.buildingItem.localName,
  588. floorId: proxyData.floorItem.id,
  589. floorName: proxyData.floorItem.localName,
  590. spaceId: proxyData.selectArea.spaceId, // 上格云3
  591. };
  592. setLocalNewSpaceInfo(spaceInfo);
  593. },
  594. /**
  595. * 地图放大的距离
  596. * @param start
  597. * @param stop
  598. */
  599. getDistance(start: any, stop: any) {
  600. return Math.hypot(stop.x - start.x, stop.y - start.y);
  601. },
  602. /**
  603. * 格式化地图数据
  604. */
  605. formateMapData() {
  606. let spaceData: any = props.spaceData;
  607. let data: any = proxyData.mapData;
  608. if (data) {
  609. proxyData.setSpaceScale();
  610. proxyData.setTempScale();
  611. if (data.width < 3000) {
  612. proxyData.comMapScale = 0.8;
  613. }
  614. data.width = data.width * proxyData.comMapScale;
  615. data.height = data.height * proxyData.comMapScale;
  616. let spaceList: any = data?.spaceList ?? [];
  617. for (let i = 0; i < spaceList.length; i++) {
  618. let item = spaceList[i];
  619. item.width = item.width * proxyData.comMapScale;
  620. item.height = item.height * proxyData.comMapScale;
  621. item.top = item.top * proxyData.comMapScale;
  622. item.left = item.left * proxyData.comMapScale;
  623. let flag: any = true;
  624. for (let j = 0; j < spaceData.length; j++) {
  625. if (item.spaceId === spaceData[j].spaceId) {
  626. flag = false;
  627. break;
  628. }
  629. }
  630. if (flag) {
  631. item.disabled = true;
  632. }
  633. // item.canClick = !item.canClick
  634. proxyData.setSpaceIcon(item);
  635. }
  636. // 备份数据
  637. proxyData.copyMapDaata = JSON.parse(JSON.stringify(data));
  638. }
  639. },
  640. // 格式化地图(四川大厦)
  641. formateSpecialMapData() {
  642. let data: any = proxyData.mapData;
  643. if (data) {
  644. data.width = data.width * proxyData.comMapScale;
  645. data.height = data.height * proxyData.comMapScale;
  646. let spaceList: any = data.spaceList || [];
  647. spaceList.map((item: any) => {
  648. let remark: any = item.remark;
  649. if (remark) {
  650. let remarkObj: any = JSON.parse(remark);
  651. item.roomFuncType = "300";
  652. item.fillColor = "#fff";
  653. item.canClick = remarkObj.canClick;
  654. item.localName = remarkObj.localName;
  655. item.pointArr = remarkObj.pointArr;
  656. item.logoPointArr = remarkObj.logoPointArr;
  657. item.circlePointArr = remarkObj.circlePointArr;
  658. item.detailPointArr = remarkObj.detailPointArr;
  659. item.devicePointArr = remarkObj.devicePointArr;
  660. proxyData.setSpaceIcon(item);
  661. item.pointArr.map((dev: any) => {
  662. dev.left = dev.left * proxyData.comMapScale;
  663. dev.top = dev.top * proxyData.comMapScale;
  664. });
  665. item.logoPointArr.map((dev: any) => {
  666. dev.left = dev.left * proxyData.comMapScale;
  667. dev.top = (dev.top * 1 - 15) * proxyData.comMapScale;
  668. });
  669. item.circlePointArr.map((dev: any) => {
  670. dev.left = dev.left * proxyData.comMapScale;
  671. dev.top = dev.top * proxyData.comMapScale;
  672. });
  673. }
  674. });
  675. // 原始数据* proxyData.comMapScale
  676. proxyData.copyMapDaata = JSON.parse(JSON.stringify(data));
  677. }
  678. },
  679. // canvas画的地图缩放处理
  680. formateSpecialMapScale(scale: any) {
  681. let data: any = JSON.parse(JSON.stringify(proxyData.copyMapDaata));
  682. if (data) {
  683. data.width = data.width * scale;
  684. data.height = data.height * scale;
  685. let spaceList: any = data.spaceList || [];
  686. spaceList.map((item: any) => {
  687. item.pointArr.map((dev: any) => {
  688. dev.left = dev.left * scale;
  689. dev.top = dev.top * scale;
  690. });
  691. item.logoPointArr.map((dev: any) => {
  692. dev.left = dev.left * scale;
  693. dev.top = dev.top * scale;
  694. });
  695. item.circlePointArr.map((dev: any) => {
  696. dev.left = dev.left * scale;
  697. dev.top = dev.top * scale;
  698. });
  699. });
  700. proxyData.mapData = data;
  701. }
  702. },
  703. // 获取空间最小宽
  704. setSpaceScale() {
  705. let data: any = proxyData.mapData;
  706. if (data) {
  707. let spaceList: any = data?.spaceList ?? [];
  708. let minHeight: any = Math.min.apply(
  709. null,
  710. spaceList.map((item: any) => item.height)
  711. );
  712. let minWidth: any = Math.min.apply(
  713. null,
  714. spaceList.map((item: any) => item.width)
  715. );
  716. let min: any = minHeight < minWidth ? minHeight : minWidth;
  717. min = min ? min : 30;
  718. proxyData.comMapScale = 30 / min;
  719. }
  720. },
  721. // 缩放的临界值修改
  722. setTempScale() {
  723. proxyData.tempScale = 0.4;
  724. let data: any = proxyData.mapData;
  725. if (data) {
  726. let width: any = proxyData.mapData.width;
  727. let height: any = proxyData.mapData.height;
  728. if (width > height) {
  729. let num: any = Math.ceil(width / proxyData.screenInfo.screenWidth);
  730. if (num < 10) {
  731. proxyData.tempScale = 0.4;
  732. } else if (num < 20) {
  733. proxyData.tempScale = 0.3;
  734. } else {
  735. proxyData.tempScale = 0.25;
  736. }
  737. } else {
  738. let num: any = Math.ceil(
  739. height / proxyData.screenInfo.screenHeight
  740. );
  741. if (num < 10) {
  742. proxyData.tempScale = 0.4;
  743. } else if (num < 20) {
  744. proxyData.tempScale = 0.3;
  745. } else {
  746. proxyData.tempScale = 0.25;
  747. }
  748. }
  749. }
  750. },
  751. /**
  752. * 设置地图最外框宽和高
  753. */
  754. setMapBoxStyle(type: any = 0) {
  755. let mapBoxEle = document.querySelector("#spaceMain");
  756. if (proxyData.mapData && proxyData.mapData.width) {
  757. mapBoxEle.style.width = proxyData.mapData.width + "px";
  758. mapBoxEle.style.height = proxyData.mapData.height + "px";
  759. }
  760. if (proxyData.mapType == 2) {
  761. if (type == 0) {
  762. canvasRef.value.init(proxyData.mapData);
  763. } else {
  764. canvasRef.value.scaleCanvas(proxyData.mapData);
  765. }
  766. }
  767. },
  768. /**
  769. * 设置空间的图标
  770. *
  771. */
  772. setSpaceIcon(item: any) {
  773. // if(item.can)
  774. if (item.canClick) {
  775. let typeName: any = getSpaceType(item.roomFuncType);
  776. item.icon = mapIcon[typeName].icon;
  777. item.selectIcon = mapIcon[typeName].selectIcon;
  778. item.backgroundColor = mapIcon[typeName].backgroundColor;
  779. item.bg = mapIcon[typeName].bg;
  780. item.icon = parseImgUrl("map-new-icon", item.icon);
  781. item.selectIcon = parseImgUrl("map-new-icon", item.selectIcon);
  782. } else {
  783. item.icon = "";
  784. }
  785. },
  786. midpoint(x1: any, y1: any, x2: any, y2: any) {
  787. return [x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2];
  788. // return [x1 + x2 / 2, y1 + (y2 - y1)]
  789. },
  790. /**
  791. * 更新地图的宽高
  792. */
  793. updateMapStyle() {
  794. if (proxyData.mapType == 1) {
  795. // 方形地图处理
  796. let data: any = JSON.parse(JSON.stringify(proxyData.copyMapDaata));
  797. if (data) {
  798. let spaceList: any = data?.spaceList ?? [];
  799. data.width = data.width * proxyData.displacement.scale;
  800. data.height = data.height * proxyData.displacement.scale;
  801. for (let i = 0; i < spaceList.length; i++) {
  802. let item = spaceList[i];
  803. item.width = item.width * proxyData.displacement.scale;
  804. item.height = item.height * proxyData.displacement.scale;
  805. item.top = item.top * proxyData.displacement.scale;
  806. item.left = item.left * proxyData.displacement.scale;
  807. }
  808. proxyData.mapData = data;
  809. }
  810. } else {
  811. // canvas画的地图逻辑处理
  812. proxyData.formateSpecialMapScale(proxyData.displacement.scale);
  813. }
  814. proxyData.setMapBoxStyle(1);
  815. },
  816. /**
  817. * 更新地图的位置
  818. */
  819. updateMapPositon(temp: any, matrix_box: any) {
  820. let left: any =
  821. proxyData.displacement.scaleCenter[0] -
  822. proxyData.displacement.scaleCenter[0] * proxyData.displacement.scale;
  823. let top: any =
  824. proxyData.displacement.scaleCenter[1] -
  825. proxyData.displacement.scaleCenter[1] * proxyData.displacement.scale;
  826. if (temp > 0 && proxyData.displacement.scale < 1) {
  827. if (left > 0) {
  828. left = ~left;
  829. }
  830. if (top > 0) {
  831. top = ~top;
  832. // top = 0
  833. }
  834. }
  835. let newTop: any =
  836. proxyData.displacement.top * proxyData.displacement.scale + top;
  837. let newLeft: any =
  838. proxyData.displacement.left * proxyData.displacement.scale + left;
  839. if (matrix_box.offsetWidth < proxyData.screenInfo.screenWidth) {
  840. newLeft = 0;
  841. }
  842. if (newLeft > 0) {
  843. matrix_box.style.left = 0 + "px";
  844. } else {
  845. matrix_box.style.left = newLeft + "px";
  846. }
  847. if (matrix_box.offsetHeight < proxyData.screenInfo.screenHeight) {
  848. matrix_box.style.top = 0;
  849. } else {
  850. if (newTop > 0) {
  851. matrix_box.style.top = 0;
  852. } else {
  853. matrix_box.style.top = newTop + "px";
  854. }
  855. }
  856. },
  857. /**
  858. * 地图缩放功能
  859. */
  860. mapScale() {
  861. let matrix_box: any = document.querySelector("#spaceMain");
  862. matrix_box.addEventListener(
  863. "touchstart",
  864. function (event: any) {
  865. let touches: any = event.touches;
  866. let events: any = touches[0];
  867. let events2: any = touches[1];
  868. // 第一个触摸点的坐标
  869. proxyData.displacement.pageX = events.pageX;
  870. proxyData.displacement.pageY = events.pageY;
  871. proxyData.displacement.moveable = true;
  872. proxyData.displacement.originScale =
  873. proxyData.displacement.scale || 1;
  874. if (events2) {
  875. proxyData.displacement.pageX2 = events2.pageX;
  876. proxyData.displacement.pageY2 = events2.pageY;
  877. let left: any = isNaN(parseInt(matrix_box.style.left))
  878. ? 0
  879. : parseInt(matrix_box.style.left);
  880. let top: any = isNaN(parseInt(matrix_box.style.top))
  881. ? 0
  882. : parseInt(matrix_box.style.top);
  883. proxyData.displacement.center = proxyData.midpoint(
  884. events.pageX,
  885. events.pageY,
  886. events2.pageX,
  887. events2.pageY
  888. );
  889. proxyData.displacement.left = left / proxyData.displacement.scale;
  890. proxyData.displacement.top = top / proxyData.displacement.scale;
  891. proxyData.displacement.scaleCenter = [
  892. proxyData.displacement.center[0] / proxyData.displacement.scale,
  893. proxyData.displacement.center[1] / proxyData.displacement.scale,
  894. ];
  895. proxyData.displacement.scaleTranslateProportion = [
  896. proxyData.displacement.scaleCenter[0] /
  897. (matrix_box.offsetWidth / proxyData.displacement.scale),
  898. proxyData.displacement.scaleCenter[1] /
  899. (matrix_box.offsetHeight / proxyData.displacement.scale),
  900. ];
  901. proxyData.displacement.oldSize = [
  902. matrix_box.offsetWidth / proxyData.displacement.scale,
  903. matrix_box.offsetHeight / proxyData.displacement.scale,
  904. ];
  905. } else {
  906. proxyData.displacement.moveable = false;
  907. }
  908. },
  909. { passive: true }
  910. );
  911. matrix_box.addEventListener(
  912. "touchmove",
  913. function (event: any) {
  914. if (!proxyData.displacement.moveable) {
  915. return;
  916. }
  917. // event.preventDefault();
  918. let touches: any = event.touches;
  919. let events: any = touches[0];
  920. let events2: any = touches[1];
  921. // 双指移动
  922. if (events2) {
  923. // 第2个指头坐标在touchmove时候获取
  924. if (!proxyData.displacement.pageX2) {
  925. proxyData.displacement.pageX2 = events2.pageX;
  926. }
  927. if (!proxyData.displacement.pageY2) {
  928. proxyData.displacement.pageY2 = events2.pageY;
  929. }
  930. // 双指缩放比例计算
  931. let zoom: any =
  932. proxyData.getDistance(
  933. {
  934. x: events.pageX,
  935. y: events.pageY,
  936. },
  937. {
  938. x: events2.pageX,
  939. y: events2.pageY,
  940. }
  941. ) /
  942. proxyData.getDistance(
  943. {
  944. x: proxyData.displacement.pageX,
  945. y: proxyData.displacement.pageY,
  946. },
  947. {
  948. x: proxyData.displacement.pageX2,
  949. y: proxyData.displacement.pageY2,
  950. }
  951. );
  952. // 应用在元素上的缩放比例
  953. let newScale: any = proxyData.displacement.originScale * zoom;
  954. if (newScale < proxyData.tempScale) {
  955. newScale = proxyData.tempScale;
  956. }
  957. // 最大缩放比例限制
  958. if (newScale > 1.5) {
  959. newScale = 1.5;
  960. }
  961. let temp: any = newScale - proxyData.displacement.scale;
  962. proxyData.displacement.scale = newScale;
  963. if (temp !== 0) {
  964. proxyData.updateMapPositon(temp, matrix_box);
  965. proxyData.updateMapStyle();
  966. }
  967. }
  968. },
  969. { passive: true }
  970. );
  971. matrix_box.addEventListener("touchend", function () {
  972. proxyData.displacement.moveable = true;
  973. });
  974. },
  975. /**
  976. * 获取建筑信息
  977. */
  978. getBuildingList() {
  979. let params: any = {
  980. criteria: {
  981. projectId: props.projectId,
  982. },
  983. orders: [
  984. {
  985. asc: true,
  986. column: "localId",
  987. },
  988. ],
  989. };
  990. getBuildingList(params).then((res) => {
  991. let resData: any = res;
  992. if (resData.result === "success") {
  993. let content: any = resData?.content ?? [];
  994. proxyData.buildingData = content;
  995. // 设置展示的建筑名称
  996. proxyData.setBuildingName();
  997. }
  998. });
  999. },
  1000. /**
  1001. *
  1002. * 选择建筑
  1003. */
  1004. checkBuilding() {
  1005. proxyData.showBuilding = true;
  1006. },
  1007. /**
  1008. * 选择楼层
  1009. */
  1010. checkFloor() {
  1011. proxyData.showFloor = true;
  1012. },
  1013. /**
  1014. * 确定选择的楼层信息
  1015. */
  1016. comfirmFloor(item: any, flag: boolean = true) {
  1017. if (item == "4555556") {
  1018. proxyData.floorItem = {
  1019. id: "4555556",
  1020. };
  1021. proxyData.mapType = 2;
  1022. } else {
  1023. proxyData.floorItem = item;
  1024. proxyData.mapType = 1;
  1025. }
  1026. proxyData.showFloor = false;
  1027. // 获取地图数据
  1028. proxyData.loadingStart();
  1029. proxyData.getMapInfo(flag);
  1030. /**
  1031. *缓存建筑对应的楼层
  1032. */
  1033. localStorageFloor(
  1034. proxyData.buildingItem.buildingId,
  1035. proxyData.floorItem.id
  1036. );
  1037. },
  1038. /**
  1039. * 确定建筑
  1040. */
  1041. comfirmBuilding(item: any) {
  1042. proxyData.showBuilding = false;
  1043. proxyData.buildingItem.buildingId = item.id;
  1044. proxyData.buildingItem.localName = item.localName;
  1045. proxyData.loadingStart();
  1046. proxyData.getFloorList();
  1047. },
  1048. /**
  1049. * 加载loading
  1050. */
  1051. loadingStart() {
  1052. Toast.loading({
  1053. duration: 0, // 持续展示 toast
  1054. forbidClick: true,
  1055. message: "加载中...",
  1056. });
  1057. },
  1058. /**
  1059. * 结束
  1060. */
  1061. loadinngEnd() {
  1062. Toast.clear();
  1063. },
  1064. /**
  1065. * 查询楼层信息
  1066. */
  1067. getFloorList(flag: boolean = true) {
  1068. if (proxyData.buildingItem.buildingId) {
  1069. let params: any = {
  1070. criteria: {
  1071. projectId: props.projectId,
  1072. buildingId: proxyData.buildingItem.buildingId,
  1073. },
  1074. orders: [
  1075. {
  1076. asc: true,
  1077. column: "localId",
  1078. },
  1079. ],
  1080. };
  1081. getFloorList(params)
  1082. .then((res) => {
  1083. let resData: any = res;
  1084. if (res.result === "success") {
  1085. proxyData.floorData = resData?.content ?? [];
  1086. // 设置楼层的名称
  1087. proxyData.setFloorName();
  1088. } else {
  1089. proxyData.floorData = [];
  1090. }
  1091. if (flag && proxyData.floorData.length) {
  1092. proxyData.getHistorySelectFloor();
  1093. proxyData.getMapInfo();
  1094. }
  1095. proxyData.loadinngEnd();
  1096. })
  1097. .catch(() => {
  1098. proxyData.loadinngEnd();
  1099. });
  1100. }
  1101. },
  1102. /**
  1103. * 获取地图信息
  1104. */
  1105. getMapInfo(flag: boolean = true, searchItem: any = null) {
  1106. let params: any = {
  1107. projectId: props.projectId,
  1108. floorId: proxyData.floorItem.id,
  1109. };
  1110. getMapInfo(params)
  1111. .then((res) => {
  1112. let resData: any = res;
  1113. if (resData.result === "success") {
  1114. // 默认地图
  1115. proxyData.mapData = resData?.data ?? null;
  1116. // 切换数据的时候清楚默认样式
  1117. proxyData.clearPreStyle();
  1118. if (proxyData.mapType === 2) {
  1119. proxyData.formateSpecialMapData();
  1120. } else {
  1121. proxyData.formateMapData();
  1122. }
  1123. // 首次进入页面的时候展示空间来源于父div
  1124. if (searchItem) {
  1125. let area = proxyData.getFirstSelectSpace(searchItem);
  1126. if (area) {
  1127. proxyData.selectArea = area;
  1128. }
  1129. }
  1130. proxyData.setSelectSpacePosition(proxyData.selectArea);
  1131. // 接口返回后设置地图缩放和滚动
  1132. nextTick(() => {
  1133. // 地图双指缩放
  1134. proxyData.setMapBoxStyle();
  1135. proxyData.mapScale();
  1136. proxyData.mapScroll();
  1137. });
  1138. }
  1139. })
  1140. .catch(() => {
  1141. proxyData.loadinngEnd();
  1142. });
  1143. },
  1144. /**
  1145. * 获取缓存的楼层
  1146. */
  1147. getHistorySelectFloor() {
  1148. let historyFloor: any = getLocalStorageFloor();
  1149. let flag: any = false;
  1150. let floorId: any = historyFloor[proxyData.buildingItem.buildingId];
  1151. proxyData.floorData.map((floor: any) => {
  1152. if (floor.id === floorId) {
  1153. flag = true;
  1154. proxyData.floorItem = floor;
  1155. }
  1156. });
  1157. if (!flag) {
  1158. proxyData.floorItem = proxyData.floorData[0];
  1159. }
  1160. },
  1161. /**
  1162. * 获取选中的选中空间
  1163. */
  1164. getHistorySpace() {
  1165. let data: any = proxyData.mapData;
  1166. let historySpace: any = getStorageSpaceId();
  1167. if (data) {
  1168. let flag: boolean = false;
  1169. let spaceList = data?.spaceList ?? [];
  1170. let key: any = `${proxyData.buildingItem.buildingId},${proxyData.floorItem.id}`;
  1171. let spaceId: any = historySpace[key];
  1172. if (spaceId) {
  1173. spaceList.map((space: any) => {
  1174. if (spaceId === space.spaceId) {
  1175. proxyData.selectArea = space;
  1176. flag = true;
  1177. }
  1178. });
  1179. }
  1180. if (!flag) {
  1181. for (let i: any = 0; i < spaceList.length; i++) {
  1182. if (spaceList[i].canClick) {
  1183. proxyData.selectArea = spaceList[i];
  1184. break;
  1185. }
  1186. }
  1187. }
  1188. }
  1189. },
  1190. /**
  1191. * 首次进入页面设置选中的空间
  1192. */
  1193. getFirstSelectSpace(item: any) {
  1194. let area: any = null;
  1195. let data: any = proxyData.mapData;
  1196. if (data && item) {
  1197. let spaceList = data?.spaceList ?? [];
  1198. for (let i = 0; i < spaceList.length; i++) {
  1199. if (spaceList[i].spaceId === item.spaceId) {
  1200. // proxyData.selectArea = spaceList[i]
  1201. area = spaceList[i];
  1202. break;
  1203. }
  1204. }
  1205. }
  1206. return area;
  1207. },
  1208. setDefaultSpace(item: any) {
  1209. if (item) {
  1210. proxyData.buildingItem.buildingId = item.buildingId;
  1211. proxyData.buildingItem.localName = item.buildingName
  1212. ? item.buildingName
  1213. : "";
  1214. proxyData.floorItem = {
  1215. id: item.floorId,
  1216. localName: item.floorName ? item.floorName : "",
  1217. };
  1218. }
  1219. },
  1220. // 设备模块初始化地图
  1221. init(item: any) {
  1222. if (item) {
  1223. proxyData.setDefaultSpace(item);
  1224. }
  1225. proxyData.getBuildingList();
  1226. proxyData.getFloorList(false);
  1227. proxyData.getMapInfo(false, item);
  1228. },
  1229. /**
  1230. *搜索后设置建筑的localName
  1231. */
  1232. setBuildingName() {
  1233. if (proxyData.buildingItem.buildingId) {
  1234. proxyData.buildingData.map((item: any) => {
  1235. if (item.id === proxyData.buildingItem.buildingId) {
  1236. proxyData.buildingItem.localName = item.localName;
  1237. }
  1238. });
  1239. } else {
  1240. // 设置常驻空间的时候使用
  1241. proxyData.buildingItem = {
  1242. buildingId: proxyData.buildingData[0].id,
  1243. localName: proxyData.buildingData[0].localName,
  1244. };
  1245. }
  1246. },
  1247. /**
  1248. * 搜索页面回来根据id设置楼层的localName
  1249. */
  1250. setFloorName() {
  1251. if (proxyData.floorItem.id) {
  1252. proxyData.floorData.map((item: any) => {
  1253. if (item.id === proxyData.floorItem.id) {
  1254. proxyData.floorItem.localName = item.localName;
  1255. }
  1256. });
  1257. } else {
  1258. // 设置常驻空间的时候使用
  1259. proxyData.floorItem = proxyData.floorData[0];
  1260. }
  1261. },
  1262. });
  1263. watch(props, (newProps: any) => {}, {
  1264. deep: false,
  1265. immediate: true,
  1266. });
  1267. onMounted(() => {
  1268. proxyData.spaceInfo = props.spaceInfo;
  1269. proxyData.buildingItem.buildingId = props.buildingId;
  1270. proxyData.floorItem.id = props.floorId;
  1271. proxyData.spaceInfo.buildingId = props.buildingId;
  1272. proxyData.spaceInfo.floorId = props.floorId;
  1273. proxyData.selectArea.spaceId = props.spaceInfo.spaceId;
  1274. proxyData.init(proxyData.spaceInfo);
  1275. });
  1276. return {
  1277. canvasRef,
  1278. ...toRefs(proxyData),
  1279. };
  1280. },
  1281. });
  1282. </script>
  1283. <style lang="scss" scoped>
  1284. .space-main {
  1285. width: 100%;
  1286. height: 100%;
  1287. position: relative;
  1288. background: #f7f8fa;
  1289. transform-origin: 0 0;
  1290. transition: transform 0.3s;
  1291. transform: scale(1);
  1292. //transform: translateX(-100px) !important;
  1293. padding: 0 5px;
  1294. overflow: hidden;
  1295. .canvasBox {
  1296. position: absolute;
  1297. left: 0;
  1298. top: 0;
  1299. z-index: -1;
  1300. }
  1301. .space-box {
  1302. position: absolute;
  1303. padding: 5px;
  1304. }
  1305. .space-disable-box {
  1306. // opacity: 0.4;
  1307. }
  1308. .space-box-bg {
  1309. // background: #5e8bcf;
  1310. background: rgba(94, 139, 207, 0.4) !important;
  1311. border: 2px solid rgba(94, 139, 207, 0.8);
  1312. border-radius: 5px;
  1313. // color: #fff;
  1314. .select-device {
  1315. span {
  1316. color: #fff !important;
  1317. }
  1318. }
  1319. .device span {
  1320. color: #fff !important;
  1321. font-size: 16px;
  1322. }
  1323. }
  1324. .space {
  1325. position: relative;
  1326. width: 100%;
  1327. height: 100%;
  1328. box-shadow: 0px 1px 4px rgba(1, 1, 51, 0.01),
  1329. 0px 16px 40px rgba(1, 1, 51, 0.03);
  1330. border-radius: 4px;
  1331. box-sizing: border-box;
  1332. .device {
  1333. position: absolute;
  1334. left: 50%;
  1335. top: 50%;
  1336. transform: translate(-50%, -50%);
  1337. text-align: center;
  1338. z-index: 666;
  1339. img {
  1340. //margin-bottom: 6px;
  1341. }
  1342. span {
  1343. display: block;
  1344. word-break: keep-all;
  1345. white-space: nowrap;
  1346. //font-size: 12px;
  1347. color: #8995ba;
  1348. font-weight: 600;
  1349. }
  1350. }
  1351. .select-device {
  1352. transform: translate(-50%, -70%);
  1353. img {
  1354. margin-bottom: 6px;
  1355. }
  1356. }
  1357. .circle {
  1358. width: 4px;
  1359. height: 4px;
  1360. border-radius: 50%;
  1361. position: absolute;
  1362. top: 50%;
  1363. left: 50%;
  1364. transform: translateX(-50%) translateY(-50%);
  1365. }
  1366. }
  1367. .select {
  1368. border: 2px solid rgba(77, 148, 255, 0.8);
  1369. }
  1370. .select-disable {
  1371. border: 2px solid rgba(77, 148, 255, 0.2);
  1372. }
  1373. .use-select {
  1374. border: 5px solid #ffe823;
  1375. }
  1376. &::-webkit-scrollbar {
  1377. display: none;
  1378. }
  1379. }
  1380. .map-toolbar {
  1381. position: fixed;
  1382. width: 44px;
  1383. right: 20px;
  1384. z-index: 999;
  1385. top: 50%;
  1386. transform: translateY(-50%);
  1387. .icon-search {
  1388. width: 44px;
  1389. height: 44px;
  1390. border-radius: 5px;
  1391. background: #fff;
  1392. }
  1393. .toolbar-item {
  1394. width: 44px;
  1395. height: 44px;
  1396. background: #ffffff;
  1397. box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.1), 0px 4px 8px rgba(0, 0, 0, 0.1);
  1398. border-radius: 4px;
  1399. margin-top: 10px;
  1400. text-align: center;
  1401. .toolbar-menu {
  1402. width: 44px;
  1403. }
  1404. img {
  1405. width: 12px;
  1406. height: 14px;
  1407. margin-top: 15px;
  1408. }
  1409. }
  1410. .text-hidden {
  1411. //font-family: Montserrat;
  1412. display: block;
  1413. font-style: normal;
  1414. width: 44px;
  1415. line-height: 44px;
  1416. font-weight: 500;
  1417. font-size: 16px;
  1418. text-align: center;
  1419. color: #4d5262;
  1420. overflow: hidden;
  1421. text-overflow: ellipsis;
  1422. white-space: nowrap;
  1423. }
  1424. }
  1425. .buiding-item {
  1426. //font-family: 'Montserrat';
  1427. width: 100%;
  1428. padding: 10px;
  1429. font-style: normal;
  1430. font-weight: 500;
  1431. font-size: 14px;
  1432. text-align: left;
  1433. color: rgba(13, 13, 61, 0.86);
  1434. border-bottom: 1px solid rgba(2, 2, 82, 0.03);
  1435. }
  1436. .active {
  1437. color: rgba(77, 148, 255, 0.8);
  1438. }
  1439. </style>