Compare commits
26 Commits
features/m
...
1.2.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f58f45954 | ||
|
|
d695e60a2f | ||
|
|
f35d0e23b8 | ||
|
|
54a4f8bdf5 | ||
|
|
c8e8f61f8a | ||
|
|
4e347e7d7d | ||
|
|
6086161a78 | ||
|
|
3a6abdaf93 | ||
|
|
27b3dfa52d | ||
|
|
92c7846247 | ||
|
|
2136ebf1d4 | ||
|
|
0819f1063a | ||
|
|
b2351240a5 | ||
|
|
be9b2d5a7f | ||
|
|
b5f9a77e40 | ||
|
|
a9fa3d2f9a | ||
|
|
45ead84c20 | ||
|
|
21b3aca968 | ||
|
|
89e81093cc | ||
|
|
ebce56aeff | ||
|
|
075bf3e948 | ||
|
|
cc9b7704c4 | ||
|
|
93fa674b15 | ||
|
|
fd018ba4c3 | ||
|
|
721f0d3d44 | ||
|
|
aaad18e07f |
@@ -2,4 +2,4 @@
|
|||||||
Repository for interactive maps using Leim's Wiki data
|
Repository for interactive maps using Leim's Wiki data
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
Live demo available at https://maps.alexcreates.fr/
|
Live demo available at https://maps.alexcreates.fr
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
import vue from "@astrojs/vue";
|
import vue from "@astrojs/vue";
|
||||||
|
import sitemap from "@astrojs/sitemap";
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [vue()],
|
integrations: [vue(), sitemap()],
|
||||||
output: 'static',
|
output: 'static',
|
||||||
site: 'https://maps.alexcreates.fr'
|
site: 'https://maps.alexcreates.fr'
|
||||||
});
|
});
|
||||||
|
|||||||
5769
package-lock.json
generated
18
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "leim-maps",
|
"name": "leim-maps",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.0.0",
|
"version": "1.2.4",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"start": "astro dev",
|
"start": "astro dev",
|
||||||
@@ -10,16 +10,14 @@
|
|||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "^6.0.3",
|
"@astrojs/sitemap": "^3.1.4",
|
||||||
"@astrojs/vue": "^3.0.1",
|
"@astrojs/vue": "^4.1.0",
|
||||||
"@nanostores/vue": "^0.10.0",
|
"@types/leaflet": "^1.9.12",
|
||||||
"@types/leaflet": "^1.9.6",
|
"@vueuse/core": "^10.9.0",
|
||||||
"@vueuse/core": "^10.7.1",
|
"astro": "^4.7.1",
|
||||||
"astro": "^3.2.0",
|
"vue": "^3.4.27"
|
||||||
"nanostores": "^0.9.3",
|
|
||||||
"vue": "^3.3.4"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"sass": "^1.68.0"
|
"sass": "^1.77.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
public/bailey-zindel-NRQV-hBF10M-unsplash.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
public/icon/graduation-cap-shadow.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/icon/graduation-cap.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
1
public/icon/square-arrow-out.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M224,104a8,8,0,0,1-13.66,5.66L184,83.31l-42.34,42.35a8,8,0,0,1-11.32-11.32L172.69,72,146.34,45.66A8,8,0,0,1,152,32h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 392 B |
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
@@ -69,6 +69,10 @@
|
|||||||
font-size: .85em;
|
font-size: .85em;
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.btn-shadow {
|
&.btn-shadow {
|
||||||
|
|||||||
@@ -43,10 +43,13 @@ a[href^='http'] {
|
|||||||
|
|
||||||
a[href^='http']::after {
|
a[href^='http']::after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "\e972";
|
content: url('/icon/square-arrow-out.svg');
|
||||||
font-family: 'Phosphor-Fill' !important;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
margin-left: .25em;
|
margin-left: .25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
@@ -106,6 +106,7 @@ for (let i = 0; i < markers.length; i++) {
|
|||||||
const coords = [convertYToScale(m.markerCoords.y), convertXToScale(m.markerCoords.x)]
|
const coords = [convertYToScale(m.markerCoords.y), convertXToScale(m.markerCoords.x)]
|
||||||
|
|
||||||
let markerIcon
|
let markerIcon
|
||||||
|
let markerIconOverride
|
||||||
|
|
||||||
switch (m.group) {
|
switch (m.group) {
|
||||||
case "capitals":
|
case "capitals":
|
||||||
@@ -154,7 +155,20 @@ for (let i = 0; i < markers.length; i++) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
const marker = L.marker(coords, { icon: markerIcon }).addTo(map)
|
// Handle icon override if it's specified
|
||||||
|
markerIconOverride = markerIcon
|
||||||
|
if (m.icon) {
|
||||||
|
markerIconOverride = L.icon({
|
||||||
|
iconUrl: `icon/${m.icon}.png`,
|
||||||
|
shadowUrl: `icon/${m.icon}-shadow.png`,
|
||||||
|
iconSize: [25, 25],
|
||||||
|
shadowSize: [35, 30],
|
||||||
|
iconAnchor: [12.5, 8],
|
||||||
|
shadowAnchor: [11, 12]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const marker = L.marker(coords, { icon: markerIconOverride }).addTo(map)
|
||||||
let popupContent = ""
|
let popupContent = ""
|
||||||
if (m.link) {
|
if (m.link) {
|
||||||
popupContent = `
|
popupContent = `
|
||||||
@@ -256,7 +270,7 @@ L.Control.Measure.include({
|
|||||||
const rulerDistanceRatio = 2
|
const rulerDistanceRatio = 2
|
||||||
|
|
||||||
const rulerOptions = {
|
const rulerOptions = {
|
||||||
position: 'topright',
|
position: 'bottomleft',
|
||||||
primaryLengthUnit: 'kilometers',
|
primaryLengthUnit: 'kilometers',
|
||||||
secondaryLengthUnit: 'days',
|
secondaryLengthUnit: 'days',
|
||||||
primaryAreaUnit: 'hectares',
|
primaryAreaUnit: 'hectares',
|
||||||
@@ -443,6 +457,84 @@ function removeCustomMarker(marker, markerTitle) {
|
|||||||
saveCustomMarkers()
|
saveCustomMarkers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL PARAMETERS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From the leaflet setup, get a working param config
|
||||||
|
*
|
||||||
|
* @returns Latitude, Longitude and zoom level of the map
|
||||||
|
*/
|
||||||
|
function getURLFromSetup() {
|
||||||
|
const centerOfMap = map.getCenter()
|
||||||
|
|
||||||
|
const lat = centerOfMap.lat
|
||||||
|
const lon = centerOfMap.lng
|
||||||
|
const zoom = parseFloat(map.getZoom().toFixed(1))
|
||||||
|
|
||||||
|
return { lat, lon, zoom }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get leaflet coords from URL params
|
||||||
|
*
|
||||||
|
* @returns URLSearchParams
|
||||||
|
*/
|
||||||
|
function getCoordsSetupFromURL() {
|
||||||
|
const params = new URL(document.location).searchParams
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the params in the URL can be parsed as leaflet coordinates
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function hasInitialSetup() {
|
||||||
|
const params = new URL(document.location).searchParams
|
||||||
|
|
||||||
|
return params.has('lat') && params.has('lon')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to refresh the URL params
|
||||||
|
*
|
||||||
|
* @returns void
|
||||||
|
*/
|
||||||
|
function setupToURL() {
|
||||||
|
const setup = getURLFromSetup()
|
||||||
|
|
||||||
|
const newParams = new URLSearchParams(setup)
|
||||||
|
const newUrl = new URL(window.location.href)
|
||||||
|
newUrl.search = newParams.toString()
|
||||||
|
|
||||||
|
window.history.replaceState(null, '', newUrl.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses the URL params to setup the leaflet map
|
||||||
|
*/
|
||||||
|
function setupFromURL() {
|
||||||
|
const setup = getCoordsSetupFromURL()
|
||||||
|
|
||||||
|
map.setView({ lat: setup.get('lat'), lng: setup.get('lon') }, setup.get('zoom') | minZoom, { animate: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the map has initial params in the URL
|
||||||
|
// If not, just setup the default URL
|
||||||
|
if (hasInitialSetup()) {
|
||||||
|
setupFromURL()
|
||||||
|
} else {
|
||||||
|
setupToURL()
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the map stops moving, update the URL to keep it up to date
|
||||||
|
map.on('moveend', () => {
|
||||||
|
setupToURL()
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UTILITIES
|
* UTILITIES
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -784,6 +784,94 @@
|
|||||||
"x": 105.79962111804268,
|
"x": 105.79962111804268,
|
||||||
"y": -82.40552057309549
|
"y": -82.40552057309549
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "Faculté de Magie Appliquée",
|
||||||
|
"description": "Établissement d'enseignements arcaniques tout public, mais à la qualité lacunaire.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/Facult%C3%A9_de_Magie_Appliqu%C3%A9e",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 103.96761286182101,
|
||||||
|
"y": -79.90785827537563
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "Académie Artistique Arcanique",
|
||||||
|
"description": "Institut d'apprentissage public centré sur les arts.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/Acad%C3%A9mie_Artistique_Arcanique",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 75.84445789595449,
|
||||||
|
"y": -199.14437153165204
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "Académie Centrale Kaldélienne",
|
||||||
|
"description": "Une des plus grandes académies dispensant des cours de magie de l'Alliance. L'examen d'entrée est public, mais les coûts de scolarité restent à la charge des étudiants.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/Acad%C3%A9mie_Centrale_Kald%C3%A9lienne",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 83.80737652386473,
|
||||||
|
"y": -184.52963682119173
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "Grande Maison de Flamberge",
|
||||||
|
"description": "La plus prestigieuse école des Terres de Syaltha. La Grande Maison est une des rares entités à certifier les sal'kayas.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/Grande_Maison_de_Flamberge",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 302.23491236190273,
|
||||||
|
"y": -110.07337124956246
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "Haute-École de Magistrature Cordouenne",
|
||||||
|
"description": "Institut de l'Alliance formant les magistrats, juges et politiciens de demain.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/Haute-%C3%89cole_de_Magistrature_Cordouenne",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 131.07900289783518,
|
||||||
|
"y": -148.801890020031
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "Institut du Fer Blanc",
|
||||||
|
"description": "Première école militaire de l'Alliance Kaldélienne.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/Institut_du_Fer_Blanc",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 140.3159943633407,
|
||||||
|
"y": -191.78102982328744
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "Maison d'Études de Tourgrise",
|
||||||
|
"description": "Établissement pluridisciplinaires axé vers les études de législations mais possèdant un cursus d'études arcaniques général.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/Maison_d%27%C3%89tudes_de_Tourgrise",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 132.82148271354282,
|
||||||
|
"y": -98.7924395350658
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": "landmarks",
|
||||||
|
"title": "École des Arts Spirituels",
|
||||||
|
"description": "Institut privé spécialisé dans les maîtrises des arcanes spirituelles.",
|
||||||
|
"link": "https://alexcreates.fr/leim/index.php/%C3%89cole_des_Arts_Spirituels",
|
||||||
|
"markerCoords": {
|
||||||
|
"x": 124.8585640856326,
|
||||||
|
"y": -95.86995303475213
|
||||||
|
},
|
||||||
|
"icon": "graduation-cap"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { MapMarker } from '@/types/Leaflet';
|
import type { MapMarker } from '@/types/Leaflet';
|
||||||
import { onClickOutside, onLongPress, useCssVar, useFocus, useLocalStorage, useMouse, useTimeout, useTimeoutFn } from '@vueuse/core'
|
import { onClickOutside, useCssVar, useLocalStorage, useMouse } from '@vueuse/core'
|
||||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
import { computed, onMounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
const markerMenu = ref<HTMLMenuElement>()
|
const markerMenu = ref<HTMLMenuElement>()
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ function setTitleError(error: Error | null) {
|
|||||||
Ajouter un marqueur personnel
|
Ajouter un marqueur personnel
|
||||||
</h2>
|
</h2>
|
||||||
<p class="modal-notice">
|
<p class="modal-notice">
|
||||||
<i class="icon ph-light ph-warning"></i>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="icon"><rect width="256" height="256" fill="none"/><path d="M142.41,40.22l87.46,151.87C236,202.79,228.08,216,215.46,216H40.54C27.92,216,20,202.79,26.13,192.09L113.59,40.22C119.89,29.26,136.11,29.26,142.41,40.22Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"/><line x1="128" y1="144" x2="128" y2="104" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"/><circle cx="128" cy="180" r="10"/></svg>
|
||||||
<span>Le marqueur sera sauvegardé mais n'apparaîtra que sur votre carte !</span>
|
<span>Le marqueur sera sauvegardé mais n'apparaîtra que sur votre carte !</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -242,7 +242,7 @@ function setTitleError(error: Error | null) {
|
|||||||
|
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<button class="btn btn-danger btn-icon btn-shadow" @click="hideMarkerModal">
|
<button class="btn btn-danger btn-icon btn-shadow" @click="hideMarkerModal">
|
||||||
<i class="ph-light ph-x"></i>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="icon"><rect width="256" height="256" fill="none"/><line x1="200" y1="56" x2="56" y2="200" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="200" y1="200" x2="56" y2="56" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
@@ -340,7 +340,7 @@ dialog {
|
|||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 1.3em;
|
width: 1.3em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { MapMarker, MapMarkerGroup, PlayerMarker } from '@/types/Leaflet';
|
import type { MapMarker, MapMarkerGroup, PlayerMarker } from '@/types/Leaflet';
|
||||||
import type { SearchMode } from '@/types/Search';
|
import type { SearchMode } from '@/types/Search';
|
||||||
import { useFocus, useLocalStorage, useMagicKeys, whenever } from '@vueuse/core';
|
import { onClickOutside, useFocus, useFocusWithin, useLocalStorage, useMagicKeys, whenever } from '@vueuse/core';
|
||||||
import { computed, onMounted, ref, onUpdated, watch } from 'vue';
|
import { computed, onMounted, ref, onUpdated, watch } from 'vue';
|
||||||
import SearchMarkersTags from './SearchMarkersTags.vue';
|
import SearchMarkersTags from './SearchMarkersTags.vue';
|
||||||
|
|
||||||
@@ -19,13 +19,15 @@ const allMarkers = computed(() => {
|
|||||||
|
|
||||||
// Search functions
|
// Search functions
|
||||||
const searchBar = ref<HTMLDivElement>()
|
const searchBar = ref<HTMLDivElement>()
|
||||||
|
const searchBarWrapper = ref<HTMLDivElement>()
|
||||||
const qInput = ref()
|
const qInput = ref()
|
||||||
const { focused: isFocused } = useFocus(qInput)
|
const { focused: isComponentFocused } = useFocusWithin(searchBarWrapper)
|
||||||
|
const { focused: isSearchFocused } = useFocus(qInput)
|
||||||
|
|
||||||
const currentSearchMode = ref<SearchMode>('query')
|
const currentSearchMode = ref<SearchMode>('query')
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
isFocused.value = true
|
isSearchFocused.value = true
|
||||||
})
|
})
|
||||||
|
|
||||||
const hasQuery = computed(() => q.value.length > 0)
|
const hasQuery = computed(() => q.value.length > 0)
|
||||||
@@ -57,8 +59,8 @@ const filteredMarkers = computed(() => {
|
|||||||
|
|
||||||
// Limit of menu list dropdown
|
// Limit of menu list dropdown
|
||||||
const currentLimit = computed(() => {
|
const currentLimit = computed(() => {
|
||||||
if (currentSearchMode.value === "query") return 10
|
if (currentSearchMode.value === "query") return 50
|
||||||
return 100
|
return 500
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,11 +72,10 @@ const shortcutKeyCombo = keys['Shift+Period']
|
|||||||
const eraseKeyCombo = keys['Escape']
|
const eraseKeyCombo = keys['Escape']
|
||||||
|
|
||||||
whenever(shortcutKeyCombo, () => {
|
whenever(shortcutKeyCombo, () => {
|
||||||
isFocused.value = true
|
isSearchFocused.value = true
|
||||||
})
|
})
|
||||||
whenever(eraseKeyCombo, () => {
|
whenever(eraseKeyCombo, () => {
|
||||||
resetAllFields()
|
resetAllFields('focusAfter')
|
||||||
isFocused.value = true
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// If query changes and has new value...
|
// If query changes and has new value...
|
||||||
@@ -82,6 +83,9 @@ watch(q, (n, o) => {
|
|||||||
if (n) setSearchMode('query')
|
if (n) setSearchMode('query')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Toggle menu if clicked outside
|
||||||
|
onClickOutside(searchBarWrapper, () => setSearchMode('query'))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Player geolocation
|
* Player geolocation
|
||||||
* Uses native JS to avoid changing leaflet library
|
* Uses native JS to avoid changing leaflet library
|
||||||
@@ -133,6 +137,26 @@ function handleCategorySwitch(g: MapMarkerGroup) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Markers handling
|
||||||
|
*/
|
||||||
|
onMounted(() => {
|
||||||
|
customMarkersData.value = useLocalStorage('custom-markers', []).value
|
||||||
|
|
||||||
|
document.addEventListener('refresh-custom-markers', () => {
|
||||||
|
customMarkersData.value = useLocalStorage('custom-markers', []).value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit event to delete custom marker
|
||||||
|
*/
|
||||||
|
function emitDeleteCustomMarker(markerTitle: string) {
|
||||||
|
const deleteCMarkerEvent = new CustomEvent(`delete-${markerTitle}`, { bubbles: true })
|
||||||
|
|
||||||
|
searchBar.value?.dispatchEvent(deleteCMarkerEvent)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EVENTS
|
* EVENTS
|
||||||
*/
|
*/
|
||||||
@@ -163,45 +187,27 @@ function resetQueryValue() {
|
|||||||
*/
|
*/
|
||||||
function resetAllFields(actionAfter?: "focusAfter") {
|
function resetAllFields(actionAfter?: "focusAfter") {
|
||||||
setSearchMode('query')
|
setSearchMode('query')
|
||||||
|
|
||||||
resetQueryValue()
|
resetQueryValue()
|
||||||
|
|
||||||
if (actionAfter === "focusAfter") isFocused.value = true
|
if (actionAfter === "focusAfter") isSearchFocused.value = true
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CUSTOM MARKERS HANDLING
|
|
||||||
*/
|
|
||||||
onMounted(() => {
|
|
||||||
customMarkersData.value = useLocalStorage('custom-markers', []).value
|
|
||||||
|
|
||||||
document.addEventListener('refresh-custom-markers', () => {
|
|
||||||
customMarkersData.value = useLocalStorage('custom-markers', []).value
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emit event to delete custom marker
|
|
||||||
*/
|
|
||||||
function emitDeleteCustomMarker(markerTitle: string) {
|
|
||||||
const deleteCMarkerEvent = new CustomEvent(`delete-${markerTitle}`, { bubbles: true })
|
|
||||||
|
|
||||||
searchBar.value?.dispatchEvent(deleteCMarkerEvent)
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<nav class="toolbar">
|
<nav ref="searchBarWrapper" class="toolbar">
|
||||||
<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>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="search-icon"><rect width="256" height="256" fill="none"/><path d="M168,112a56,56,0,1,1-56-56A56,56,0,0,1,168,112Zm61.66,117.66a8,8,0,0,1-11.32,0l-50.06-50.07a88,88,0,1,1,11.32-11.31l50.06,50.06A8,8,0,0,1,229.66,229.66ZM112,184a72,72,0,1,0-72-72A72.08,72.08,0,0,0,112,184Z"/></svg>
|
||||||
|
|
||||||
<input ref="qInput" class="" name="recherche" type="text" v-model="q" title="Rechercher le monde" placeholder="Ville, point d'intérêt…">
|
<input ref="qInput" class="" name="recherche" type="text" v-model="q" title="Rechercher le monde" placeholder="Ville, point d'intérêt…">
|
||||||
|
|
||||||
<button v-if="hasGroupFilter || hasQuery" @click="onCloseQuery" class="close-btn" title="Enlever le filtre">
|
<button v-if="hasGroupFilter || hasQuery" @click="onCloseQuery" class="close-btn" title="Enlever le filtre">
|
||||||
<i class="ph-light ph-x"></i>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="icon"><rect width="256" height="256" fill="none"/><line x1="200" y1="56" x2="56" y2="200" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"/><line x1="200" y1="200" x2="56" y2="56" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"/></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button v-if="hasPlayers" data-to-players class="player-btn" :tabindex="shouldBeActive ? 1 : 0" title="Aller à la position actuelle des joueurs">
|
<button v-if="hasPlayers" data-to-players class="player-btn" :tabindex="shouldBeActive ? 1 : 0" title="Aller à la position actuelle des joueurs">
|
||||||
<i class="pin-icon ph-fill ph-map-pin"></i>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="icon"><rect width="256" height="256" fill="none"/><path d="M128,16a88.1,88.1,0,0,0-88,88c0,75.3,80,132.17,83.41,134.55a8,8,0,0,0,9.18,0C136,236.17,216,179.3,216,104A88.1,88.1,0,0,0,128,16Zm0,56a32,32,0,1,1-32,32A32,32,0,0,1,128,72Z"/></svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -218,20 +224,24 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
|
|
||||||
<div class="desc" v-html="m.description"></div>
|
<div class="desc" v-html="m.description"></div>
|
||||||
|
|
||||||
<div class="icon">
|
<div v-if="m.icon">
|
||||||
<i v-if="m.group === 'quests'" class="ph-fill ph-flag-banner"></i>
|
<svg v-if="m.icon === 'graduation-cap'" xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 256 256"><path d="M251.76,88.94l-120-64a8,8,0,0,0-7.52,0l-120,64a8,8,0,0,0,0,14.12L32,117.87v48.42a15.91,15.91,0,0,0,4.06,10.65C49.16,191.53,78.51,216,128,216a130,130,0,0,0,48-8.76V240a8,8,0,0,0,16,0V199.51a115.63,115.63,0,0,0,27.94-22.57A15.91,15.91,0,0,0,224,166.29V117.87l27.76-14.81a8,8,0,0,0,0-14.12ZM128,200c-43.27,0-68.72-21.14-80-33.71V126.4l76.24,40.66a8,8,0,0,0,7.52,0L176,143.47v46.34C163.4,195.69,147.52,200,128,200Zm80-33.75a97.83,97.83,0,0,1-16,14.25V134.93l16-8.53ZM188,118.94l-.22-.13-56-29.87a8,8,0,0,0-7.52,14.12L171,128l-43,22.93L25,96,128,41.07,231,96Z"></path></svg>
|
||||||
<i v-else-if="m.group === 'landmarks'" class="ph-fill ph-castle-turret"></i>
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<svg v-if="m.group === 'quests'" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M231.22,59.44l-80,168a8,8,0,1,1-14.44-6.88L165.62,160H32a8,8,0,0,1-5.88-13.43l42.56-46.1L26.59,61.9A8,8,0,0,1,32,48H224a8,8,0,0,1,7.22,11.44Z"/></svg>
|
||||||
|
<svg v-else-if="m.group === 'capitals'" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M200,24h-8a16,16,0,0,0-16,16V56H148V40a16,16,0,0,0-16-16h-8a16,16,0,0,0-16,16V56H80V40A16,16,0,0,0,64,24H56A16,16,0,0,0,40,40V84.69A15.86,15.86,0,0,0,44.69,96L56,107.31V216a16,16,0,0,0,16,16H184a16,16,0,0,0,16-16V107.31L211.31,96A15.86,15.86,0,0,0,216,84.69V40A16,16,0,0,0,200,24ZM152,216H104V152a24,24,0,0,1,48,0Z"/></svg>
|
||||||
|
<svg v-else-if="m.group === 'landmarks'" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M208,80a8,8,0,0,0-8,8v16H188.85L184,55.2A8,8,0,0,0,181.31,50h0L138.44,11.88l-.2-.17a16,16,0,0,0-20.48,0l-.2.17L74.68,50v0A7.93,7.93,0,0,0,72,55.2L67.15,104H56V88a8,8,0,0,0-16,0v24a8,8,0,0,0,8,8H65.54l-9.47,94.48A16,16,0,0,0,72,232H184a16,16,0,0,0,15.92-17.56L190.46,120H208a8,8,0,0,0,8-8V88A8,8,0,0,0,208,80ZM87.24,64h81.52l4,40H136V88a8,8,0,0,0-16,0v16H83.23ZM72,216l4.81-48H179.19L184,216Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Custom marker actions -->
|
<!-- Custom marker actions -->
|
||||||
<div class="search-item-actions" v-if="m.group === 'custom'">
|
<div class="search-item-actions" v-if="m.group === 'custom'">
|
||||||
<!-- <button class="btn btn-info btn-icon btn-sm">
|
<!-- <button class="btn btn-info btn-icon btn-sm">
|
||||||
<i class="ph-light ph-pencil-simple-line"></i>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="icon"><rect width="256" height="256" fill="none"/><path d="M92.69,216H48a8,8,0,0,1-8-8V163.31a8,8,0,0,1,2.34-5.65L165.66,34.34a8,8,0,0,1,11.31,0L221.66,79a8,8,0,0,1,0,11.31L98.34,213.66A8,8,0,0,1,92.69,216Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="136" y1="64" x2="192" y2="120" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||||
</button> -->
|
</button> -->
|
||||||
|
|
||||||
<button class="btn btn-danger btn-icon btn-sm" @click="emitDeleteCustomMarker(m.title)">
|
<button class="btn btn-danger btn-icon btn-sm" @click="emitDeleteCustomMarker(m.title)">
|
||||||
<i class="ph-light ph-trash"></i>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" class="icon"><rect width="256" height="256" fill="none"/><line x1="216" y1="56" x2="40" y2="56" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="104" y1="104" x2="104" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><line x1="152" y1="104" x2="152" y2="168" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M200,56V208a8,8,0,0,1-8,8H64a8,8,0,0,1-8-8V56" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path d="M168,56V40a16,16,0,0,0-16-16H104A16,16,0,0,0,88,40V56" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@@ -272,12 +282,12 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
$search-icon-size: 1.2em;
|
$search-icon-size: 1.2em;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-block: .2rem;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: $search-items-gap;
|
gap: $search-items-gap;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
padding-block: .2rem;
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 10rem;
|
min-width: 10rem;
|
||||||
padding-inline-start: calc($search-icon-size + $search-items-gap);
|
padding-inline-start: calc($search-icon-size + $search-items-gap);
|
||||||
@@ -293,8 +303,8 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
left: 0;
|
left: 0;
|
||||||
font-size: $search-icon-size;
|
width: $search-icon-size;
|
||||||
color: var(--slate-400);
|
fill: var(--slate-400);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,8 +347,11 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
|
|
||||||
.player-btn {
|
.player-btn {
|
||||||
margin-left: .25rem;
|
margin-left: .25rem;
|
||||||
font-size: 1.5em;
|
|
||||||
color: var(--red-500);
|
.icon {
|
||||||
|
font-size: 1.5em;
|
||||||
|
fill: var(--red-500);
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
&::before {
|
&::before {
|
||||||
@@ -362,10 +375,14 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-results {
|
.search-results {
|
||||||
max-height: 50vh;
|
max-height: 20vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scrollbar-gutter: stable;
|
scrollbar-gutter: stable;
|
||||||
|
|
||||||
|
@media screen and (width >= 900px) {
|
||||||
|
max-height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
&::-webkit-scrollbar,
|
&::-webkit-scrollbar,
|
||||||
&::-webkit-scrollbar-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
width: 26px;
|
width: 26px;
|
||||||
@@ -429,7 +446,7 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
right: .75rem;
|
right: .75rem;
|
||||||
color: var(--slate-400);
|
fill: var(--slate-400);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
@@ -457,6 +474,12 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.group-custom {
|
||||||
|
.title {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -467,6 +490,9 @@ function emitDeleteCustomMarker(markerTitle: string) {
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
right: .25em;
|
right: .25em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .3rem;
|
||||||
transition-property: visibility, opacity;
|
transition-property: visibility, opacity;
|
||||||
transition-duration: .2s;
|
transition-duration: .2s;
|
||||||
transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||||
|
|||||||
@@ -26,10 +26,9 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
'active': currentSearchMode === 'quests'
|
'active': currentSearchMode === 'quests'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span class="icon">
|
<svg v-if="currentSearchMode === 'quests'" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><polyline points="40 144 96 200 224 72" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||||
<i v-if="currentSearchMode === 'quests'" class="ph-bold ph-check"></i>
|
<svg v-else class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M231.22,59.44l-80,168a8,8,0,1,1-14.44-6.88L165.62,160H32a8,8,0,0,1-5.88-13.43l42.56-46.1L26.59,61.9A8,8,0,0,1,32,48H224a8,8,0,0,1,7.22,11.44Z"/></svg>
|
||||||
<i v-else class="ph-fill ph-flag-banner"></i>
|
|
||||||
</span>
|
|
||||||
<span class="label">
|
<span class="label">
|
||||||
Quêtes
|
Quêtes
|
||||||
</span>
|
</span>
|
||||||
@@ -44,10 +43,9 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
'active': currentSearchMode === 'capitals'
|
'active': currentSearchMode === 'capitals'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span class="icon">
|
<svg v-if="currentSearchMode === 'capitals'" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><polyline points="40 144 96 200 224 72" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||||
<i v-if="currentSearchMode === 'capitals'" class="ph-bold ph-check"></i>
|
<svg v-else class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M200,24h-8a16,16,0,0,0-16,16V56H148V40a16,16,0,0,0-16-16h-8a16,16,0,0,0-16,16V56H80V40A16,16,0,0,0,64,24H56A16,16,0,0,0,40,40V84.69A15.86,15.86,0,0,0,44.69,96L56,107.31V216a16,16,0,0,0,16,16H184a16,16,0,0,0,16-16V107.31L211.31,96A15.86,15.86,0,0,0,216,84.69V40A16,16,0,0,0,200,24ZM152,216H104V152a24,24,0,0,1,48,0Z"/></svg>
|
||||||
<i v-else class="ph-fill ph-castle-turret"></i>
|
|
||||||
</span>
|
|
||||||
<span class="label">
|
<span class="label">
|
||||||
Capitales
|
Capitales
|
||||||
</span>
|
</span>
|
||||||
@@ -62,10 +60,9 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
'active': currentSearchMode === 'landmarks'
|
'active': currentSearchMode === 'landmarks'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span class="icon">
|
<svg v-if="currentSearchMode === 'landmarks'" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><polyline points="40 144 96 200 224 72" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||||
<i v-if="currentSearchMode === 'landmarks'" class="ph-bold ph-check"></i>
|
<svg v-else class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M208,80a8,8,0,0,0-8,8v16H188.85L184,55.2A8,8,0,0,0,181.31,50h0L138.44,11.88l-.2-.17a16,16,0,0,0-20.48,0l-.2.17L74.68,50v0A7.93,7.93,0,0,0,72,55.2L67.15,104H56V88a8,8,0,0,0-16,0v24a8,8,0,0,0,8,8H65.54l-9.47,94.48A16,16,0,0,0,72,232H184a16,16,0,0,0,15.92-17.56L190.46,120H208a8,8,0,0,0,8-8V88A8,8,0,0,0,208,80ZM87.24,64h81.52l4,40H136V88a8,8,0,0,0-16,0v16H83.23ZM72,216l4.81-48H179.19L184,216Z"/></svg>
|
||||||
<i v-else class="ph-fill ph-lighthouse"></i>
|
|
||||||
</span>
|
|
||||||
<span class="label">
|
<span class="label">
|
||||||
Points d'intérêt
|
Points d'intérêt
|
||||||
</span>
|
</span>
|
||||||
@@ -80,10 +77,9 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
'active': currentSearchMode === 'custom'
|
'active': currentSearchMode === 'custom'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span class="icon">
|
<svg v-if="currentSearchMode === 'custom'" class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><polyline points="40 144 96 200 224 72" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/></svg>
|
||||||
<i v-if="currentSearchMode === 'custom'" class="ph-bold ph-check"></i>
|
<svg v-else xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M172,120a44,44,0,1,1-44-44A44.05,44.05,0,0,1,172,120Zm60,8A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88.09,88.09,0,0,0-91.47-87.93C77.43,41.89,39.87,81.12,40,128.25a87.65,87.65,0,0,0,22.24,58.16A79.71,79.71,0,0,1,84,165.1a4,4,0,0,1,4.83.32,59.83,59.83,0,0,0,78.28,0,4,4,0,0,1,4.83-.32,79.71,79.71,0,0,1,21.79,21.31A87.62,87.62,0,0,0,216,128Z"/></svg>
|
||||||
<i v-else class="ph-fill ph-user-circle"></i>
|
|
||||||
</span>
|
|
||||||
<span class="label">
|
<span class="label">
|
||||||
Personnels
|
Personnels
|
||||||
</span>
|
</span>
|
||||||
@@ -95,6 +91,7 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.tag-list {
|
.tag-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: .5rem;
|
gap: .5rem;
|
||||||
margin-top: .5rem;
|
margin-top: .5rem;
|
||||||
|
|
||||||
@@ -128,6 +125,7 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
border: 1px solid var(--slate-400);
|
border: 1px solid var(--slate-400);
|
||||||
border-radius: 100vmax;
|
border-radius: 100vmax;
|
||||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
||||||
|
white-space: nowrap;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
outline: .2rem solid transparent;
|
outline: .2rem solid transparent;
|
||||||
@@ -140,7 +138,7 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 1.1em;
|
width: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
@@ -155,12 +153,20 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
|||||||
color: var(--white);
|
color: var(--white);
|
||||||
background-color: var(--#{$c}-500);
|
background-color: var(--#{$c}-500);
|
||||||
border-color: var(--#{$c}-700);
|
border-color: var(--#{$c}-700);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--white);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.active) {
|
&:not(.active) {
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
color: var(--#{$c}-500);
|
color: var(--#{$c}-500);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--#{$c}-500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
src/env.d.ts
vendored
@@ -1 +1,2 @@
|
|||||||
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ const { title } = Astro.props;
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="author" content="Alexis Pelé" />
|
<meta name="author" content="Alexis Pelé" />
|
||||||
<meta name="description" content="Carte du monde connu de Léim, centrée sur l'Alliance Kaldélienne" />
|
<meta name="description" content="Carte du monde connu de Léim, centrée sur l'Alliance Kaldélienne" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width; initial-scale=1" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<title>{title} — Leim Wiki</title>
|
<title>{title} — Leim Wiki</title>
|
||||||
|
|
||||||
|
<link rel="canonical" href={Astro.url}>
|
||||||
|
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
@@ -24,16 +26,17 @@ const { title } = Astro.props;
|
|||||||
<meta name="msapplication-TileColor" content="#00aba9">
|
<meta name="msapplication-TileColor" content="#00aba9">
|
||||||
<meta name="theme-color" content="#a9d1eb">
|
<meta name="theme-color" content="#a9d1eb">
|
||||||
|
|
||||||
<link rel="stylesheet" href="phicons/bold/style.css" />
|
<meta property="og:title" content={title}/>
|
||||||
<link rel="stylesheet" href="phicons/fill/style.css" />
|
<meta property="og:type" content="map" />
|
||||||
<link rel="stylesheet" href="phicons/light/style.css" />
|
<meta property="og:url" content={Astro.url} />
|
||||||
|
<meta property="og:image" content="/bailey-zindel-NRQV-hBF10M-unsplash.jpg" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="leaflet/leaflet.css" rel="preload" />
|
<link rel="stylesheet" href="/leaflet/leaflet.css" rel="preload" />
|
||||||
<script is:inline src="leaflet/leaflet.js"></script>
|
<script is:inline src="/leaflet/leaflet.js"></script>
|
||||||
|
|
||||||
<script is:inline type="text/javascript" src="/js/leaflet-zoomify.min.js"></script>
|
<script is:inline type="text/javascript" src="/js/leaflet-zoomify.min.js"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="leaflet-measure/leaflet-measure.css" rel="preload" />
|
<link rel="stylesheet" href="/leaflet-measure/leaflet-measure.css" rel="preload" />
|
||||||
<script is:inline type="text/javascript" src="/js/leaflet-measure.min.js"></script>
|
<script is:inline type="text/javascript" src="/js/leaflet-measure.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export type MapMarkerGroup = "capitals" | "cities" | "towns" | "landmarks" | "quests" | "custom";
|
export type MapMarkerGroup = "capitals" | "cities" | "towns" | "landmarks" | "quests" | "custom";
|
||||||
|
export type MapMarkerIcon = "castle" | "flag" | "graduation-cap" | "location-pin" | "monument" | "push-pin"
|
||||||
|
|
||||||
export type MapCoords = {
|
export type MapCoords = {
|
||||||
x: number,
|
x: number,
|
||||||
@@ -11,6 +12,7 @@ export type MapMarker = {
|
|||||||
description?: string,
|
description?: string,
|
||||||
link?: string,
|
link?: string,
|
||||||
group?: MapMarkerGroup,
|
group?: MapMarkerGroup,
|
||||||
|
icon?: MapMarkerIcon,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PlayerMarker = {
|
export type PlayerMarker = {
|
||||||
|
|||||||