Zoom
vue
<template>
<MapBase :projection="projection">
<MapZoom @zoom="updateMarkerScale">
<MapSphere
fill="var(--vp-c-bg-alt)"
stroke="var(--vp-c-border)"
>
<MapGraticule />
<MapFeatures :data="data" />
<MapMesh :data="data" />
<MapMarker
v-for="(item, index) in cities"
:key="index"
:coordinates="[item.lon, item.lat]"
>
<g :transform="`scale(${markerScale})`">
<text
font-size="14"
y="-8"
text-anchor="middle"
>
{{ item.city }}
</text>
<circle
r="3"
/>
</g>
</MapMarker>
</MapSphere>
</MapZoom>
</MapBase>
</template>
<script setup lang="ts">
import type { ZoomEvent } from '@d3-maps/vue'
import { geoNaturalEarth1 } from 'd3-geo'
import { ref } from 'vue'
interface City {
city: string
lon: number
lat: number
}
const initialCities: City[] = [
{ city: 'Minsk', lon: 27.34, lat: 53.54 },
{ city: 'Dili', lon: 125.36, lat: -8.35 },
{ city: 'Dushanbe', lon: 68.48, lat: 38.35 },
{ city: 'Guatemala City', lon: -90.31, lat: 14.37 },
{ city: 'Njamena', lon: 12.1348, lat: 15.0557 },
{ city: 'Tokyo', lon: 139.45, lat: 35.41 },
{ city: 'Georgetown', lon: -58.1, lat: 6.48 },
]
const { default: data } = await import('@d3-maps/atlas/world/countries/countries-110m')
const projection = geoNaturalEarth1
const cities = ref<City[]>(initialCities)
const markerScale = ref(1)
const currentZoom = ref(1)
function updateMarkerScale(e: ZoomEvent) {
if (currentZoom.value === e.transform.k) return
currentZoom.value = e.transform.k
markerScale.value = 1 / e.transform.k
}
</script>