hookehuyr

新增弹框组件

...@@ -9,7 +9,12 @@ export {} ...@@ -9,7 +9,12 @@ export {}
9 9
10 declare module '@vue/runtime-core' { 10 declare module '@vue/runtime-core' {
11 export interface GlobalComponents { 11 export interface GlobalComponents {
12 + 2: typeof import('./src/components/InfoWindow copy 2.vue')['default']
13 + copy: typeof import('./src/components/InfoWindow copy.vue')['default']
12 InfoWindow: typeof import('./src/components/InfoWindow.vue')['default'] 14 InfoWindow: typeof import('./src/components/InfoWindow.vue')['default']
15 + InfoWindowLite: typeof import('./src/components/InfoWindowLite.vue')['default']
16 + InfoWindowSingle: typeof import('./src/components/InfoWindowSingle.vue')['default']
17 + InfoWindowWarn: typeof import('./src/components/InfoWindowWarn.vue')['default']
13 RouterLink: typeof import('vue-router')['RouterLink'] 18 RouterLink: typeof import('vue-router')['RouterLink']
14 RouterView: typeof import('vue-router')['RouterView'] 19 RouterView: typeof import('vue-router')['RouterView']
15 VanCol: typeof import('vant/es')['Col'] 20 VanCol: typeof import('vant/es')['Col']
......
...@@ -341,6 +341,31 @@ export default { ...@@ -341,6 +341,31 @@ export default {
341 // background-size: 6.5rem 3rem; 341 // background-size: 6.5rem 3rem;
342 // } 342 // }
343 // } 343 // }
344 +
345 + .info-window-title {
346 + display: flex;
347 + overflow-x: scroll;
348 + overflow-y: hidden;
349 + -webkit-overflow-scrolling: touch;
350 + position: relative;
351 + text-align: left;
352 +
353 + .item {
354 + width: 33.333%;
355 + flex-shrink: 0;
356 + color: #888;
357 + font-size: 1.1rem;
358 + margin-bottom: 0.75rem;
359 + display: inline-block;
360 + }
361 +
362 + .checked {
363 + color: #AB8F57;
364 + span {
365 + border-bottom: 1.5px solid #AB8F57; padding-bottom: 3px;
366 + }
367 + }
368 + }
344 } 369 }
345 370
346 .leaflet-popup-tip-container { 371 .leaflet-popup-tip-container {
...@@ -362,28 +387,4 @@ export default { ...@@ -362,28 +387,4 @@ export default {
362 box-shadow: none; 387 box-shadow: none;
363 } 388 }
364 389
365 -.info-window-title {
366 - display: flex;
367 - overflow-x: scroll;
368 - overflow-y: hidden;
369 - -webkit-overflow-scrolling: touch;
370 - position: relative;
371 - text-align: left;
372 -
373 - .item {
374 - width: 33.333%;
375 - flex-shrink: 0;
376 - color: #888;
377 - font-size: 1.1rem;
378 - margin-bottom: 0.75rem;
379 - display: inline-block;
380 - }
381 -
382 - .checked {
383 - color: #AB8F57;
384 - span {
385 - border-bottom: 1.5px solid #AB8F57; padding-bottom: 3px;
386 - }
387 - }
388 -}
389 </style> 390 </style>
......
1 +<template>
2 + <div style="position: relative;">
3 + <div class="info-window-lite-wrapper">
4 + <div :style="{ width: (widow_info.width * 0.8) + 'px', overflow: 'auto' }">
5 + <div class="hideScrollBar info-window-title">
6 + <div class="checked">
7 + <span>{{ info.name }}</span>
8 + </div>
9 + </div>
10 + <div v-if="info?.details?.length > 3" @click="handleNavScroll()" style="position: fixed; right: 0.75rem; width: 1rem; background-color: #FFF;top: 1.5rem;">
11 + <van-icon v-if="!nav_scroll" name="arrow" color="#888" size="1.25rem" style="vertical-align: sub;" />
12 + <van-icon v-else name="arrow-left" color="#888" size="1.25rem" style="vertical-align: sub;" />
13 + </div>
14 + </div>
15 + <div class="van-hairline--top" style="margin: 1rem 0;">
16 + <div style="width: 100%; float: left; text-align: center; margin-top: 1rem;">
17 + <van-icon name="https://cdn.ipadbiz.cn/xys/map/%E5%89%8D%E5%BE%80@2x.png" size="1.5rem" color="#FFF"
18 + style="vertical-align: bottom;" />&nbsp;
19 + <span style="color: #AB8F57; font-size: 1.1rem;">前往</span>
20 + </div>
21 + </div>
22 + </div>
23 + <div class="leaflet-popup-tip-container" style="left: 50%; position: relative;">
24 + <div class="leaflet-popup-tip"></div>
25 + </div>
26 +
27 + <van-popup teleport="body" v-model:show="show_popup" position="bottom" :overlay="true"
28 + :style="{ padding: '1rem', height: '100%' }">
29 + <van-icon name="cross" size="1.35rem" @click="show_popup = false" style="float: right; color: gray;" />
30 + <div class="popup-wrapper">
31 + <div class="title">
32 + {{ popup_title }}
33 + </div>
34 + <div class="content" v-html="popup_content">
35 + </div>
36 + <video-player ref="videoPlayer" style="width: 100%; height: 10rem;"
37 + poster="https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100"
38 + :src="video_src" class="video-player vjs-big-play-centered" controls :loop="true" :volume="0.6"></video-player>
39 + </div>
40 + </van-popup>
41 + </div>
42 +</template>
43 +
44 +<script>
45 +import $ from 'jquery'
46 +
47 +export default {
48 + props: {
49 + infoWindow: {
50 + type: Object,
51 + default: () => { }
52 + },
53 + info: {
54 + type: Object,
55 + default: () => { }
56 + },
57 + rect: {
58 + type: Object,
59 + default: () => { }
60 + },
61 + },
62 + mounted() {
63 + },
64 + watch: {
65 + rect(val) {
66 + this.widow_info = val;
67 + },
68 + },
69 + data() {
70 + return {
71 + show_popup: false,
72 + popup_title: '',
73 + popup_content: '',
74 + video_src: '',
75 + ind: '',
76 + is_play: false,
77 + audio: new Audio(),
78 + widow_info: {},
79 + play_time: '00:00',
80 + isActive: 0,
81 + nav_scroll: false,
82 + }
83 + },
84 + methods: {
85 + // 关闭
86 + close() {
87 + console.warn(this.infoWindow);
88 + // 高德地图信息窗关闭的api
89 + this.infoWindow.close()
90 + },
91 + showDetail() {
92 + this.show_popup = true;
93 + this.popup_title = '三宝楼';
94 + this.popup_content = '尊敬的游客朋友们您好,欢迎来到西园寺,您现在所到的地方是“三宝楼......';
95 + this.video_src = 'https://video.pearvideo.com/mp4/short/20200209/cont-1650197-14888002-hd.mp4'
96 + },
97 + goTo(url) {
98 + location.href = this.info.details[this.isActive].url;
99 + },
100 + }
101 +}
102 +</script>
103 +
104 +<style lang="less">
105 +.info-window-lite-wrapper {
106 + background: #fff;
107 + color: #333;
108 + -webkit-box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
109 + box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
110 + text-align: left;
111 + border-radius: 5px;
112 + padding: 1.5rem 1.25rem;
113 + overflow: auto;
114 +
115 + .info-text {
116 + width: 100%;
117 + line-height: 1.5;
118 + float: left;
119 + color: #7A6C6C;
120 + }
121 + .info-text-audio {
122 + width: 80%;
123 + line-height: 1.5;
124 + float: left;
125 + color: #7A6C6C;
126 + }
127 +
128 + .info-control {
129 + width: 20%;
130 + float: left;
131 + text-align: center;
132 + color: #AB8F57;
133 +
134 + .control-play {
135 + text-align: center;
136 + margin-bottom: 0.5rem;
137 +
138 + i {
139 + margin-top: 0 !important;
140 + }
141 + }
142 + }
143 +
144 + // .t-popup-content {
145 + // position: relative;
146 + // width: 25rem;
147 + // padding: 0;
148 + // margin: 0;
149 + // border-radius: 0.1rem;
150 + // background: rgba(255, 255, 255, 0.9);
151 + // -webkit-box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
152 + // box-shadow: 0 0.02rem 0.05rem 0 rgba(0, 0, 0, 0.1);
153 + // line-height: 1.4;
154 +
155 + // .view-name {
156 + // margin: 0;
157 + // padding: 0.5rem;
158 + // width: 25rem;
159 + // height: 2.5rem;
160 + // font-size: 1.2rem;
161 + // text-indent: 0.2rem;
162 + // white-space: nowrap;
163 + // text-overflow: ellipsis;
164 + // color: #5b5b5b;
165 + // -webkit-box-sizing: border-box;
166 + // box-sizing: border-box;
167 + // border-bottom: solid 1px #e8e8e8;
168 + // border-radius: 0.1rem 0.1rem 0 0;
169 + // background: #f7f7f7;
170 + // overflow: hidden;
171 + // }
172 +
173 + // .view-photo {
174 + // display: block;
175 + // float: left;
176 + // margin: 0.5rem;
177 + // height: 100%;
178 + // width: 9rem;
179 + // height: 9rem;
180 + // border-radius: 3px;
181 + // }
182 +
183 + // .introduction {
184 + // float: left;
185 + // margin: 0.2rem 0;
186 + // width: 13.5rem;
187 + // height: 6.75rem;
188 + // font-size: 0.9rem;
189 + // color: #202020;
190 + // overflow: hidden;
191 + // }
192 +
193 + // // .control-play {
194 + // // display: block;
195 + // // float: left;
196 + // // margin-right: 0.5rem;
197 + // // width: 7rem;
198 + // // height: 3rem;
199 + // // border-radius: 2px;
200 + // // background: #ffdd02 center no-repeat;
201 + // // background-size: 6.5rem 3rem;
202 + // // }
203 +
204 + // .show-details {
205 + // display: block;
206 + // float: left;
207 + // width: 7rem;
208 + // height: 3rem;
209 + // border-radius: 2px;
210 + // background: #9196a9 center no-repeat;
211 + // background-size: 6.5rem 3rem;
212 + // }
213 + // }
214 +
215 + .info-window-title {
216 + display: flex;
217 + overflow-x: scroll;
218 + overflow-y: hidden;
219 + -webkit-overflow-scrolling: touch;
220 + position: relative;
221 + text-align: left;
222 +
223 + .item {
224 + width: 33.333%;
225 + flex-shrink: 0;
226 + color: #888;
227 + font-size: 1.1rem;
228 + margin-bottom: 0.75rem;
229 + display: inline-block;
230 + }
231 +
232 + .checked {
233 + color: #AB8F57;
234 + span {
235 + border-bottom: 1.5px solid #AB8F57; padding-bottom: 3px;
236 + }
237 + }
238 + }
239 +}
240 +
241 +.leaflet-popup-tip-container {
242 + margin-top: -1px;
243 + width: 2rem;
244 + height: 2rem;
245 + margin-left: -20px;
246 + overflow: hidden;
247 + pointer-events: none;
248 +}
249 +
250 +.leaflet-popup-tip {
251 + width: 1rem;
252 + height: 1rem;
253 + -webkit-transform: rotate(0);
254 + transform: rotate(0);
255 + background: transparent url(https://map.365daoyou.cn/web/images/info-sharp.png) center no-repeat;
256 + background-size: 1rem 1rem;
257 + box-shadow: none;
258 +}
259 +
260 +</style>
This diff is collapsed. Click to expand it.
1 <!-- 1 <!--
2 * @Date: 2023-05-19 14:54:27 2 * @Date: 2023-05-19 14:54:27
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2023-06-06 14:45:27 4 + * @LastEditTime: 2023-06-06 17:19:52
5 * @FilePath: /map-demo/src/views/index.vue 5 * @FilePath: /map-demo/src/views/index.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -86,6 +86,8 @@ ...@@ -86,6 +86,8 @@
86 <!-- 自定义组件InfoWindow,初始时需要隐藏 --> 86 <!-- 自定义组件InfoWindow,初始时需要隐藏 -->
87 <!-- 隐藏不要使用v-if,因为我们需要渲染完成后的原生html结构作为信息框的dom对象使用 --> 87 <!-- 隐藏不要使用v-if,因为我们需要渲染完成后的原生html结构作为信息框的dom对象使用 -->
88 <InfoWindow v-show="showInfoWindow" ref="infoWindow" :info-window="infoWindow" :info="itemInfo" :rect="rect"></InfoWindow> 88 <InfoWindow v-show="showInfoWindow" ref="infoWindow" :info-window="infoWindow" :info="itemInfo" :rect="rect"></InfoWindow>
89 + <InfoWindowLite v-show="showInfoWindowLite" ref="infoWindowLite" :info-window="infoWindowLite" :info="itemInfo" :rect="rect"></InfoWindowLite>
90 + <InfoWindowWarn v-show="showInfoWindowWarn" ref="infoWindowWarn" :info-window="infoWindowWarn" :info="itemInfo" :rect="rect"></InfoWindowWarn>
89 </div> 91 </div>
90 </template> 92 </template>
91 93
...@@ -98,6 +100,8 @@ import _ from 'lodash'; ...@@ -98,6 +100,8 @@ import _ from 'lodash';
98 import $ from 'jquery'; 100 import $ from 'jquery';
99 //引入定义的信息窗组件 101 //引入定义的信息窗组件
100 import InfoWindow from '@/components/InfoWindow' 102 import InfoWindow from '@/components/InfoWindow'
103 +import InfoWindowLite from '@/components/InfoWindowLite'
104 +import InfoWindowWarn from '@/components/InfoWindowWarn'
101 import { useRect } from '@vant/use'; 105 import { useRect } from '@vant/use';
102 106
103 const GPS = { 107 const GPS = {
...@@ -207,7 +211,11 @@ export default { ...@@ -207,7 +211,11 @@ export default {
207 video_src: '', 211 video_src: '',
208 show_nav_popup: false, 212 show_nav_popup: false,
209 showInfoWindow: false, 213 showInfoWindow: false,
214 + showInfoWindowLite: false,
215 + showInfoWindowWarn: false,
210 infoWindow: {}, 216 infoWindow: {},
217 + infoWindowLite: {},
218 + infoWindowWarn: {},
211 itemInfo: {}, 219 itemInfo: {},
212 navBarList: [], 220 navBarList: [],
213 rect: {}, 221 rect: {},
...@@ -257,6 +265,20 @@ export default { ...@@ -257,6 +265,20 @@ export default {
257 const rect = useRect(this.$refs.root); 265 const rect = useRect(this.$refs.root);
258 this.rect = rect; 266 this.rect = rect;
259 } 267 }
268 + },
269 + showInfoWindowLite (val) {
270 + if (val) {
271 + // 元素的大小及其相对于视口的位置
272 + const rect = useRect(this.$refs.root);
273 + this.rect = rect;
274 + }
275 + },
276 + showInfoWindowWarn (val) {
277 + if (val) {
278 + // 元素的大小及其相对于视口的位置
279 + const rect = useRect(this.$refs.root);
280 + this.rect = rect;
281 + }
260 } 282 }
261 }, 283 },
262 methods: { 284 methods: {
...@@ -506,7 +528,7 @@ export default { ...@@ -506,7 +528,7 @@ export default {
506 } 528 }
507 // 绑定景点的点击事件 - 文字出现才能触发 529 // 绑定景点的点击事件 - 文字出现才能触发
508 var clickListener = marker.on('click', (e) => { 530 var clickListener = marker.on('click', (e) => {
509 - this.show_popup = true; 531 + this.positionWarnMarker(coord.toiletInfo[i]);
510 }) 532 })
511 // 533 //
512 this.toiletInfo.push(marker); 534 this.toiletInfo.push(marker);
...@@ -543,7 +565,7 @@ export default { ...@@ -543,7 +565,7 @@ export default {
543 } 565 }
544 // 绑定景点的点击事件 - 文字出现才能触发 566 // 绑定景点的点击事件 - 文字出现才能触发
545 var clickListener = marker.on('click', (e) => { 567 var clickListener = marker.on('click', (e) => {
546 - this.show_popup = true; 568 + this.positionLiteMarker(coord.activityInfo[i]);
547 }) 569 })
548 // 570 //
549 this.activityInfo.push(marker); 571 this.activityInfo.push(marker);
...@@ -580,7 +602,7 @@ export default { ...@@ -580,7 +602,7 @@ export default {
580 } 602 }
581 // 绑定景点的点击事件 - 文字出现才能触发 603 // 绑定景点的点击事件 - 文字出现才能触发
582 var clickListener = marker.on('click', (e) => { 604 var clickListener = marker.on('click', (e) => {
583 - this.show_popup = true; 605 + this.positionLiteMarker(coord.publicInfo[i]);
584 }) 606 })
585 // 607 //
586 this.publicInfo.push(marker); 608 this.publicInfo.push(marker);
...@@ -859,13 +881,7 @@ export default { ...@@ -859,13 +881,7 @@ export default {
859 zoom; 881 zoom;
860 console.warn(text); 882 console.warn(text);
861 // 点击空白处 关闭弹框 883 // 点击空白处 关闭弹框
862 - if (this.showInfoWindow) { 884 + this.closeInfoWindow()
863 - this.$refs['infoWindow'].close();
864 - // 打开缩放
865 - this.map.setStatus({
866 - zoomEnable: true
867 - });
868 - }
869 }, 885 },
870 setWalkRoute() { 886 setWalkRoute() {
871 //步行导航 887 //步行导航
...@@ -909,6 +925,7 @@ export default { ...@@ -909,6 +925,7 @@ export default {
909 this.navName = 'publicInfo' 925 this.navName = 'publicInfo'
910 this.setPublicLayer() 926 this.setPublicLayer()
911 } 927 }
928 + this.closeInfoWindow()
912 }, 929 },
913 handleSafeRoute(status) { // 打开/关闭逃生路线线 930 handleSafeRoute(status) { // 打开/关闭逃生路线线
914 if (status) { 931 if (status) {
...@@ -934,6 +951,30 @@ export default { ...@@ -934,6 +951,30 @@ export default {
934 zoomEnable: false 951 zoomEnable: false
935 }); 952 });
936 }, 953 },
954 + positionLiteMarker(item) {
955 + // 点击后创建自定义信息窗口
956 + this.setInfoWindowsLite(item)
957 + // 把地图中心点设置为当前点击的标记点
958 + this.map.setZoomAndCenter(this.zoom, item.position);
959 + //
960 + this.show_nav_popup = false;
961 + // 禁止缩放
962 + this.map.setStatus({
963 + zoomEnable: false
964 + });
965 + },
966 + positionWarnMarker(item) {
967 + // 点击后创建自定义信息窗口
968 + this.setInfoWindowsWarn(item)
969 + // 把地图中心点设置为当前点击的标记点
970 + this.map.setZoomAndCenter(this.zoom, item.position);
971 + //
972 + this.show_nav_popup = false;
973 + // 禁止缩放
974 + this.map.setStatus({
975 + zoomEnable: false
976 + });
977 + },
937 setInfoWindows(item) { 978 setInfoWindows(item) {
938 // 此时需要把组件的样式设置为可见 979 // 此时需要把组件的样式设置为可见
939 this.showInfoWindow = true 980 this.showInfoWindow = true
...@@ -950,6 +991,63 @@ export default { ...@@ -950,6 +991,63 @@ export default {
950 this.itemInfo = item 991 this.itemInfo = item
951 // 信息窗口打开 992 // 信息窗口打开
952 infoWindow.open(this.map, item.position) 993 infoWindow.open(this.map, item.position)
994 + },
995 + setInfoWindowsLite(item) {
996 + // 此时需要把组件的样式设置为可见
997 + this.showInfoWindowLite = true
998 + // 设置marker头部的标题信息窗口
999 + const infoWindowLite = new AMap.InfoWindow({
1000 + // 使用自定义窗体
1001 + isCustom: true,
1002 + // 只有当组件渲染完毕后,通过$el才能拿到原生的dom对象
1003 + content: this.$refs['infoWindowLite'].$el,
1004 + // 设置定位偏移量
1005 + offset: new AMap.Pixel(0, -30),
1006 + })
1007 + this.infoWindowLite = infoWindowLite;
1008 + this.itemInfo = item
1009 + // 信息窗口打开
1010 + infoWindowLite.open(this.map, item.position)
1011 + },
1012 + setInfoWindowsWarn(item) {
1013 + // 此时需要把组件的样式设置为可见
1014 + this.showInfoWindowWarn = true
1015 + // 设置marker头部的标题信息窗口
1016 + const infoWindowWarn = new AMap.InfoWindow({
1017 + // 使用自定义窗体
1018 + isCustom: true,
1019 + // 只有当组件渲染完毕后,通过$el才能拿到原生的dom对象
1020 + content: this.$refs['infoWindowWarn'].$el,
1021 + // 设置定位偏移量
1022 + offset: new AMap.Pixel(0, -30),
1023 + })
1024 + this.infoWindowWarn = infoWindowWarn;
1025 + this.itemInfo = item
1026 + // 信息窗口打开
1027 + infoWindowWarn.open(this.map, item.position)
1028 + },
1029 + closeInfoWindow () {
1030 + if (this.showInfoWindow) {
1031 + this.$refs['infoWindow'].close();
1032 + // 打开缩放
1033 + this.map.setStatus({
1034 + zoomEnable: true
1035 + });
1036 + }
1037 + if (this.showInfoWindowLite) {
1038 + this.$refs['infoWindowLite'].close();
1039 + // 打开缩放
1040 + this.map.setStatus({
1041 + zoomEnable: true
1042 + });
1043 + }
1044 + if (this.showInfoWindowWarn) {
1045 + this.$refs['infoWindowWarn'].close();
1046 + // 打开缩放
1047 + this.map.setStatus({
1048 + zoomEnable: true
1049 + });
1050 + }
953 } 1051 }
954 1052
955 } 1053 }
......