Spaces:
Sleeping
Sleeping
File size: 2,286 Bytes
a7b8df9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
import { useEffect, useRef, useState } from 'react';
import { useInView } from 'framer-motion';
interface UseScrollAnimationOptions {
threshold?: number;
rootMargin?: string;
triggerOnce?: boolean;
delay?: number;
}
export const useScrollAnimation = (options: UseScrollAnimationOptions = {}) => {
const ref = useRef(null);
const isInView = useInView(ref, {
threshold: options.threshold || 0.1,
margin: options.rootMargin || '-100px 0px',
once: options.triggerOnce !== false,
});
const [hasAnimated, setHasAnimated] = useState(false);
useEffect(() => {
if (isInView && !hasAnimated) {
if (options.delay) {
setTimeout(() => setHasAnimated(true), options.delay);
} else {
setHasAnimated(true);
}
}
}, [isInView, hasAnimated, options.delay]);
return {
ref,
inView: isInView,
hasAnimated: hasAnimated || isInView,
};
};
export const useStaggeredAnimation = (itemCount: number, delay: number = 100) => {
const [visibleItems, setVisibleItems] = useState<number[]>([]);
const { ref, inView } = useScrollAnimation();
useEffect(() => {
if (inView) {
const timeouts: NodeJS.Timeout[] = [];
for (let i = 0; i < itemCount; i++) {
const timeout = setTimeout(() => {
setVisibleItems(prev => [...prev, i]);
}, i * delay);
timeouts.push(timeout);
}
return () => {
timeouts.forEach(timeout => clearTimeout(timeout));
};
}
}, [inView, itemCount, delay]);
return {
ref,
visibleItems,
inView,
};
};
// Hook for parallax effects
export const useParallax = (speed: number = 0.5) => {
const [offset, setOffset] = useState(0);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleScroll = () => {
if (ref.current) {
const rect = ref.current.getBoundingClientRect();
const scrolled = window.pageYOffset;
const rate = scrolled * speed;
setOffset(rate);
}
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [speed]);
return {
ref,
offset,
};
}; |