mirror of
https://github.com/ArthurDanjou/artsite.git
synced 2026-01-14 15:54:13 +01:00
Add mapbox
This commit is contained in:
@@ -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=
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
114
app/components/home/Map.vue
Normal 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>
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -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
1064
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -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)',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user