Skip to content

Commit 551dae2

Browse files
committed
Sync new features to all variants (JS + CSS/TW, TS + CSS/TW). Added ...props and custom className
1 parent 2a080f9 commit 551dae2

File tree

4 files changed

+223
-81
lines changed

4 files changed

+223
-81
lines changed

src/content/Animations/AnimatedContent/AnimatedContent.jsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ const AnimatedContent = ({
2121
disappearDuration = 0.5,
2222
disappearEase = 'power3.in',
2323
onComplete,
24-
onDisappearanceComplete
24+
onDisappearanceComplete,
25+
className = '',
26+
...props
2527
}) => {
2628
const ref = useRef(null);
2729

@@ -93,7 +95,16 @@ const AnimatedContent = ({
9395
disappearEase, onComplete, onDisappearanceComplete
9496
]);
9597

96-
return <div ref={ref} style={{ visibility: 'hidden' }}>{children}</div>;
98+
return (
99+
<div
100+
ref={ref}
101+
className={className}
102+
style={{ visibility: 'hidden' }}
103+
{...props}
104+
>
105+
{children}
106+
</div>
107+
);
97108
};
98109

99110
export default AnimatedContent;

src/tailwind/Animations/AnimatedContent/AnimatedContent.jsx

Lines changed: 62 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,93 @@ 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,
25+
className = '',
26+
...props
2027
}) => {
2128
const ref = useRef(null);
2229

2330
useEffect(() => {
2431
const el = ref.current;
2532
if (!el) return;
2633

34+
let scrollerTarget = container || document.getElementById('snap-main-container') || null;
35+
36+
if (typeof scrollerTarget === 'string') {
37+
scrollerTarget = document.querySelector(scrollerTarget);
38+
}
39+
2740
const axis = direction === 'horizontal' ? 'x' : 'y';
2841
const offset = reverse ? -distance : distance;
2942
const startPct = (1 - threshold) * 100;
3043

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

37-
gsap.to(el, {
70+
tl.to(el, {
3871
[axis]: 0,
3972
scale: 1,
4073
opacity: 1,
4174
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-
}
75+
ease
76+
});
77+
78+
const st = ScrollTrigger.create({
79+
trigger: el,
80+
scroller: scrollerTarget,
81+
start: `top ${startPct}%`,
82+
once: true,
83+
onEnter: () => tl.play()
5184
});
5285

5386
return () => {
54-
ScrollTrigger.getAll().forEach(t => t.kill());
55-
gsap.killTweensOf(el);
87+
st.kill();
88+
tl.kill();
5689
};
5790
}, [
58-
distance,
59-
direction,
60-
reverse,
61-
duration,
62-
ease,
63-
initialOpacity,
64-
animateOpacity,
65-
scale,
66-
threshold,
67-
delay,
68-
onComplete
91+
container,
92+
distance, direction, reverse, duration, ease,
93+
initialOpacity, animateOpacity, scale, threshold,
94+
delay, disappearAfter, disappearDuration,
95+
disappearEase, onComplete, onDisappearanceComplete
6996
]);
7097

71-
return <div ref={ref}>{children}</div>;
98+
return (
99+
<div
100+
ref={ref}
101+
className={`invisible ${className}`}
102+
{...props}
103+
>
104+
{children}
105+
</div>
106+
);
72107
};
73108

74-
export default AnimatedContent;
109+
export default AnimatedContent;
Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
1-
import React, { useRef, useEffect, ReactNode } from 'react';
1+
import React, { useRef, useEffect } from 'react';
22
import { gsap } from 'gsap';
33
import { ScrollTrigger } from 'gsap/ScrollTrigger';
44

55
gsap.registerPlugin(ScrollTrigger);
66

7-
interface AnimatedContentProps {
8-
children: ReactNode;
7+
interface AnimatedContentProps extends React.HTMLAttributes<HTMLDivElement> {
8+
children: React.ReactNode;
9+
container?: Element | string | null;
910
distance?: number;
1011
direction?: 'vertical' | 'horizontal';
1112
reverse?: boolean;
1213
duration?: number;
13-
ease?: string | ((progress: number) => number);
14+
ease?: string;
1415
initialOpacity?: number;
1516
animateOpacity?: boolean;
1617
scale?: number;
1718
threshold?: number;
1819
delay?: number;
20+
disappearAfter?: number;
21+
disappearDuration?: number;
22+
disappearEase?: string;
1923
onComplete?: () => void;
24+
onDisappearanceComplete?: () => void;
2025
}
2126

2227
const AnimatedContent: React.FC<AnimatedContentProps> = ({
2328
children,
29+
container,
2430
distance = 100,
2531
direction = 'vertical',
2632
reverse = false,
@@ -31,45 +37,81 @@ const AnimatedContent: React.FC<AnimatedContentProps> = ({
3137
scale = 1,
3238
threshold = 0.1,
3339
delay = 0,
34-
onComplete
40+
disappearAfter = 0,
41+
disappearDuration = 0.5,
42+
disappearEase = 'power3.in',
43+
onComplete,
44+
onDisappearanceComplete,
45+
className = '',
46+
style,
47+
...props
3548
}) => {
3649
const ref = useRef<HTMLDivElement>(null);
3750

3851
useEffect(() => {
3952
const el = ref.current;
4053
if (!el) return;
4154

55+
let scrollerTarget: Element | string | null =
56+
container || document.getElementById('snap-main-container') || null;
57+
58+
if (typeof scrollerTarget === 'string') {
59+
scrollerTarget = document.querySelector(scrollerTarget);
60+
}
61+
4262
const axis = direction === 'horizontal' ? 'x' : 'y';
4363
const offset = reverse ? -distance : distance;
4464
const startPct = (1 - threshold) * 100;
4565

4666
gsap.set(el, {
4767
[axis]: offset,
4868
scale,
49-
opacity: animateOpacity ? initialOpacity : 1
69+
opacity: animateOpacity ? initialOpacity : 1,
70+
visibility: 'visible'
71+
});
72+
73+
const tl = gsap.timeline({
74+
paused: true,
75+
delay,
76+
onComplete: () => {
77+
if (onComplete) onComplete();
78+
79+
if (disappearAfter > 0) {
80+
gsap.to(el, {
81+
[axis]: reverse ? distance : -distance,
82+
scale: 0.8,
83+
opacity: animateOpacity ? initialOpacity : 0,
84+
delay: disappearAfter,
85+
duration: disappearDuration,
86+
ease: disappearEase,
87+
onComplete: () => onDisappearanceComplete?.()
88+
});
89+
}
90+
}
5091
});
5192

52-
gsap.to(el, {
93+
tl.to(el, {
5394
[axis]: 0,
5495
scale: 1,
5596
opacity: 1,
5697
duration,
57-
ease,
58-
delay,
59-
onComplete,
60-
scrollTrigger: {
61-
trigger: el,
62-
start: `top ${startPct}%`,
63-
toggleActions: 'play none none none',
64-
once: true
65-
}
98+
ease
99+
});
100+
101+
const st = ScrollTrigger.create({
102+
trigger: el,
103+
scroller: scrollerTarget || window,
104+
start: `top ${startPct}%`,
105+
once: true,
106+
onEnter: () => tl.play()
66107
});
67108

68109
return () => {
69-
ScrollTrigger.getAll().forEach(t => t.kill());
70-
gsap.killTweensOf(el);
110+
st.kill();
111+
tl.kill();
71112
};
72113
}, [
114+
container,
73115
distance,
74116
direction,
75117
reverse,
@@ -80,10 +122,23 @@ const AnimatedContent: React.FC<AnimatedContentProps> = ({
80122
scale,
81123
threshold,
82124
delay,
83-
onComplete
125+
disappearAfter,
126+
disappearDuration,
127+
disappearEase,
128+
onComplete,
129+
onDisappearanceComplete
84130
]);
85131

86-
return <div ref={ref}>{children}</div>;
132+
return (
133+
<div
134+
ref={ref}
135+
className={className}
136+
style={{ visibility: 'hidden', ...style }}
137+
{...props}
138+
>
139+
{children}
140+
</div>
141+
);
87142
};
88143

89-
export default AnimatedContent;
144+
export default AnimatedContent;

0 commit comments

Comments
 (0)