diff --git a/src/components/layout/Footer.svelte b/src/components/layout/Footer.svelte index 393cc8d..da65db1 100644 --- a/src/components/layout/Footer.svelte +++ b/src/components/layout/Footer.svelte @@ -111,6 +111,11 @@ z-index: 2; transition: transform .3s var(--ease-standard); + pointer-events: none; + } + + footer p, footer, a { + pointer-events: all; } :global(footer:not([data-template="white-paper"] footer)) { diff --git a/src/views/Expertise.svelte b/src/views/Expertise.svelte index 23772be..8cee967 100644 --- a/src/views/Expertise.svelte +++ b/src/views/Expertise.svelte @@ -6,14 +6,17 @@ let { data } = $props() // --- DOM refs --- - let videoFwd = $state(null) - let videoRev = $state(null) - let sectionEl = $state(null) + let videoFwd = $state(null) + let videoRev = $state(null) + let sectionEl = $state(null) + let textContainer = $state(null) + let itemEls = $state([]) // --- State --- let isReverse = $state(false) let duration = $state(0) let currentItem = $state(0) + let offsetY = $state(0) // --- Non-reactive --- let playhead = 0 // forward-equivalent position, updated from timeupdate @@ -39,6 +42,14 @@ } }) + function computeOffset() { + if (!textContainer || !itemEls[currentItem]) return + const wh = window.innerHeight + const wrapperRect = textContainer.parentElement.getBoundingClientRect() + const el = itemEls[currentItem] + offsetY = wh / 2 - wrapperRect.top - el.offsetTop - el.offsetHeight / 2 + } + function initVideo() { if (!videoFwd) return const start = () => { @@ -47,6 +58,7 @@ playhead = 0 isReverse = false if (videoRev) videoRev.currentTime = duration + requestAnimationFrame(() => computeOffset()) // Force first-frame decode (required on mobile Safari) videoFwd.play().then(() => videoFwd.pause()).catch(() => {}) } @@ -61,6 +73,7 @@ playhead = 0 isReverse = false currentItem = 0 + offsetY = 0 if (videoFwd) { videoFwd.pause(); videoFwd.currentTime = 0 } if (videoRev) { videoRev.pause() } } @@ -126,6 +139,7 @@ clearTimeout(lockTimer) lockTimer = setTimeout(() => { canScroll = true }, 650) + requestAnimationFrame(() => { if (isActive) computeOffset() }) dir === 'down' ? playForward() : playReverse() } @@ -174,12 +188,17 @@ if (e.key === 'ArrowDown') { e.preventDefault(); navigate('down') } if (e.key === 'ArrowUp') { e.preventDefault(); navigate('up') } } + const onResize = () => { if (isActive) computeOffset() } + window.addEventListener('resize', onResize) + window.addEventListener('orientationchange', onResize) window.addEventListener('keydown', onKeyDown) return () => { sectionEl?.removeEventListener('wheel', onWheel) sectionEl?.removeEventListener('touchstart', onTouchStart) sectionEl?.removeEventListener('touchend', onTouchEnd) + window.removeEventListener('resize', onResize) + window.removeEventListener('orientationchange', onResize) window.removeEventListener('keydown', onKeyDown) videoFwd?.removeEventListener('timeupdate', onFwdTime) videoRev?.removeEventListener('timeupdate', onRevTime) @@ -224,9 +243,13 @@