Skip to content

Commit 2a080f9

Browse files
committed
Scroll targeting, fix cleanup & add exit animations
- Replace global ScrollTrigger cleanup with instance-specific kill() to prevent side effects - Add `container` support for custom scroll proxies (CSS snap or locomotive-scroll) - Update animation logic from `gsap.to` to `gsap.timeline` - Implement disappear animation and speciefic props - Fix animation glitch by setting initial visibility to hidden
1 parent ea7b1b9 commit 2a080f9

File tree

1 file changed

+52
-27
lines changed

1 file changed

+52
-27
lines changed

src/content/Animations/AnimatedContent/AnimatedContent.jsx

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ gsap.registerPlugin(ScrollTrigger);
66

77
const AnimatedContent = ({
88
children,
9+
container,
910
distance = 100,
1011
direction = 'vertical',
1112
reverse = false,
@@ -16,59 +17,83 @@ const AnimatedContent = ({
1617
scale = 1,
1718
threshold = 0.1,
1819
delay = 0,
19-
onComplete
20+
disappearAfter = 0,
21+
disappearDuration = 0.5,
22+
disappearEase = 'power3.in',
23+
onComplete,
24+
onDisappearanceComplete
2025
}) => {
2126
const ref = useRef(null);
2227

2328
useEffect(() => {
2429
const el = ref.current;
2530
if (!el) return;
2631

32+
let scrollerTarget = container || document.getElementById('snap-main-container') || null;
33+
34+
if (typeof scrollerTarget === 'string') {
35+
scrollerTarget = document.querySelector(scrollerTarget);
36+
}
37+
2738
const axis = direction === 'horizontal' ? 'x' : 'y';
2839
const offset = reverse ? -distance : distance;
2940
const startPct = (1 - threshold) * 100;
3041

3142
gsap.set(el, {
3243
[axis]: offset,
3344
scale,
34-
opacity: animateOpacity ? initialOpacity : 1
45+
opacity: animateOpacity ? initialOpacity : 1,
46+
visibility: 'visible'
47+
});
48+
49+
const tl = gsap.timeline({
50+
paused: true,
51+
delay,
52+
onComplete: () => {
53+
if (onComplete) onComplete();
54+
if (disappearAfter > 0) {
55+
gsap.to(el, {
56+
[axis]: reverse ? distance : -distance,
57+
scale: 0.8,
58+
opacity: animateOpacity ? initialOpacity : 0,
59+
delay: disappearAfter,
60+
duration: disappearDuration,
61+
ease: disappearEase,
62+
onComplete: () => onDisappearanceComplete?.()
63+
});
64+
}
65+
}
3566
});
3667

37-
gsap.to(el, {
68+
tl.to(el, {
3869
[axis]: 0,
3970
scale: 1,
4071
opacity: 1,
4172
duration,
42-
ease,
43-
delay,
44-
onComplete,
45-
scrollTrigger: {
46-
trigger: el,
47-
start: `top ${startPct}%`,
48-
toggleActions: 'play none none none',
49-
once: true
50-
}
73+
ease
74+
});
75+
76+
const st = ScrollTrigger.create({
77+
trigger: el,
78+
scroller: scrollerTarget,
79+
start: `top ${startPct}%`,
80+
once: true,
81+
onEnter: () => tl.play()
5182
});
5283

5384
return () => {
54-
ScrollTrigger.getAll().forEach(t => t.kill());
55-
gsap.killTweensOf(el);
85+
st.kill();
86+
tl.kill();
5687
};
5788
}, [
58-
distance,
59-
direction,
60-
reverse,
61-
duration,
62-
ease,
63-
initialOpacity,
64-
animateOpacity,
65-
scale,
66-
threshold,
67-
delay,
68-
onComplete
89+
container,
90+
distance, direction, reverse, duration, ease,
91+
initialOpacity, animateOpacity, scale, threshold,
92+
delay, disappearAfter, disappearDuration,
93+
disappearEase, onComplete, onDisappearanceComplete
6994
]);
7095

71-
return <div ref={ref}>{children}</div>;
96+
return <div ref={ref} style={{ visibility: 'hidden' }}>{children}</div>;
7297
};
7398

74-
export default AnimatedContent;
99+
export default AnimatedContent;

0 commit comments

Comments
 (0)