- PreviewArticle.vue : nouveau composant qui ecoute journal-item-click et s'insere entre Carte O et iframe AEP - EmbedDynamique.vue : retire le swap article (iframe AEP toujours visible en bas) - ColCentre.astro : passe en flex-col, preview ouverte = Carte O 33vh + Preview auto + iframe 67vh, overflow-y-auto sur le container - Bouton 'Retour a la carte' emet preview-close -> grid revient 1/3 + 2/3 - Scroll independant : Journal (gauche), Centre (preview), Insta (droite) - Drag-resize desactive quand preview ouverte (anti-collision)
71 lines
2.0 KiB
Vue
71 lines
2.0 KiB
Vue
<script setup lang="ts">
|
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
|
|
|
const iframeRef = ref<HTMLIFrameElement | null>(null)
|
|
const wrapperRef = ref<HTMLDivElement | null>(null)
|
|
const skeletonHidden = ref(false)
|
|
|
|
// Force rendu desktop de l'iframe AEP : viewport simulee 1440px + scale dynamique
|
|
const VIEWPORT_W = 1440
|
|
const iframeScale = ref(0.42)
|
|
let resizeObs: ResizeObserver | null = null
|
|
|
|
const updateScale = () => {
|
|
if (!wrapperRef.value) return
|
|
const w = wrapperRef.value.clientWidth
|
|
if (w > 0) iframeScale.value = w / VIEWPORT_W
|
|
}
|
|
|
|
const iframeStyle = computed(() => ({
|
|
width: VIEWPORT_W + 'px',
|
|
height: (100 / iframeScale.value) + '%',
|
|
transform: `scale(${iframeScale.value})`,
|
|
transformOrigin: '0 0',
|
|
}))
|
|
|
|
onMounted(() => {
|
|
if (wrapperRef.value && typeof ResizeObserver !== 'undefined') {
|
|
updateScale()
|
|
resizeObs = new ResizeObserver(updateScale)
|
|
resizeObs.observe(wrapperRef.value)
|
|
}
|
|
})
|
|
onUnmounted(() => {
|
|
resizeObs?.disconnect()
|
|
resizeObs = null
|
|
})
|
|
|
|
const onIframeLoad = () => {
|
|
if (iframeRef.value) {
|
|
iframeRef.value.classList.remove('opacity-0')
|
|
iframeRef.value.classList.add('opacity-100')
|
|
}
|
|
skeletonHidden.value = true
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="embed-dynamique h-full flex flex-col relative">
|
|
<div class="h-full">
|
|
<div ref="wrapperRef" class="relative h-full bg-neutral-100 overflow-hidden">
|
|
<div
|
|
v-if="!skeletonHidden"
|
|
id="embed-skeleton"
|
|
class="absolute inset-0 flex items-center justify-center bg-neutral-50 animate-pulse z-10"
|
|
>
|
|
<span class="text-neutral-400 text-sm">Chargement de la carte AEP...</span>
|
|
</div>
|
|
<iframe
|
|
src="https://aep.trans-former.fr/agences"
|
|
title="Carte AEP"
|
|
class="absolute top-0 left-0 border-0 opacity-0 transition-opacity duration-500"
|
|
:style="iframeStyle"
|
|
sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
|
|
@load="onIframeLoad"
|
|
ref="iframeRef"
|
|
></iframe>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|