Add mapbox

This commit is contained in:
2024-07-24 17:58:43 +02:00
parent 67263e8071
commit e638d459b3
10 changed files with 1035 additions and 199 deletions

View File

@@ -20,4 +20,9 @@ NUXT_DISCORD_USER_ID=
NUXT_PUBLIC_CLOUD_RESUME= NUXT_PUBLIC_CLOUD_RESUME=
# Nuxt I18N # Nuxt I18N
NUXT_PUBLIC_I18N_BASE_URL= NUXT_PUBLIC_I18N_BASE_URL=
# Nuxt Mapbox
NUXT_PUBLIC_MAPBOX_LIGHT=
NUXT_PUBLIC_MAPBOX_STYLE_DARK=
NUXT_PUBLIC_MAPBOX_ACCESS_TOKEN=

View File

@@ -67,6 +67,11 @@ NUXT_PUBLIC_CLOUD_RESUME=...
# Nuxt I18N # Nuxt I18N
NUXT_PUBLIC_I18N_BASE_URL=... NUXT_PUBLIC_I18N_BASE_URL=...
# Nuxt Mapbox
NUXT_PUBLIC_MAPBOX_STYLE_LIGHT=...
NUXT_PUBLIC_MAPBOX_STYLE_DARK=...
NUXT_PUBLIC_MAPBOX_ACCESS_TOKEN=...
``` ```
## 📄 License ## 📄 License

View File

@@ -9,9 +9,13 @@ const { t } = useI18n({
<div class="flex items-center"> <div class="flex items-center">
<UTooltip text="It's me 👋"> <UTooltip text="It's me 👋">
<div class="flex items-center w-12 h-12"> <div class="flex items-center w-12 h-12">
<NuxtImg <UAvatar
alt="Arthur Danjou picture" alt="Avatar"
class="w-full h-full hover:rotate-[360deg] duration-500 transform-gpu" chip-color="gray"
chip-position="top-right"
chip-text="?"
class="hover:rotate-[360deg] duration-500 transform-gpu"
size="md"
src="/favicon.png" src="/favicon.png"
/> />
</div> </div>

View File

@@ -42,7 +42,9 @@ const { t } = useI18n({
{{ {{
stats.languages.data.slice(0, 2).map(language => `${language.name} (${language.percent}%)`).join(t('separator')) stats.languages.data.slice(0, 2).map(language => `${language.name} (${language.percent}%)`).join(t('separator'))
}} }}
{{ stats.languages.data.slice(0, 2).map(language => `${language.name} (${language.percent}%)`).join(t('separator')) }} {{
stats.languages.data.slice(0, 2).map(language => `${language.name} (${language.percent}%)`).join(t('separator'))
}}
</template> </template>
</i18n-t> </i18n-t>
</ClientOnly> </ClientOnly>
@@ -68,4 +70,3 @@ const { t } = useI18n({
} }
} }
</i18n> </i18n>

114
app/components/home/Map.vue Normal file
View File

@@ -0,0 +1,114 @@
<script lang="ts" setup>
const colorMode = useColorMode()
const isDark = computed(() => colorMode.value === 'dark')
const zoom = ref(11)
const coordinates = ref<[number, number]>([2.179040, 48.877419])
function adjustZoom(amount: number) {
const targetZoom = zoom.value + amount
const frameRate = 1000 / 60
const step = amount / 20
const interval = setInterval(() => {
if ((amount > 0 && zoom.value < targetZoom) || (amount < 0 && zoom.value > targetZoom)) {
zoom.value += step
}
else {
clearInterval(interval)
}
}, frameRate)
}
const { t } = useI18n({
useScope: 'local',
})
const config = useRuntimeConfig()
</script>
<template>
<div class="flex items-center justify-center mt-4 flex-col space-y-1">
<div class="relative h-80 md:h-96 w-full">
<MapboxMap
:options="{
accessToken: config.public.mapbox.accessToken,
style: isDark ? config.public.mapbox.style.dark : config.public.mapbox.style.light,
center: coordinates,
zoom,
projection: 'globe',
}"
class="relative z-10"
map-id="map"
>
<MapboxDefaultMarker
:lnglat="coordinates"
:options="{
color: '#808080',
size: 1.5,
}"
marker-id="marker"
/>
</MapboxMap>
<div
v-show="zoom < 15"
class="map-button left-2"
@click.prevent="adjustZoom(1)"
>
<UIcon
name="i-ph-plus-bold"
size="24"
/>
</div>
<div
v-show="zoom > 0"
class="map-button right-2"
@click.prevent="adjustZoom(-1)"
>
<UIcon
name="i-ph-minus-bold"
size="24"
/>
</div>
</div>
<div class="flex gap-3 items-center group">
<div class="flex items-center justify-center group-hover:animate-slide duration-300">
<UIcon
name="i-ph-hand-grabbing-duotone"
size="16"
/>
</div>
<p class="text-[12px] italic">
{{ t('caption') }}
</p>
</div>
</div>
</template>
<style lang="scss">
.map-button {
@apply z-30 absolute bottom-2 dark:bg-gray-800 dark:hover:bg-gray-900 bg-gray-200 hover:bg-gray-100 duration-300 border border-neutral-300 dark:border-neutral-700 cursor-pointer flex items-center justify-center rounded-full p-2
}
.mapboxgl-control-container {
display: none !important;
}
.mapboxgl-canvas {
border-radius: 1rem;
}
</style>
<i18n lang="json">
{
"en": {
"caption": "Where I live"
},
"fr": {
"caption": "Où j'habite"
},
"es": {
"caption": "Donde vivo"
}
}
</i18n>

