Migrate CoordinatesControl to vue
This commit is contained in:
parent
c51d2ef554
commit
7471bb794f
@ -14,12 +14,23 @@
|
||||
- limitations under the License.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="ui__element ui__panel location">
|
||||
<span class="value coordinates" :data-label="componentSettings.label">{{ formattedCoordinates }}</span>
|
||||
<span v-if="componentSettings.showChunk" class="value chunk"
|
||||
:data-label="chunkLabel">{{ formattedChunk }}</span>
|
||||
<span v-if="componentSettings.showRegion" class="value region"
|
||||
:data-label="regionLabel">{{ formattedRegion }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {computed, defineComponent, onMounted, onUnmounted} from "@vue/runtime-core";
|
||||
import {computed, defineComponent, onUnmounted, watch} from "@vue/runtime-core";
|
||||
import {useStore} from "@/store";
|
||||
import {CoordinatesControl, CoordinatesControlOptions} from "@/leaflet/control/CoordinatesControl";
|
||||
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
|
||||
import {watch} from "vue";
|
||||
import {onMounted, ref} from "vue";
|
||||
import {Coordinate, CoordinatesControlOptions} from "@/index";
|
||||
import {LeafletMouseEvent} from "leaflet";
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -31,26 +42,129 @@ export default defineComponent({
|
||||
|
||||
setup(props) {
|
||||
const store = useStore(),
|
||||
componentSettings = computed(() => store.state.components.coordinatesControl);
|
||||
let control = new CoordinatesControl(componentSettings.value as CoordinatesControlOptions);
|
||||
componentSettings = computed(() => store.state.components.coordinatesControl),
|
||||
currentMap = computed(() => store.state.currentMap),
|
||||
|
||||
watch(componentSettings, (newSettings) => {
|
||||
props.leaflet.removeControl(control);
|
||||
chunkLabel = computed(() => store.state.messages.locationChunk),
|
||||
regionLabel = computed(() => store.state.messages.locationRegion),
|
||||
|
||||
if(!newSettings) {
|
||||
coordinates = ref<Coordinate|null>(null),
|
||||
|
||||
formattedCoordinates = computed(() => {
|
||||
if(coordinates.value) {
|
||||
const x = Math.round(coordinates.value.x).toString().padStart(5, ' '),
|
||||
y = coordinates.value.y.toString().padStart(3, ' '),
|
||||
z = Math.round(coordinates.value.z).toString().padStart(5, ' ');
|
||||
|
||||
return componentSettings.value!.showY ? `${x}, ${y}, ${z}` : `${x}, ${z}`;
|
||||
} else {
|
||||
return componentSettings.value!.showY ? '-----, ---, -----' : '-----, -----';
|
||||
}
|
||||
}),
|
||||
|
||||
formattedChunk = computed(() => {
|
||||
if(coordinates.value) {
|
||||
const chunkX = Math.floor(coordinates.value.x / 16).toString().padStart(4, ' '),
|
||||
chunkZ = Math.floor(coordinates.value.z / 16).toString().padStart(4, ' ');
|
||||
|
||||
return `${chunkX}, ${chunkZ}`;
|
||||
} else {
|
||||
return '----, ----'
|
||||
}
|
||||
}),
|
||||
|
||||
formattedRegion = computed(() => {
|
||||
if(coordinates.value) {
|
||||
const regionX = Math.floor(coordinates.value.x / 512).toString().padStart(3, ' '),
|
||||
regionZ = Math.floor(coordinates.value.z / 512).toString().padStart(3, ' ');
|
||||
|
||||
return `r.${regionX}, ${regionZ}.mca`;
|
||||
} else {
|
||||
return '--------------';
|
||||
}
|
||||
});
|
||||
|
||||
const onMouseMove = (event: LeafletMouseEvent) => {
|
||||
if (!store.state.currentMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
control = new CoordinatesControl(newSettings as CoordinatesControlOptions);
|
||||
props.leaflet.addControl(control);
|
||||
}, {deep: true});
|
||||
coordinates.value = store.state.currentMap.latLngToLocation(event.latlng, store.state.currentWorld!.seaLevel + 1);
|
||||
}
|
||||
|
||||
onMounted(() => props.leaflet.addControl(control));
|
||||
onUnmounted(() => props.leaflet.removeControl(control));
|
||||
},
|
||||
const onMouseOut = () => coordinates.value = null;
|
||||
|
||||
render() {
|
||||
return null;
|
||||
watch(currentMap, newValue => {
|
||||
if(!newValue) {
|
||||
coordinates.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
props.leaflet.on('mousemove', onMouseMove);
|
||||
props.leaflet.on('mouseout', onMouseOut);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
props.leaflet.off('mousemove', onMouseMove);
|
||||
props.leaflet.off('mouseout', onMouseOut);
|
||||
});
|
||||
|
||||
return {
|
||||
componentSettings,
|
||||
chunkLabel,
|
||||
regionLabel,
|
||||
formattedCoordinates,
|
||||
formattedChunk,
|
||||
formattedRegion
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.location {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.6rem 1.5rem;
|
||||
flex-direction: row;
|
||||
|
||||
.value {
|
||||
line-height: 1;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
font-size: 2rem;
|
||||
|
||||
&[data-label]:before {
|
||||
content: attr(data-label);
|
||||
display: block;
|
||||
line-height: 1;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1.25rem;
|
||||
font-family: Raleway, sans-serif;;
|
||||
}
|
||||
|
||||
& + .value {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.region {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px), (max-height: 480px) {
|
||||
.value {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 384px) {
|
||||
.chunk {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
8
src/index.d.ts
vendored
8
src/index.d.ts
vendored
@ -26,7 +26,6 @@ import {
|
||||
PointTuple,
|
||||
PolylineOptions
|
||||
} from "leaflet";
|
||||
import {CoordinatesControlOptions} from "@/leaflet/control/CoordinatesControl";
|
||||
import {LogoControlOptions} from "@/leaflet/control/LogoControl";
|
||||
import {globalMessages, serverMessages} from "../messages";
|
||||
import {LiveAtlasMarkerType} from "@/util/markers";
|
||||
@ -297,6 +296,13 @@ export interface ClockControlOptions extends ControlOptions {
|
||||
showWeather: boolean;
|
||||
}
|
||||
|
||||
export interface CoordinatesControlOptions extends ControlOptions {
|
||||
showY: boolean;
|
||||
showRegion: boolean;
|
||||
showChunk: boolean;
|
||||
label: string;
|
||||
}
|
||||
|
||||
interface LiveAtlasPartialComponentConfig {
|
||||
markers?: {
|
||||
showLabels: boolean;
|
||||
|
@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 James Lyne
|
||||
*
|
||||
* Some portions of this file were taken from https://github.com/webbukkit/dynmap.
|
||||
* These portions are Copyright 2020 Dynmap Contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {ControlOptions, LeafletMouseEvent, Control, Map, DomUtil, Util} from 'leaflet';
|
||||
import {useStore} from "@/store";
|
||||
import {Coordinate} from "@/index";
|
||||
|
||||
const store = useStore();
|
||||
|
||||
export interface CoordinatesControlOptions extends ControlOptions {
|
||||
showY: boolean;
|
||||
showRegion: boolean;
|
||||
showChunk: boolean;
|
||||
label: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaflet map control which displays in-game block coordinates when hovering over or tapping the map
|
||||
*/
|
||||
export class CoordinatesControl extends Control {
|
||||
declare options: CoordinatesControlOptions;
|
||||
declare _map ?: Map;
|
||||
|
||||
private _location?: Coordinate;
|
||||
private _locationChanged: boolean = false;
|
||||
private readonly _coordsContainer: HTMLSpanElement;
|
||||
private readonly _regionContainer: HTMLSpanElement;
|
||||
private readonly _chunkContainer: HTMLSpanElement;
|
||||
|
||||
constructor(options: CoordinatesControlOptions) {
|
||||
super(options);
|
||||
|
||||
this._coordsContainer = DomUtil.create('span', 'value coordinates');
|
||||
this._chunkContainer = DomUtil.create('span', 'value chunk');
|
||||
this._regionContainer = DomUtil.create('span', 'value region');
|
||||
|
||||
options.position = 'bottomleft';
|
||||
Util.setOptions(this, options);
|
||||
}
|
||||
|
||||
onAdd(map: Map) {
|
||||
const container = DomUtil.create('div', 'leaflet-control-coordinates');
|
||||
|
||||
this._coordsContainer.textContent = this.options.showY ? '-----, ---, -----' : '-----, -----';
|
||||
this._coordsContainer.dataset.label = this.options.label;
|
||||
container.appendChild(this._coordsContainer);
|
||||
|
||||
if (this.options.showRegion) {
|
||||
this._regionContainer.textContent = '--------------';
|
||||
this._regionContainer.dataset.label = store.state.messages.locationRegion;
|
||||
container.appendChild(this._regionContainer);
|
||||
}
|
||||
|
||||
if (this.options.showChunk) {
|
||||
this._chunkContainer.textContent = '----, ----';
|
||||
this._chunkContainer.dataset.label = store.state.messages.locationChunk;
|
||||
container.appendChild(this._chunkContainer);
|
||||
}
|
||||
|
||||
map.on('mousemove', this._onMouseMove, this);
|
||||
map.on('mouseout', this._onMouseOut, this);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
remove() {
|
||||
if (!this._map) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this._map.off('mousemove', this._onMouseMove, this);
|
||||
this._map.off('mouseout', this._onMouseOut, this);
|
||||
super.remove();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
_onMouseMove(event: LeafletMouseEvent) {
|
||||
if (!this._map || !store.state.currentMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._location = store.state.currentMap.latLngToLocation(event.latlng, store.state.currentWorld!.seaLevel + 1);
|
||||
|
||||
if(!this._locationChanged) {
|
||||
this._locationChanged = true;
|
||||
requestAnimationFrame(() => this._update());
|
||||
}
|
||||
}
|
||||
|
||||
_onMouseOut() {
|
||||
if (!this._map) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._location = undefined;
|
||||
|
||||
if(!this._locationChanged) {
|
||||
this._locationChanged = true;
|
||||
requestAnimationFrame(() => this._update());
|
||||
}
|
||||
}
|
||||
|
||||
_update() {
|
||||
if (!this._map || !store.state.currentWorld || !this._locationChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._locationChanged = false;
|
||||
|
||||
if(!this._location) {
|
||||
if (this.options.showY) {
|
||||
this._coordsContainer.textContent = '-----, ---, -----';
|
||||
} else {
|
||||
this._coordsContainer.textContent = '-----, -----';
|
||||
}
|
||||
|
||||
if (this.options.showRegion) {
|
||||
this._regionContainer.textContent = '--------------';
|
||||
}
|
||||
|
||||
if (this.options.showChunk) {
|
||||
this._chunkContainer.textContent = '----, ----';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const x = Math.round(this._location.x).toString().padStart(5, ' '),
|
||||
y = this._location.y.toString().padStart(3, ' '),
|
||||
z = Math.round(this._location.z).toString().padStart(5, ' '),
|
||||
regionX = Math.floor(this._location.x / 512).toString().padStart(3, ' '),
|
||||
regionZ = Math.floor(this._location.z / 512).toString().padStart(3, ' '),
|
||||
chunkX = Math.floor(this._location.x / 16).toString().padStart(4, ' '),
|
||||
chunkZ = Math.floor(this._location.z / 16).toString().padStart(4, ' ');
|
||||
|
||||
if (this.options.showY) {
|
||||
this._coordsContainer.textContent = `${x}, ${y}, ${z}`;
|
||||
} else {
|
||||
this._coordsContainer.textContent = `${x}, ${z}`;
|
||||
}
|
||||
|
||||
if (this.options.showRegion) {
|
||||
this._regionContainer.textContent = `r.${regionX}, ${regionZ}.mca`;
|
||||
}
|
||||
|
||||
if (this.options.showChunk) {
|
||||
this._chunkContainer.textContent = `${chunkX}, ${chunkZ}`;
|
||||
}
|
||||
}
|
||||
}
|
@ -99,50 +99,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-control-coordinates {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem 1.5rem;
|
||||
|
||||
.value {
|
||||
line-height: 1;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
font-size: 2rem;
|
||||
|
||||
&[data-label]:before {
|
||||
content: attr(data-label);
|
||||
display: block;
|
||||
line-height: 1;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1.25rem;
|
||||
font-family: Raleway, sans-serif;;
|
||||
}
|
||||
|
||||
& + .value {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.region {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px), (max-height: 480px) {
|
||||
.value {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 384px) {
|
||||
.chunk {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-control-layers {
|
||||
width: auto;
|
||||
border: none;
|
||||
|
Loading…
Reference in New Issue
Block a user