portfolio/src/hooks/useScrollReveal.ts
Cursor Agent 2e76528ac0
Port portfolio from Next.js/React to SolidJS with Vite
Replace Next.js App Router with Vite, solid-js, and @solidjs/router.
Convert all components, sections, hooks, and pages to SolidJS patterns
(signals, onMount, For, A). Swap lucide-react for lucide-solid and add
client-side routing with Vercel SPA rewrites.

Co-authored-by: Mike Karl <karl.mike2002@gmail.com>
2026-06-15 23:52:28 +00:00

66 lines
1.2 KiB
TypeScript

import { onMount } from "solid-js";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
interface ScrollRevealOptions {
y?: number;
x?: number;
duration?: number;
delay?: number;
stagger?: number;
start?: string;
ease?: string;
}
export function useScrollReveal<T extends HTMLElement>(
options: ScrollRevealOptions = {}
) {
let ref: T | undefined;
onMount(() => {
const el = ref;
if (!el) return;
const {
y = 40,
x = 0,
duration = 0.8,
delay = 0,
stagger = 0.1,
start = "top 85%",
ease = "power3.out",
} = options;
const children = el.children.length > 0 ? el.children : [el];
gsap.set(children, { opacity: 0, y, x });
const tween = gsap.to(children, {
opacity: 1,
y: 0,
x: 0,
duration,
delay,
stagger,
ease,
scrollTrigger: {
trigger: el,
start,
toggleActions: "play none none none",
},
});
return () => {
tween.kill();
ScrollTrigger.getAll().forEach((st) => {
if (st.trigger === el) st.kill();
});
};
});
return (el: T) => {
ref = el;
};
}