Added flyTo support ; targets players

The implementation forces Vue to attach vanilla event handlers, because their VDom doesn't bubble up and there's no way for it to easily communicate with Astro components.
Nanostores aren't an option because .astro files are rendered on the server, so the store can't be used client side (would be nice if it did tho!!!)
This commit is contained in:
Alexis
2023-10-13 17:44:52 +02:00
parent e654d3f96a
commit 085887615a
3 changed files with 179 additions and 176 deletions

View File

@@ -175,6 +175,14 @@ const { markers, players } = $world.get()
const measureControl = L.control.measure(rulerOptions); const measureControl = L.control.measure(rulerOptions);
measureControl.addTo(map); measureControl.addTo(map);
/**
* Flying to points of interests
*/
document.addEventListener('fly-to', (e) => {
const targetCoords = e.detail
map.flyTo([targetCoords.y, targetCoords.x], 5)
})
/** /**
* DEBUGS * DEBUGS
*/ */

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { allTasks } from 'nanostores'; import { allTasks } from 'nanostores';
import { useStore } from '@nanostores/vue' import { useStore } from '@nanostores/vue'
import { $world, flyTo } from '../worldStore'; import { $world } from '../worldStore';
import { useFocus, useMagicKeys, whenever } from '@vueuse/core'; import { useFocus, useMagicKeys, whenever } from '@vueuse/core';
import { computed, onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
@@ -9,7 +9,7 @@ import { computed, onMounted, ref } from 'vue';
$world.listen(() => {}) $world.listen(() => {})
await allTasks() await allTasks()
const { markers, players, lastCoords } = useStore($world).value const { markers, players } = useStore($world).value
// Search functions // Search functions
const qInput = ref() const qInput = ref()
@@ -48,20 +48,24 @@ whenever(shortcutKeyCombo, () => {
q.value = "" q.value = ""
}) })
// Player geolocation // Player geolocation (uses native JS to avoid changing leaflet library)
function handlePlayerTarget () { onMounted(() => {
flyTo(players.markerCoords) const playerBtnRef = document.querySelector('[data-to-players]')
} const flyToPlayers = new CustomEvent('fly-to', { bubbles: true, detail: players.markerCoords })
playerBtnRef?.addEventListener('click', () => {
playerBtnRef.dispatchEvent(flyToPlayers)
})
})
</script> </script>
<template> <template>
{{ lastCoords }}
<div ref="searchBar" class="search-w" :data-focused="shouldBeActive"> <div ref="searchBar" class="search-w" :data-focused="shouldBeActive">
<div class="input-w"> <div class="input-w">
<i class="search-icon ph-fill ph-magnifying-glass"></i> <i class="search-icon ph-fill ph-magnifying-glass"></i>
<input ref="qInput" type="text" v-model="q"> <input ref="qInput" type="text" v-model="q">
<button class="player-btn" @click.native="handlePlayerTarget"> <button data-to-players class="player-btn">
<i class="pin-icon ph-fill ph-map-pin"></i> <i class="pin-icon ph-fill ph-map-pin"></i>
</button> </button>
</div> </div>

View File

@@ -4,15 +4,6 @@ import type { MapCoords, MapMarker } from '../../types/Leaflet';
export const $world = deepMap({ export const $world = deepMap({
markers: [] as MapMarker[], markers: [] as MapMarker[],
players: {} as MapMarker, players: {} as MapMarker,
lastCoords: {
y: 0,
x: 0,
}
})
export const flyTo = action($world, 'fly-to', (store, coords: MapCoords) => {
store.setKey('lastCoords', coords)
return store.get()
}) })
// Fetch initial data // Fetch initial data