mouvement et lock de la carte + prevent refresh homepage

This commit is contained in:
Valentin
2024-10-07 23:39:50 +02:00
parent 6dad6cc7bc
commit 80f7f43370
7 changed files with 225 additions and 96 deletions

View File

@@ -20,7 +20,8 @@
:couleur="etape.couleur || brandColor" />
<ModaleDiaporama
v-if="partie.type === 'diaporama'"
:partie="partie" />
:partie="partie"
:couleur="etape.couleur || brandColor" />
<ModaleEntretien
v-if="partie.type === 'entretien'"
:partie="partie"
@@ -36,7 +37,8 @@
</main>
<ModaleFooter
:content="etape || page"
:couleur="etape.couleur || brandColor" />
:couleur="etape.couleur || brandColor"
:map="map" />
</div>
</div>
</Transition>
@@ -46,6 +48,7 @@
import { computed, watch, onMounted } from 'vue';
import { storeToRefs } from 'pinia';
import { useContentStore } from '../stores/content';
import { useMapStore } from '../stores/mapState';
import { useRoute, useRouter } from 'vue-router';
import ModaleHeader from './components/ModaleHeader.vue';
@@ -64,13 +67,17 @@ const { isObjectEmpty, scrollTop } = useUtils();
const router = useRouter();
const store = useContentStore();
const mapState = useMapStore();
const route = useRoute();
const { loading, error, href, etape, page } = storeToRefs(store);
const { loading, error, href, map, etape, page } = storeToRefs(store);
const { duration } = storeToRefs(mapState);
const isEtapeValid = computed(() => !error.value && !loading.value && etape.value && !isObjectEmpty(etape.value));
const isPageValid = computed(() => !error.value && !loading.value && page.value && !isObjectEmpty(page.value));
let isModaleEtape, wasModaleEtape;
const brandColor = "#80c8bf";
let isProgrammaticNavigation = false;
@@ -78,18 +85,18 @@ let isProgrammaticNavigation = false;
const handleRouteChange = () => {
watch(
() => route.params.id,
(newId) => {
(newId) => {
if (isProgrammaticNavigation) {
isProgrammaticNavigation = false;
return;
}
if (!newId) {
store.emptyAll();
store.emptyAll(map.value);
} else {
store.fetchEtapeData(newId);
store.fetchEtapeData(newId, map.value);
if (!etape.value?.data) {
store.fetchStaticData(newId);
store.fetchStaticData(newId, map.value);
}
scrollTop();
}
@@ -112,36 +119,82 @@ const handleHrefChange = () => {
() => href.value,
(newHref) => {
const relativePath = newHref.split('.fr')[1];
if (relativePath && relativePath !== '' && relativePath !== '/') {
isProgrammaticNavigation = true;
router.push(relativePath);
scrollTop();
isProgrammaticNavigation = true;
if (newHref == '') {
router.push('/');
mapState.unlockMap(map.value)
} else {
if (relativePath && relativePath !== '' && relativePath !== '/') {
mapState.lockMap(map.value);
router.push(relativePath);
scrollTop();
}
}
}
);
};
const handleMapMovement = () => {
watch(
() => href.value,
() => {
console.log("NEW HREF");
console.log(href.value);
isModaleEtape = !isObjectEmpty(etape.value);
console.log("CAS 1", !wasModaleEtape && isModaleEtape);
console.log("CAS 2", wasModaleEtape && isModaleEtape);
console.log("CAS 3", wasModaleEtape && !isModaleEtape);
if (!wasModaleEtape && isModaleEtape) {
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value}s`);
mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
} else if (wasModaleEtape && isModaleEtape) {
document.documentElement.style.setProperty('--modale-leave-delay', 0);
document.documentElement.style.setProperty('--modale-enter-delay', `${duration.value * 2}s`);
mapState.resetMap(map.value);
setTimeout(() => {
mapState.zoomToPlace(map.value, etape.value.coordinates.lat, etape.value.coordinates.lon);
}, duration.value * 1000);
} else if (wasModaleEtape && !isModaleEtape) {
document.documentElement.style.setProperty('--modale-leave-delay', 0);
mapState.resetMap(map.value);
}
wasModaleEtape = isModaleEtape;
},
);
};
onMounted(() => {
isModaleEtape = !isObjectEmpty(etape.value);
wasModaleEtape = isModaleEtape;
handleRouteChange();
handleColorChange();
handleHrefChange();
handleMapMovement();
});
</script>
<style scss>
.v-enter-active,
.v-enter-active {
transition: all 0.5s linear var(--modale-enter-delay);
}
.v-leave-active {
transition: all 0.3s ease;
transition: all 0.5s linear var(--modale-leave-delay);
}
.v-enter-from,
.v-leave-to {
transform: translateY(100%);
opacity: 0;
transform: translateY(20vh);
}
.v-enter-to,
.v-leave-from {
transform: translateY(0%);
opacity: 1;
transform: translateY(0vh);
}
</style>

View File

@@ -5,7 +5,7 @@
</div>
<div v-if="content.previous || content.next" class="related-etape-links">
<div v-if="content.previous" class="card previous" @click="store.fetchEtapeData(content.previous.nid)">
<div v-if="content.previous" class="card previous" @click="store.fetchEtapeData(content.previous.nid, map)">
<div class="icon">
<div :style="{ backgroundColor: content.previous.couleur }"></div>
<div :style="{ backgroundColor: content.previous.couleur }"></div>
@@ -21,7 +21,7 @@
</div>
</div>
</div>
<div v-if="content.next" class="card next" @click="store.fetchEtapeData(content.next.nid)">
<div v-if="content.next" class="card next" @click="store.fetchEtapeData(content.next.nid, map)">
<div class="icon">
<div :style="{ backgroundColor: content.next.couleur }"></div>
<div :style="{ backgroundColor: content.next.couleur }"></div>
@@ -50,5 +50,6 @@ const store = useContentStore();
const props = defineProps({
content: Object,
couleur: String,
map: Object,
});
</script>

View File

@@ -26,6 +26,7 @@
</template>
<script setup>
import { onMounted } from 'vue';
import { useImageModal } from '../../composables/useImageModale';
import ImageModale from '../ImageModale.vue';
// WebComponent
@@ -34,7 +35,8 @@ import { register } from 'swiper/element/bundle';
register();
const props = defineProps({
partie: Object
partie: Object,
couleur: String,
});
const {
@@ -62,6 +64,10 @@ const handleImageClick = (event) => {
openImageModale(img.src, img.alt, swiperMedia);
}
};
onMounted(() => {
document.documentElement.style.setProperty('--etape-couleur', props.couleur);
});
</script>
<style>

View File

@@ -1,6 +1,12 @@
<template>
<div class="videos">
<iframe v-for="video in partie.videos" :src="video" frameborder="0" width="100%" style="aspect-ratio: 16 / 9;"></iframe>
<iframe
v-for="video in partie.videos"
:src="video"
frameborder="0"
width="100%"
style="aspect-ratio: 16 / 9;">
</iframe>
</div>
</template>