Initial commit of project structure

This commit is contained in:
Timo Knuth
2026-01-13 08:13:48 +01:00
commit be7f7b7bf7
47 changed files with 4455 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
import { useEffect, useRef, RefObject } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
interface ScrollAnimationOptions {
trigger?: RefObject<HTMLElement>;
start?: string;
end?: string;
scrub?: boolean | number;
markers?: boolean;
}
export const useScrollFadeIn = (
ref: RefObject<HTMLElement>,
options: ScrollAnimationOptions = {}
) => {
useEffect(() => {
const element = ref.current;
if (!element) return;
gsap.fromTo(
element,
{ opacity: 0, y: 60 },
{
opacity: 1,
y: 0,
duration: 1,
ease: 'power3.out',
scrollTrigger: {
trigger: options.trigger?.current || element,
start: options.start || 'top 85%',
end: options.end || 'top 20%',
toggleActions: 'play none none reverse',
},
}
);
return () => {
ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
};
}, [ref, options]);
};
export const useParallax = (
ref: RefObject<HTMLElement>,
speed: number = 0.5
) => {
useEffect(() => {
const element = ref.current;
if (!element) return;
gsap.to(element, {
yPercent: -50 * speed,
ease: 'none',
scrollTrigger: {
trigger: element,
start: 'top bottom',
end: 'bottom top',
scrub: true,
},
});
return () => {
ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
};
}, [ref, speed]);
};
export const useStaggerReveal = (
containerRef: RefObject<HTMLElement>,
childSelector: string,
options: ScrollAnimationOptions = {}
) => {
useEffect(() => {
const container = containerRef.current;
if (!container) return;
const children = container.querySelectorAll(childSelector);
gsap.fromTo(
children,
{ opacity: 0, y: 40 },
{
opacity: 1,
y: 0,
duration: 0.8,
stagger: 0.15,
ease: 'power2.out',
scrollTrigger: {
trigger: container,
start: options.start || 'top 80%',
toggleActions: 'play none none reverse',
},
}
);
return () => {
ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
};
}, [containerRef, childSelector, options]);
};