This commit is contained in:
2026-03-31 14:03:41 +02:00
parent 399d78e508
commit d567fa3e02
14 changed files with 336 additions and 153 deletions

View File

@@ -7,32 +7,58 @@ import { cn } from "~/lib/utils";
const AnimateTextIn = ({
children,
animation = "type",
position,
position = 0,
tlId = undefined,
speed = 1,
scrollOnly = false,
className
}: {
children: ReactNode,
animation?: "type" | "slide",
position: gsap.Position,
className?:HTMLAttributes<HTMLDivElement>['className']
position?: gsap.Position,
tlId?: string,
scrollOnly?: boolean,
speed?: number,
className?: HTMLAttributes<HTMLDivElement>['className']
}) => {
const el = useRef<HTMLDivElement>(null)
const gsapContext = useGsapContext();
useGSAP(() => {
const rect = el.current?.getBoundingClientRect()
const isInView = rect && rect.top < window.innerHeight
const scroller = gsapContext?.getScroller()
console.log(scroller)
let viewportTop = 0
let viewportBottom = window.innerHeight
if (scroller && scroller instanceof Element) {
const scrollerRect = scroller.getBoundingClientRect()
viewportTop = scrollerRect.top
viewportBottom = scrollerRect.top + scrollerRect.height
}
const isInView = rect && rect.bottom > viewportTop && rect.top < viewportBottom
console.log(isInView)
const chars = new SplitText(el.current, { type: 'chars' })
gsapContext?.addAnimation(gsap.to(el.current, { opacity: 100, duration: 0 }), 0)
gsapContext?.addAnimation(gsap.to(el.current, { opacity: 100, duration: 0 }), 0, tlId)
const fromVars = animation === "slide"
? { opacity: 0, x: -10, duration: 0.2, stagger: { each: 0.08 }, ease: 'bounce.inOut', onComplete: () => chars.revert() }
: { opacity: 0, duration: 0.01, stagger: { each: 0.04 }, ease: 'bounce.inOut', onComplete: () => chars.revert() }
if (isInView) {
gsapContext?.addAnimation(gsap.from(chars.chars, fromVars), position)
? { opacity: 0, x: -10, duration: 0.2 * speed, stagger: { each: 0.08 * speed }, ease: 'bounce.inOut', onComplete: () => chars.revert() }
: { opacity: 0, duration: 0.01 * speed, stagger: { each: 0.04 * speed }, ease: 'bounce.inOut', onComplete: () => chars.revert() }
if (isInView && !scrollOnly) {
gsapContext?.addAnimation(gsap.from(chars.chars, fromVars), position, tlId)
} else {
gsap.from(chars.chars, { ...fromVars, scrollTrigger: { trigger: el.current, start: 'top 85%', scroller: gsapContext?.getScroller() } })
gsap.from(chars.chars,
{
...fromVars,
scrollTrigger: {
trigger: el.current,
start: 'top bottom',
end: 'bottom top',
toggleActions: "play reverse play reverse",
scroller
}
})
}
}, { dependencies: [] })
return (
<div ref={el} className={cn(className,"opacity-0")}>
<div ref={el} className={cn(className, "opacity-0")}>
{children}
</div>
)