MVp
This commit is contained in:
61
components/ParallaxLayer.tsx
Normal file
61
components/ParallaxLayer.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
'use client'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { gsap } from 'gsap'
|
||||
import { ScrollTrigger } from 'gsap/ScrollTrigger'
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
gsap.registerPlugin(ScrollTrigger)
|
||||
}
|
||||
|
||||
interface ParallaxLayerProps {
|
||||
depth?: number
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
speed?: number
|
||||
}
|
||||
|
||||
export default function ParallaxLayer({
|
||||
depth = 1,
|
||||
children,
|
||||
className = '',
|
||||
speed = 0.5
|
||||
}: ParallaxLayerProps) {
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const element = ref.current
|
||||
if (!element) return
|
||||
|
||||
// Check for reduced motion
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||
if (prefersReducedMotion) return
|
||||
|
||||
const yMovement = -100 * depth * speed
|
||||
|
||||
const tl = gsap.to(element, {
|
||||
yPercent: yMovement,
|
||||
ease: 'none',
|
||||
scrollTrigger: {
|
||||
trigger: element,
|
||||
start: 'top bottom',
|
||||
end: 'bottom top',
|
||||
scrub: true,
|
||||
invalidateOnRefresh: true
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
tl.kill()
|
||||
}
|
||||
}, [depth, speed])
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={`will-change-transform ${className}`}
|
||||
style={{ willChange: 'transform' }}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user