Files
Portfolio-Game/frontend/app/composables/useIntersectionObserver.ts
skycel e5eb9d0e78 Add journey timeline page with scroll animations (Story 2.8)
- Create useIntersectionObserver composable for scroll-triggered animations
- Add TimelineItem component with alternating layout (desktop)
- Implement journey page with i18n-based milestones data
- Add 7 career milestones (2018-2025) in FR and EN
- Gradient timeline line with animated connection points
- Glassmorphism card design with hover effects
- Respect prefers-reduced-motion for all animations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 11:14:32 +01:00

58 lines
1.2 KiB
TypeScript

export interface UseIntersectionObserverOptions {
threshold?: number
rootMargin?: string
once?: boolean
}
export function useIntersectionObserver(
target: Ref<HTMLElement | null>,
options: UseIntersectionObserverOptions = {}
) {
const { threshold = 0.1, rootMargin = '0px', once = true } = options
const isVisible = ref(false)
if (import.meta.client) {
let observer: IntersectionObserver | null = null
const cleanup = () => {
if (observer) {
observer.disconnect()
observer = null
}
}
watch(
target,
(el) => {
cleanup()
if (!el) return
observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
isVisible.value = true
if (once && observer) {
observer.unobserve(entry.target)
}
} else if (!once) {
isVisible.value = false
}
})
},
{ threshold, rootMargin }
)
observer.observe(el)
},
{ immediate: true }
)
onUnmounted(cleanup)
}
return { isVisible: readonly(isVisible) }
}