✨ 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>
This commit is contained in:
57
frontend/app/composables/useIntersectionObserver.ts
Normal file
57
frontend/app/composables/useIntersectionObserver.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
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) }
|
||||
}
|
||||
Reference in New Issue
Block a user