expertise : fix active text centering - related to #52
All checks were successful
Deploy / Deploy to Production (push) Successful in 28s
All checks were successful
Deploy / Deploy to Production (push) Successful in 28s
This commit is contained in:
parent
6e0b0bd551
commit
4b946d4cf0
2 changed files with 34 additions and 5 deletions
|
|
@ -111,6 +111,11 @@
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
transition: transform .3s var(--ease-standard);
|
transition: transform .3s var(--ease-standard);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer p, footer, a {
|
||||||
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(footer:not([data-template="white-paper"] footer)) {
|
:global(footer:not([data-template="white-paper"] footer)) {
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,17 @@
|
||||||
let { data } = $props()
|
let { data } = $props()
|
||||||
|
|
||||||
// --- DOM refs ---
|
// --- DOM refs ---
|
||||||
let videoFwd = $state(null)
|
let videoFwd = $state(null)
|
||||||
let videoRev = $state(null)
|
let videoRev = $state(null)
|
||||||
let sectionEl = $state(null)
|
let sectionEl = $state(null)
|
||||||
|
let textContainer = $state(null)
|
||||||
|
let itemEls = $state([])
|
||||||
|
|
||||||
// --- State ---
|
// --- State ---
|
||||||
let isReverse = $state(false)
|
let isReverse = $state(false)
|
||||||
let duration = $state(0)
|
let duration = $state(0)
|
||||||
let currentItem = $state(0)
|
let currentItem = $state(0)
|
||||||
|
let offsetY = $state(0)
|
||||||
|
|
||||||
// --- Non-reactive ---
|
// --- Non-reactive ---
|
||||||
let playhead = 0 // forward-equivalent position, updated from timeupdate
|
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() {
|
function initVideo() {
|
||||||
if (!videoFwd) return
|
if (!videoFwd) return
|
||||||
const start = () => {
|
const start = () => {
|
||||||
|
|
@ -47,6 +58,7 @@
|
||||||
playhead = 0
|
playhead = 0
|
||||||
isReverse = false
|
isReverse = false
|
||||||
if (videoRev) videoRev.currentTime = duration
|
if (videoRev) videoRev.currentTime = duration
|
||||||
|
requestAnimationFrame(() => computeOffset())
|
||||||
// Force first-frame decode (required on mobile Safari)
|
// Force first-frame decode (required on mobile Safari)
|
||||||
videoFwd.play().then(() => videoFwd.pause()).catch(() => {})
|
videoFwd.play().then(() => videoFwd.pause()).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
@ -61,6 +73,7 @@
|
||||||
playhead = 0
|
playhead = 0
|
||||||
isReverse = false
|
isReverse = false
|
||||||
currentItem = 0
|
currentItem = 0
|
||||||
|
offsetY = 0
|
||||||
if (videoFwd) { videoFwd.pause(); videoFwd.currentTime = 0 }
|
if (videoFwd) { videoFwd.pause(); videoFwd.currentTime = 0 }
|
||||||
if (videoRev) { videoRev.pause() }
|
if (videoRev) { videoRev.pause() }
|
||||||
}
|
}
|
||||||
|
|
@ -126,6 +139,7 @@
|
||||||
clearTimeout(lockTimer)
|
clearTimeout(lockTimer)
|
||||||
lockTimer = setTimeout(() => { canScroll = true }, 650)
|
lockTimer = setTimeout(() => { canScroll = true }, 650)
|
||||||
|
|
||||||
|
requestAnimationFrame(() => { if (isActive) computeOffset() })
|
||||||
dir === 'down' ? playForward() : playReverse()
|
dir === 'down' ? playForward() : playReverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,12 +188,17 @@
|
||||||
if (e.key === 'ArrowDown') { e.preventDefault(); navigate('down') }
|
if (e.key === 'ArrowDown') { e.preventDefault(); navigate('down') }
|
||||||
if (e.key === 'ArrowUp') { e.preventDefault(); navigate('up') }
|
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)
|
window.addEventListener('keydown', onKeyDown)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
sectionEl?.removeEventListener('wheel', onWheel)
|
sectionEl?.removeEventListener('wheel', onWheel)
|
||||||
sectionEl?.removeEventListener('touchstart', onTouchStart)
|
sectionEl?.removeEventListener('touchstart', onTouchStart)
|
||||||
sectionEl?.removeEventListener('touchend', onTouchEnd)
|
sectionEl?.removeEventListener('touchend', onTouchEnd)
|
||||||
|
window.removeEventListener('resize', onResize)
|
||||||
|
window.removeEventListener('orientationchange', onResize)
|
||||||
window.removeEventListener('keydown', onKeyDown)
|
window.removeEventListener('keydown', onKeyDown)
|
||||||
videoFwd?.removeEventListener('timeupdate', onFwdTime)
|
videoFwd?.removeEventListener('timeupdate', onFwdTime)
|
||||||
videoRev?.removeEventListener('timeupdate', onRevTime)
|
videoRev?.removeEventListener('timeupdate', onRevTime)
|
||||||
|
|
@ -224,9 +243,13 @@
|
||||||
|
|
||||||
<!-- Text items -->
|
<!-- Text items -->
|
||||||
<div class="expertise-text-wrapper" aria-live="polite" aria-atomic="true">
|
<div class="expertise-text-wrapper" aria-live="polite" aria-atomic="true">
|
||||||
<div class="expertise-text">
|
<div
|
||||||
|
class="expertise-text"
|
||||||
|
bind:this={textContainer}
|
||||||
|
style="transform: translateY({offsetY}px)"
|
||||||
|
>
|
||||||
{#each items as item, i}
|
{#each items as item, i}
|
||||||
<div class="expertise-item" class:active={i === currentItem}>
|
<div class="expertise-item" class:active={i === currentItem} bind:this={itemEls[i]}>
|
||||||
{@html item.text}
|
{@html item.text}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
@ -287,6 +310,7 @@
|
||||||
.expertise-text {
|
.expertise-text {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
transition: transform 0.6s var(--ease-standard);
|
||||||
}
|
}
|
||||||
|
|
||||||
.expertise-item {
|
.expertise-item {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue