@sword916/vae-map-plus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/build/index.mjs +113 -0
- package/examples/App.vue +18 -0
- package/examples/index.js +13 -0
- package/examples/router/index.js +35 -0
- package/examples/views/amap.vue +29 -0
- package/examples/views/amarker.vue +58 -0
- package/examples/views/buffer.vue +66 -0
- package/examples/views/cluster.vue +74 -0
- package/examples/views/cover.vue +85 -0
- package/examples/views/draw-line.vue +49 -0
- package/examples/views/draw.vue +54 -0
- package/examples/views/echarts.vue +142 -0
- package/examples/views/emarker.vue +39 -0
- package/examples/views/image.vue +182 -0
- package/examples/views/index.vue +61 -0
- package/examples/views/lrmap.vue +108 -0
- package/examples/views/map.vue +82 -0
- package/examples/views/measure.vue +86 -0
- package/examples/views/parts/popup.vue +39 -0
- package/examples/views/parts/tooltip.vue +39 -0
- package/examples/views/push-area.vue +52 -0
- package/examples/views/push-line.vue +84 -0
- package/examples/views/trace.vue +49 -0
- package/index.html +13 -0
- package/jsconfig.json +17 -0
- package/package.json +47 -0
- package/public/favicon.ico +0 -0
- package/public/images/game.png +0 -0
- package/public/images/grid.png +0 -0
- package/public/images/marker.png +0 -0
- package/public/index.html +30 -0
- package/src/components/resize-listener/component.jsx +30 -0
- package/src/components/resize-listener/index.js +3 -0
- package/src/composables/useAutoMessage.js +41 -0
- package/src/composables/useContextMenu.js +99 -0
- package/src/composables/useMapMeasure.js +191 -0
- package/src/composables/useResizeObserver.js +81 -0
- package/src/mixins/message.js +1 -0
- package/src/packages/index.js +16 -0
- package/src/packages/vae-amap/index.js +8 -0
- package/src/packages/vae-amap/style.less +9 -0
- package/src/packages/vae-amap/vae-amap.jsx +98 -0
- package/src/packages/vae-cloudmap/ctrl-context-menu/index.vue +74 -0
- package/src/packages/vae-cloudmap/ctrl-draw/index.vue +499 -0
- package/src/packages/vae-cloudmap/ctrl-draw-line/index.vue +161 -0
- package/src/packages/vae-cloudmap/index.js +57 -0
- package/src/packages/vae-cloudmap/scripts/L.MarkerCluster/index.js +2690 -0
- package/src/packages/vae-cloudmap/scripts/L.MarkerCluster/style.css +14 -0
- package/src/packages/vae-cloudmap/scripts/L.Vae.CRS/index.js +212 -0
- package/src/packages/vae-cloudmap/scripts/L.Vae.Client/index.js +780 -0
- package/src/packages/vae-cloudmap/scripts/Mixin.ContextMenu/index.js +101 -0
- package/src/packages/vae-cloudmap/style.less +163 -0
- package/src/packages/vae-cloudmap/vae-cloudmap.jsx +272 -0
- package/src/packages/vae-map/ctrl-context-menu/index.vue +74 -0
- package/src/packages/vae-map/ctrl-draw/index.vue +498 -0
- package/src/packages/vae-map/ctrl-draw-line/index.vue +128 -0
- package/src/packages/vae-map/index.js +59 -0
- package/src/packages/vae-map/scripts/L.MarkerCluster/index.js +2690 -0
- package/src/packages/vae-map/scripts/L.MarkerCluster/style.css +14 -0
- package/src/packages/vae-map/scripts/L.Vae.CRS/index.js +114 -0
- package/src/packages/vae-map/scripts/L.Vae.Client/index.js +548 -0
- package/src/packages/vae-map/scripts/Mixin.ContextMenu/index.js +1 -0
- package/src/packages/vae-map/style.less +161 -0
- package/src/packages/vae-map/vae-lrmap.jsx +237 -0
- package/src/packages/vae-map/vae-map.jsx +135 -0
- package/src/plugins/L.AnimatedMarker/index.js +158 -0
- package/src/plugins/L.EchartsLayer/index.js +339 -0
- package/src/plugins/L.ElasticMarker/index.js +162 -0
- package/src/plugins/L.FootageCalculator.Area/index.js +263 -0
- package/src/plugins/L.FootageCalculator.Line/index.js +273 -0
- package/src/plugins/L.GeoUtil/buffer.js +67 -0
- package/src/plugins/L.GeoUtil/index.js +284 -0
- package/src/plugins/L.Glyphicon/index.js +91 -0
- package/src/plugins/L.Glyphicon/style.less +37 -0
- package/src/plugins/L.MarkerClusterX/index.js +93 -0
- package/src/plugins/L.MarkerClusterX/style.less +162 -0
- package/src/plugins/L.SafeDivOverlay/index.js +55 -0
- package/src/plugins/L.TileLayer.ChinaProvider/index.js +108 -0
- package/src/plugins/L.VuePopup/index.js +67 -0
- package/src/plugins/L.VueTooltip/index.js +63 -0
- package/src/plugins/Mixin.Map.Measure/index.js +248 -0
- package/src/plugins/globals/index.js +7 -0
- package/src/utils/index.js +36 -0
- package/src/utils/resize-event.js +45 -0
- package/vite.config.mjs +25 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :style="style">
|
|
3
|
+
<div v-for="item in count" :key="item">{{ name }}: {{ item }}</div>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup>
|
|
8
|
+
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
9
|
+
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
name: {
|
|
12
|
+
type: String,
|
|
13
|
+
default: ''
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const count = ref(1)
|
|
18
|
+
let timer = null
|
|
19
|
+
|
|
20
|
+
const style = computed(() => ({
|
|
21
|
+
width: `${100 + count.value * 10}px`
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
onMounted(() => {
|
|
25
|
+
timer = window.setInterval(() => {
|
|
26
|
+
count.value += 1
|
|
27
|
+
if (count.value === 10) {
|
|
28
|
+
clearInterval(timer)
|
|
29
|
+
timer = null
|
|
30
|
+
}
|
|
31
|
+
}, 1000)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
onBeforeUnmount(() => {
|
|
35
|
+
if (timer) {
|
|
36
|
+
clearInterval(timer)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :style="style">
|
|
3
|
+
<div v-for="item in count" :key="item">{{ name }}: {{ item }}</div>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup>
|
|
8
|
+
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
9
|
+
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
name: {
|
|
12
|
+
type: String,
|
|
13
|
+
default: ''
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const count = ref(1)
|
|
18
|
+
let timer = null
|
|
19
|
+
|
|
20
|
+
const style = computed(() => ({
|
|
21
|
+
width: `${50 + count.value * 10}px`
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
onMounted(() => {
|
|
25
|
+
timer = window.setInterval(() => {
|
|
26
|
+
count.value += 1
|
|
27
|
+
if (count.value === 5) {
|
|
28
|
+
clearInterval(timer)
|
|
29
|
+
timer = null
|
|
30
|
+
}
|
|
31
|
+
}, 1000)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
onBeforeUnmount(() => {
|
|
35
|
+
if (timer) {
|
|
36
|
+
clearInterval(timer)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<vae-map :base-layers="['GaoDe.Normal.Map']" @init-map="initMap" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
const poly = [
|
|
7
|
+
{ lat: 34.26572889446933, lng: 117.18566894531251 },
|
|
8
|
+
{ lat: 34.24274329938616, lng: 117.1956253051758 },
|
|
9
|
+
{ lat: 34.27395677834786, lng: 117.4043655395508 },
|
|
10
|
+
{ lat: 34.29579932143427, lng: 117.39475250244142 }
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
const baseLayers = L.layerGroup()
|
|
14
|
+
let calculator = null
|
|
15
|
+
|
|
16
|
+
const drawPoly = (map) => {
|
|
17
|
+
L.polygon(poly).addTo(baseLayers)
|
|
18
|
+
_.delay(() => {
|
|
19
|
+
map.fitBounds(L.latLngBounds(poly))
|
|
20
|
+
}, 250)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const doCalculate = () => {
|
|
24
|
+
calculator = L.footageCalculator.area({
|
|
25
|
+
latlngs: poly,
|
|
26
|
+
headStart: { lat: 34.26572889446933, lng: 117.18566894531251 },
|
|
27
|
+
headEnd: { lat: 34.29579932143427, lng: 117.39475250244142 },
|
|
28
|
+
tailStart: { lat: 34.24274329938616, lng: 117.1956253051758 },
|
|
29
|
+
tailEnd: { lat: 34.27395677834786, lng: 117.4043655395508 }
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const result = calculator.doCalculate({
|
|
33
|
+
headStart: { lat: 34.26572889446933, lng: 117.18566894531251 },
|
|
34
|
+
tailStart: { lat: 34.24274329938616, lng: 117.1956253051758 },
|
|
35
|
+
headDistance: 100,
|
|
36
|
+
tailDistance: 100
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
L.polygon(result.latlngs, { color: 'red' }).addTo(baseLayers)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const initMap = (map) => {
|
|
43
|
+
map.addLayer(baseLayers)
|
|
44
|
+
map.on('click', (event) => {
|
|
45
|
+
console.log(event.latlng)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
baseLayers.clearLayers()
|
|
49
|
+
drawPoly(map)
|
|
50
|
+
doCalculate()
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<vae-map @init-map="initMap" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
const lines = [
|
|
7
|
+
[
|
|
8
|
+
{ lat: 34.31614748988616, lng: 117.32368469238283 },
|
|
9
|
+
{ lat: 34.293104769231974, lng: 117.31870651245119 },
|
|
10
|
+
{ lat: 34.28629709450699, lng: 117.33801841735841 }
|
|
11
|
+
],
|
|
12
|
+
[
|
|
13
|
+
{ lat: 34.29955736832844, lng: 117.33630180358887 },
|
|
14
|
+
{ lat: 34.299202842785114, lng: 117.35329627990724 }
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
{ lat: 34.29565750505196, lng: 117.33501434326173 },
|
|
18
|
+
{ lat: 34.29374296045891, lng: 117.35097885131837 }
|
|
19
|
+
]
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const footages = [3100, 200, 200, 2000, 100, 300, 300, 300, 2000, 100, 100]
|
|
23
|
+
const colors = ['#964B00', '#FFC0CB', '#00FF00', '#87CEFA', '#e01f54', '#f5e8c8', '#0a915d']
|
|
24
|
+
const baseLayers = L.layerGroup()
|
|
25
|
+
const polylines = []
|
|
26
|
+
|
|
27
|
+
const drawLines = (map) => {
|
|
28
|
+
let latlngs = []
|
|
29
|
+
lines.forEach((line) => {
|
|
30
|
+
polylines.push(L.polyline(line).addTo(baseLayers))
|
|
31
|
+
latlngs = _.concat(latlngs, line)
|
|
32
|
+
})
|
|
33
|
+
_.delay(() => {
|
|
34
|
+
map.fitBounds(L.latLngBounds(latlngs))
|
|
35
|
+
}, 250)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const doCalculate = () => {
|
|
39
|
+
let footageIndex = 0
|
|
40
|
+
|
|
41
|
+
for (const line of lines) {
|
|
42
|
+
const remainingFootages = _.takeRight(footages, footages.length - footageIndex)
|
|
43
|
+
if (remainingFootages.length === 0) {
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const calculator = new L.FootageCalculator.Line({
|
|
48
|
+
latlngs: line,
|
|
49
|
+
width: 200
|
|
50
|
+
})
|
|
51
|
+
let start = line[0]
|
|
52
|
+
|
|
53
|
+
for (const footage of remainingFootages) {
|
|
54
|
+
const { path, remainingPath, area } = calculator.doCalculate({
|
|
55
|
+
start,
|
|
56
|
+
distance: footage
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
L.polygon(area, {
|
|
60
|
+
color: colors[footageIndex % colors.length],
|
|
61
|
+
fillOpacity: 0.8
|
|
62
|
+
}).addTo(baseLayers)
|
|
63
|
+
|
|
64
|
+
footageIndex += 1
|
|
65
|
+
start = _.last(path)
|
|
66
|
+
|
|
67
|
+
if (remainingPath.length === 0) {
|
|
68
|
+
break
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const initMap = (map) => {
|
|
75
|
+
map.addLayer(baseLayers)
|
|
76
|
+
map.on('click', (event) => {
|
|
77
|
+
console.log(event.latlng)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
baseLayers.clearLayers()
|
|
81
|
+
drawLines(map)
|
|
82
|
+
doCalculate()
|
|
83
|
+
}
|
|
84
|
+
</script>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="map-container">
|
|
3
|
+
<vae-map :base-layers="['GaoDe.Normal.Map']" @init-map="initMap" />
|
|
4
|
+
<div class="actions">
|
|
5
|
+
<el-button @click="start">START</el-button>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup>
|
|
11
|
+
import { ref } from 'vue'
|
|
12
|
+
|
|
13
|
+
const latLngs = [
|
|
14
|
+
{ lat: 34.3380, lng: 117.311 },
|
|
15
|
+
{ lat: 34.2794, lng: 117.314 },
|
|
16
|
+
{ lat: 34.2867, lng: 117.365 },
|
|
17
|
+
{ lat: 34.2470, lng: 117.341 },
|
|
18
|
+
{ lat: 34.2132, lng: 117.403 }
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
const map = ref(null)
|
|
22
|
+
const aMarker = ref(null)
|
|
23
|
+
|
|
24
|
+
const initMap = (value) => {
|
|
25
|
+
map.value = value
|
|
26
|
+
aMarker.value = L.animatedMarker({ latLngs }).addTo(map.value)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const start = () => {
|
|
30
|
+
aMarker.value.on('chunkmove', ({ index, duration }) => {
|
|
31
|
+
map.value.panTo(latLngs[index], { duration: duration / 1000 })
|
|
32
|
+
})
|
|
33
|
+
aMarker.value.startMove()
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<style lang="less" scoped>
|
|
38
|
+
.map-container {
|
|
39
|
+
height: 100%;
|
|
40
|
+
position: relative;
|
|
41
|
+
|
|
42
|
+
.actions {
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 20px;
|
|
45
|
+
right: 20px;
|
|
46
|
+
z-index: 2000;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
</style>
|
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>vae-map</title>
|
|
7
|
+
<link rel="icon" href="/favicon.ico" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/examples/index.js"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/jsconfig.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sword916/vae-map-plus",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "map components and plugins",
|
|
6
|
+
"author": "@sword916",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"main": "./lib/index.js",
|
|
9
|
+
"module": "./lib/index.js",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"dev": "vite",
|
|
15
|
+
"build": "node ./build/index.mjs",
|
|
16
|
+
"build-example": "vite build",
|
|
17
|
+
"preview": "vite preview --port 6601",
|
|
18
|
+
"pub": "npm publish --access public",
|
|
19
|
+
"pub-beta": "npm publish --tag beta --access public"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@amap/amap-jsapi-loader": "^1.0.1",
|
|
23
|
+
"@fortawesome/fontawesome-free": "^5.15.4",
|
|
24
|
+
"@geoman-io/leaflet-geoman-free": "^2.11.4",
|
|
25
|
+
"@turf/buffer": "^6.5.0",
|
|
26
|
+
"axios": "^0.24.0",
|
|
27
|
+
"echarts": "^5.2.2",
|
|
28
|
+
"element-plus": "^2.8.8",
|
|
29
|
+
"jquery": "^3.6.0",
|
|
30
|
+
"leaflet": "^1.9.4",
|
|
31
|
+
"leaflet-geometryutil": "^0.10.3",
|
|
32
|
+
"leaflet.markercluster": "^1.5.3",
|
|
33
|
+
"lodash": "^4.17.21",
|
|
34
|
+
"proj4": "^2.7.5",
|
|
35
|
+
"proj4leaflet": "^1.0.2",
|
|
36
|
+
"uuid": "^9.0.1",
|
|
37
|
+
"vue": "^3.5.13",
|
|
38
|
+
"vue-router": "^4.5.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
42
|
+
"@vitejs/plugin-vue-jsx": "^4.1.2",
|
|
43
|
+
"@vue/compiler-sfc": "^3.5.13",
|
|
44
|
+
"less": "^4.2.0",
|
|
45
|
+
"vite": "^5.4.11"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
7
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
8
|
+
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
|
9
|
+
<style type="text/css">
|
|
10
|
+
html {
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
body {
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
margin: 0;
|
|
19
|
+
padding: 0;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
23
|
+
<title>...</title>
|
|
24
|
+
</head>
|
|
25
|
+
|
|
26
|
+
<body>
|
|
27
|
+
<div id="app"></div>
|
|
28
|
+
</body>
|
|
29
|
+
|
|
30
|
+
</html>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { defineComponent, ref } from 'vue'
|
|
2
|
+
import { debounce as lodashDebounce } from 'lodash'
|
|
3
|
+
import { useElementResize } from '@/composables/useResizeObserver'
|
|
4
|
+
|
|
5
|
+
export default defineComponent({
|
|
6
|
+
name: 'ResizeListener',
|
|
7
|
+
props: {
|
|
8
|
+
debounce: {
|
|
9
|
+
type: Number,
|
|
10
|
+
default: 100
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
emits: ['resize'],
|
|
14
|
+
setup(props, { emit, slots }) {
|
|
15
|
+
const rootRef = ref(null)
|
|
16
|
+
const emitResize = lodashDebounce(() => {
|
|
17
|
+
if (rootRef.value) {
|
|
18
|
+
emit('resize', rootRef.value)
|
|
19
|
+
}
|
|
20
|
+
}, props.debounce)
|
|
21
|
+
|
|
22
|
+
useElementResize(rootRef, ({ visible }) => {
|
|
23
|
+
if (visible) {
|
|
24
|
+
emitResize()
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return () => <div ref={rootRef}>{slots.default?.()}</div>
|
|
29
|
+
}
|
|
30
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ElMessage, ElNotification } from 'element-plus'
|
|
2
|
+
|
|
3
|
+
export function useAutoMessage() {
|
|
4
|
+
return (options) => {
|
|
5
|
+
let message
|
|
6
|
+
let type
|
|
7
|
+
let duration
|
|
8
|
+
|
|
9
|
+
if (_.isString(options)) {
|
|
10
|
+
message = options
|
|
11
|
+
type = 'error'
|
|
12
|
+
duration = 3000
|
|
13
|
+
} else {
|
|
14
|
+
message = options.message
|
|
15
|
+
type = options.type || 'error'
|
|
16
|
+
duration = _.isNil(options.duration) ? 3000 : options.duration
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (['success', 'warning', 'info', 'error'].includes(type)) {
|
|
20
|
+
ElMessage({
|
|
21
|
+
message,
|
|
22
|
+
type,
|
|
23
|
+
duration
|
|
24
|
+
})
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let notifyType = type
|
|
29
|
+
if (notifyType === 'info') {
|
|
30
|
+
notifyType = 'primary'
|
|
31
|
+
} else if (notifyType === 'error') {
|
|
32
|
+
notifyType = 'danger'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ElNotification({
|
|
36
|
+
message,
|
|
37
|
+
type: notifyType,
|
|
38
|
+
duration
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { computed, h, nextTick, onBeforeUnmount, ref, unref, watch } from 'vue'
|
|
2
|
+
import ContextMenu from '@/packages/vae-map/ctrl-context-menu/index.vue'
|
|
3
|
+
|
|
4
|
+
function resolveElement(target) {
|
|
5
|
+
return target?.$el ?? target ?? null
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function useContextMenu({ mapRef, mapContainerRef, menusRef }) {
|
|
9
|
+
const contextMenuRef = ref(null)
|
|
10
|
+
const showContextMenu = ref(false)
|
|
11
|
+
const contextMenuEvent = ref(null)
|
|
12
|
+
const contextMenuLeft = ref(0)
|
|
13
|
+
const contextMenuTop = ref(0)
|
|
14
|
+
|
|
15
|
+
const menuList = computed(() => unref(menusRef) ?? [])
|
|
16
|
+
|
|
17
|
+
const hideContextMenu = () => {
|
|
18
|
+
const map = unref(mapRef)
|
|
19
|
+
map?.off('click', hideContextMenu)
|
|
20
|
+
showContextMenu.value = false
|
|
21
|
+
contextMenuEvent.value = null
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const handleCallback = (callback) => {
|
|
25
|
+
showContextMenu.value = false
|
|
26
|
+
if (callback && _.isFunction(callback)) {
|
|
27
|
+
callback(contextMenuEvent.value)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const handleRightClick = async (event) => {
|
|
32
|
+
showContextMenu.value = true
|
|
33
|
+
contextMenuEvent.value = event
|
|
34
|
+
await nextTick()
|
|
35
|
+
|
|
36
|
+
const menuEl = resolveElement(contextMenuRef.value)
|
|
37
|
+
const containerEl = resolveElement(unref(mapContainerRef))
|
|
38
|
+
if (!menuEl || !containerEl) {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const menuHeight = menuEl.scrollHeight
|
|
43
|
+
const menuWidth = menuEl.scrollWidth
|
|
44
|
+
const containerHeight = containerEl.scrollHeight
|
|
45
|
+
const containerWidth = containerEl.scrollWidth
|
|
46
|
+
|
|
47
|
+
contextMenuLeft.value = event.containerPoint.x
|
|
48
|
+
contextMenuTop.value = event.containerPoint.y
|
|
49
|
+
|
|
50
|
+
if (contextMenuLeft.value + menuWidth > containerWidth && containerWidth > menuWidth) {
|
|
51
|
+
contextMenuLeft.value = containerWidth - menuWidth
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (contextMenuTop.value + menuHeight > containerHeight && containerHeight > menuHeight) {
|
|
55
|
+
contextMenuTop.value = containerHeight - menuHeight
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
unref(mapRef)?.on('click', hideContextMenu)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const addContextMenu = () => {
|
|
62
|
+
const map = unref(mapRef)
|
|
63
|
+
if (!map) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
map.off('contextmenu', handleRightClick)
|
|
67
|
+
if (menuList.value.length > 0) {
|
|
68
|
+
map.on('contextmenu', handleRightClick)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
watch(menuList, addContextMenu, { deep: true })
|
|
73
|
+
|
|
74
|
+
onBeforeUnmount(() => {
|
|
75
|
+
const map = unref(mapRef)
|
|
76
|
+
map?.off('contextmenu', handleRightClick)
|
|
77
|
+
map?.off('click', hideContextMenu)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const renderContextMenu = () => {
|
|
81
|
+
if (menuList.value.length === 0 || !showContextMenu.value) {
|
|
82
|
+
return null
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return h(ContextMenu, {
|
|
86
|
+
ref: contextMenuRef,
|
|
87
|
+
menus: menuList.value,
|
|
88
|
+
left: contextMenuLeft.value,
|
|
89
|
+
top: contextMenuTop.value,
|
|
90
|
+
onCallback: handleCallback
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
addContextMenu,
|
|
96
|
+
hideContextMenu,
|
|
97
|
+
renderContextMenu
|
|
98
|
+
}
|
|
99
|
+
}
|