View File

@@ -5,5 +5,6 @@ const { locale } = useI18n()
<template> <template>
<main class="!max-w-none prose dark:prose-invert"> <main class="!max-w-none prose dark:prose-invert">
<ContentDoc :path="`/home/${locale}`" /> <ContentDoc :path="`/home/${locale}`" />
<HomeMap />
</main> </main>
</template> </template>

View File

@@ -21,6 +21,7 @@ export default defineNuxtConfig({
'@nuxthq/studio', '@nuxthq/studio',
'@nuxt/image', '@nuxt/image',
'@nuxtjs/i18n', '@nuxtjs/i18n',
'nuxt-mapbox',
], ],
// Nuxt Hub // Nuxt Hub
@@ -105,6 +106,13 @@ export default defineNuxtConfig({
cloud: { cloud: {
resume: '', resume: '',
}, },
mapbox: {
accessToken: '',
style: {
light: '',
dark: '',
},
},
}, },
}, },

View File

@@ -35,6 +35,8 @@
"@vueuse/nuxt": "^10.11.0", "@vueuse/nuxt": "^10.11.0",
"drizzle-kit": "^0.22.8", "drizzle-kit": "^0.22.8",
"eslint": "^9.7.0", "eslint": "^9.7.0",
"mapbox-gl": "^3.5.2",
"nuxt-mapbox": "^1.6.0",
"typescript": "^5.5.4", "typescript": "^5.5.4",
"vue-tsc": "^2.0.28", "vue-tsc": "^2.0.28",
"wrangler": "^3.66.0" "wrangler": "^3.66.0"

1064
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,7 @@ export default <Partial<Config>>{
extend: { extend: {
animation: { animation: {
wave: 'wave 3s infinite', wave: 'wave 3s infinite',
slide: 'slide 3s infinite',
}, },
keyframes: { keyframes: {
wave: { wave: {
@@ -30,6 +31,23 @@ export default <Partial<Config>>{
transform: 'rotate(12deg) scale(1.5)', transform: 'rotate(12deg) scale(1.5)',
}, },
}, },
slide: {
'0%, 100%': {
transform: 'translateX(0) translateY(0)',
},
'20%': {
transform: 'translateX(10px)',
},
'40%': {
transform: 'translateY(-10px) translateX(10px)',
},
'60%': {
transform: 'translateY(10px) translateX(-10px)',
},
'80%': {
transform: 'translateY(-10px)',
},
},
}, },
}, },
}, },