Implement display of lines and circles
This commit is contained in:
parent
34b0e5f259
commit
a809b68bb2
@ -231,7 +231,7 @@ function buildLines(data: any): Map<string, DynmapLine> {
|
||||
|
||||
lines.set(key, {
|
||||
x: line.x || [0, 0],
|
||||
y: [line.ybottom || 0, line.ytop || 0],
|
||||
y: line.y || [0, 0],
|
||||
z: line.z || [0, 0],
|
||||
style: {
|
||||
color: line.color || '#ff0000',
|
||||
@ -322,7 +322,8 @@ export default {
|
||||
});
|
||||
});
|
||||
|
||||
for(let i = 0; i < 408; i++) {
|
||||
//Extra fake players for testing
|
||||
for(let i = 0; i < 150; i++) {
|
||||
players.add({
|
||||
account: "VIDEO GAMES " + i,
|
||||
health: Math.round(Math.random() * 10),
|
||||
|
@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<GenericMarker v-for="[id, marker] in markerSet.markers" :options="marker" :key="id" :layer-group="layerGroup"></GenericMarker>
|
||||
<Areas :areas="markerSet.areas" :layer-group="layerGroup"></Areas>
|
||||
<Circles :circles="markerSet.circles" :layer-group="layerGroup"></Circles>
|
||||
<Lines :lines="markerSet.lines" :layer-group="layerGroup"></Lines>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -10,11 +12,15 @@ import L from 'leaflet';
|
||||
import {DynmapMarkerSet} from "@/dynmap";
|
||||
import GenericMarker from "@/components/map/marker/GenericMarker.vue";
|
||||
import Areas from "@/components/map/vector/Areas.vue";
|
||||
import Circles from "@/components/map/vector/Circles.vue";
|
||||
import Lines from "@/components/map/vector/Lines.vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
GenericMarker,
|
||||
Areas
|
||||
Areas,
|
||||
Circles,
|
||||
Lines,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
140
src/components/map/vector/Circles.vue
Normal file
140
src/components/map/vector/Circles.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<script lang="ts">
|
||||
import {defineComponent, computed} from "@vue/runtime-core";
|
||||
import L, {LatLngExpression} from 'leaflet';
|
||||
import {useStore} from "@/store";
|
||||
import {DynmapCircle} from "@/dynmap";
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
circles: {
|
||||
type: Object as () => Map<string, DynmapCircle>,
|
||||
required: true
|
||||
},
|
||||
layerGroup: {
|
||||
type: Object as () => L.LayerGroup,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
setup() {
|
||||
const store = useStore(),
|
||||
currentProjection = computed(() => store.state.currentProjection),
|
||||
layers = Object.freeze(new Map()) as Map<string, L.Path>;
|
||||
|
||||
return {
|
||||
layers,
|
||||
currentProjection,
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
//FIXME: Prevent unnecessary repositioning when changing worlds
|
||||
currentProjection() {
|
||||
const projection = useStore().state.currentProjection,
|
||||
latLng = (x: number, y: number, z: number) => {
|
||||
return projection.locationToLatLng({x, y, z});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for (const [id, circle] of this.circles) {
|
||||
this.updateCircle(id, circle, latLng);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.createCircles();
|
||||
},
|
||||
|
||||
unmounted() {
|
||||
|
||||
},
|
||||
|
||||
render() {
|
||||
return null;
|
||||
},
|
||||
|
||||
methods: {
|
||||
createCircles() {
|
||||
const projection = useStore().state.currentProjection,
|
||||
latLng = (x: number, y: number, z: number) => {
|
||||
return projection.locationToLatLng({x, y, z});
|
||||
};
|
||||
|
||||
this.circles.forEach((circle: DynmapCircle, id: string) => {
|
||||
this.createCircle(id, circle, latLng);
|
||||
});
|
||||
},
|
||||
|
||||
createCircle(id: string, options: DynmapCircle, latLng: Function) {
|
||||
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
||||
points = this.getPoints(options, latLng, outline);
|
||||
let circle;
|
||||
|
||||
if(outline) {
|
||||
circle = new L.Polyline(points, options.style);
|
||||
} else {
|
||||
circle = new L.Polygon(points, options.style);
|
||||
}
|
||||
|
||||
if(options.label) {
|
||||
circle.bindPopup(() => {
|
||||
const popup = document.createElement('span');
|
||||
|
||||
if (options.popupContent) {
|
||||
popup.classList.add('CirclePopup');
|
||||
popup.insertAdjacentHTML('afterbegin', options.popupContent);
|
||||
} else if (options.isHTML) {
|
||||
popup.classList.add('CirclePopup');
|
||||
popup.insertAdjacentHTML('afterbegin', options.label);
|
||||
} else {
|
||||
popup.textContent = options.label;
|
||||
}
|
||||
|
||||
return popup;
|
||||
});
|
||||
}
|
||||
|
||||
this.layers.set(id, circle);
|
||||
this.layerGroup.addLayer(circle);
|
||||
},
|
||||
|
||||
getPoints(options: DynmapCircle, latLng: Function, outline: boolean): LatLngExpression[] {
|
||||
const points = [];
|
||||
|
||||
for(let i = 0; i < 360; i++) {
|
||||
const rad = i * Math.PI / 180.0,
|
||||
x = options.radius[0] * Math.sin(rad) + options.location.x,
|
||||
z = options.radius[1] * Math.cos(rad) + options.location.z;
|
||||
|
||||
console.log(x,options.location.y,z, latLng(x, options.location.y, z));
|
||||
|
||||
points.push(latLng(x, options.location.y, z));
|
||||
}
|
||||
|
||||
if(outline && points.length) {
|
||||
points.push(points[0]);
|
||||
}
|
||||
|
||||
return points;
|
||||
},
|
||||
|
||||
updateCircle(id: string, options: DynmapCircle, latLng: Function) {
|
||||
let circle = this.layers.get(id) as L.Polyline,
|
||||
outline = (options.style && options.style.fillOpacity && (options.style.fillOpacity <= 0)) as boolean,
|
||||
points = this.getPoints(options, latLng, outline);
|
||||
|
||||
if (!circle) {
|
||||
return;
|
||||
}
|
||||
|
||||
circle.setLatLngs(points);
|
||||
circle.redraw();
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
122
src/components/map/vector/Lines.vue
Normal file
122
src/components/map/vector/Lines.vue
Normal file
@ -0,0 +1,122 @@
|
||||
<script lang="ts">
|
||||
import {defineComponent, computed} from "@vue/runtime-core";
|
||||
import L, {LatLngExpression} from 'leaflet';
|
||||
import {useStore} from "@/store";
|
||||
import {DynmapLine} from "@/dynmap";
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
lines: {
|
||||
type: Object as () => Map<string, DynmapLine>,
|
||||
required: true
|
||||
},
|
||||
layerGroup: {
|
||||
type: Object as () => L.LayerGroup,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
setup() {
|
||||
const store = useStore(),
|
||||
currentProjection = computed(() => store.state.currentProjection),
|
||||
layers = Object.freeze(new Map()) as Map<string, L.Path>;
|
||||
|
||||
return {
|
||||
layers,
|
||||
currentProjection,
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
//FIXME: Prevent unnecessary repositioning when changing worlds
|
||||
currentProjection() {
|
||||
const projection = useStore().state.currentProjection,
|
||||
latLng = (x: number, y: number, z: number) => {
|
||||
return projection.locationToLatLng({x, y, z});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for (const [id, line] of this.lines) {
|
||||
this.updateLine(id, line, latLng);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.createLines();
|
||||
},
|
||||
|
||||
unmounted() {
|
||||
|
||||
},
|
||||
|
||||
render() {
|
||||
return null;
|
||||
},
|
||||
|
||||
methods: {
|
||||
createLines() {
|
||||
const projection = useStore().state.currentProjection,
|
||||
latLng = (x: number, y: number, z: number) => {
|
||||
return projection.locationToLatLng({x, y, z});
|
||||
};
|
||||
|
||||
this.lines.forEach((line: DynmapLine, id: string) => {
|
||||
this.createLine(id, line, latLng);
|
||||
});
|
||||
},
|
||||
|
||||
createLine(id: string, options: DynmapLine, latLng: Function) {
|
||||
const points = this.getPoints(options, latLng),
|
||||
line= new L.Polyline(points, options.style);
|
||||
|
||||
if(options.label) {
|
||||
line.bindPopup(() => {
|
||||
const popup = document.createElement('span');
|
||||
|
||||
if (options.popupContent) {
|
||||
popup.classList.add('LinePopup');
|
||||
popup.insertAdjacentHTML('afterbegin', options.popupContent);
|
||||
} else if (options.isHTML) {
|
||||
popup.classList.add('LinePopup');
|
||||
popup.insertAdjacentHTML('afterbegin', options.label);
|
||||
} else {
|
||||
popup.textContent = options.label;
|
||||
}
|
||||
|
||||
return popup;
|
||||
});
|
||||
}
|
||||
|
||||
this.layers.set(id, line);
|
||||
this.layerGroup.addLayer(line);
|
||||
},
|
||||
|
||||
getPoints(options: DynmapLine, latLng: Function): LatLngExpression[] {
|
||||
const points = [];
|
||||
|
||||
for(let i = 0; i < options.x.length; i++) {
|
||||
points.push(latLng(options.x[i], options.y[i], options.z[i]));
|
||||
}
|
||||
|
||||
return points;
|
||||
},
|
||||
|
||||
updateLine(id: string, options: DynmapLine, latLng: Function) {
|
||||
let line = this.layers.get(id) as L.Polyline,
|
||||
points = this.getPoints(options, latLng);
|
||||
|
||||
if (!line) {
|
||||
return;
|
||||
}
|
||||
|
||||
line.setLatLngs(points);
|
||||
line.redraw();
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
2
src/dynmap.d.ts
vendored
2
src/dynmap.d.ts
vendored
@ -203,7 +203,7 @@ interface DynmapLine {
|
||||
interface DynmapCircle {
|
||||
location: Coordinate;
|
||||
radius: PointTuple;
|
||||
style: CircleMarkerOptions;
|
||||
style: PathOptions;
|
||||
label: string;
|
||||
isHTML: boolean;
|
||||
minZoom?: number;
|
||||
|
Loading…
Reference in New Issue
Block a user