Skip to content

Commit 008af1b

Browse files
Lisofffaalsakhaev
authored andcommitted
fix: update animation
1 parent cb2c864 commit 008af1b

File tree

4 files changed

+63
-139
lines changed

4 files changed

+63
-139
lines changed

website/src/components/Header/index.tsx

Lines changed: 40 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,89 +37,77 @@ export const Header: FC<HeaderProps> = ({ setModalOpen }) => {
3737
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark');
3838
};
3939

40-
useEffect(() => {
41-
if (typeof window === 'undefined' || window.innerWidth < 1024 || !headerRef.current) return;
40+
useEffect(() => {
41+
if (typeof window === 'undefined' || window.innerWidth < 1024 || !headerRef.current) return;
4242

43-
const logo = headerRef.current.querySelector(`.${styles.logoLink}`);
44-
const navLinks = Array.from(headerRef.current.querySelectorAll(`.${styles.navLinks} a`));
45-
const themeSwitcher = headerRef.current.querySelector(`.${styles.themeSwitcher}`);
46-
const button = headerRef.current.querySelector(`.${styles.mvmButton}`);
43+
const logo = headerRef.current.querySelector(`.${styles.logoLink}`);
44+
const navLinks = Array.from(headerRef.current.querySelectorAll(`.${styles.navLinks} a`));
45+
const themeSwitcher = headerRef.current.querySelector(`.${styles.themeSwitcher}`);
46+
const button = headerRef.current.querySelector(`.${styles.mvmButton}`);
4747

48-
const animatableElements: gsap.TweenTarget[] = [];
49-
50-
if (logo) animatableElements.push(logo);
51-
animatableElements.push(...navLinks);
52-
if (themeSwitcher) animatableElements.push(themeSwitcher);
53-
if (button) animatableElements.push(button);
48+
gsap.set([logo, ...navLinks, themeSwitcher, button], {
49+
opacity: 0,
50+
y: 20
51+
});
5452

55-
timelineRef.current = gsap.timeline()
56-
.fromTo(logo,
57-
{ opacity: 0, x: -30 },
58-
{ opacity: 1, x: 0, duration: 0.6, ease: 'power3.out' }
59-
)
60-
.fromTo(navLinks,
61-
{ opacity: 0, y: 15 },
62-
{
53+
timelineRef.current = gsap.timeline()
54+
.to(logo, {
6355
opacity: 1,
6456
y: 0,
65-
duration: 0.5,
57+
duration: 0.6,
58+
ease: 'power2.in'
59+
})
60+
.to(navLinks, {
61+
opacity: 1,
62+
y: 0,
63+
duration: 0.5,
6664
stagger: 0.1,
67-
ease: 'back.out(1.2)'
68-
},
69-
'-=0.4'
70-
);
71-
72-
if (themeSwitcher && button) {
73-
timelineRef.current
74-
.fromTo([themeSwitcher, button],
75-
{ opacity: 0, scale: 0.8 },
76-
{
77-
opacity: 1,
78-
scale: 1,
79-
duration: 0.4,
80-
stagger: 0.1,
81-
ease: 'elastic.out(1, 0.5)'
82-
},
83-
'-=0.3'
84-
);
85-
}
65+
ease: 'power2.in'
66+
}, '-=0.4')
67+
.to([themeSwitcher, button], {
68+
opacity: 1,
69+
y: 0,
70+
duration: 0.4,
71+
stagger: 0.1,
72+
ease: 'power2.in'
73+
}, '-=0.3');
8674

87-
return () => {
88-
timelineRef.current?.kill();
89-
};
90-
}, []);
75+
return () => {
76+
timelineRef.current?.kill();
77+
};
78+
}, []);
9179

9280
useEffect(() => {
9381
if (typeof window === 'undefined' || !mobileMenuRef.current) return;
9482

9583
if (isMobileMenu) {
9684
gsap.fromTo(mobileMenuRef.current,
97-
{ opacity: 0, y: -20 },
85+
{ opacity: 0, y: -50 },
9886
{
9987
opacity: 1,
10088
y: 0,
101-
duration: 0.3,
102-
ease: 'power2.out'
89+
duration: 0.4,
90+
ease: 'power2.in'
10391
}
10492
);
10593

10694
gsap.fromTo(mobileMenuRef.current.querySelectorAll('a'),
107-
{ opacity: 0, y: 10 },
95+
{ opacity: 0, y: 20 },
10896
{
10997
opacity: 1,
11098
y: 0,
111-
duration: 0.4,
99+
duration: 0.5,
112100
stagger: 0.08,
113-
ease: 'back.out(1.2)',
101+
ease: 'power2.in',
114102
delay: 0.2
115103
}
116104
);
117105
} else {
118106
gsap.to(mobileMenuRef.current,
119107
{
120108
opacity: 0,
121-
y: -20,
122-
duration: 0.2,
109+
y: -50,
110+
duration: 0.3,
123111
ease: 'power2.in'
124112
}
125113
);

website/src/components/HomePage/ExamplesSection.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const ExamplesSection = () => {
1515

1616
const addToItemsRef = (el: HTMLElement | null, index: number) => {
1717
if (el) {
18-
gsap.set(el, { opacity: 0 });
18+
gsap.set(el, { opacity: 0, y: 100 });
1919
itemsRef.current[index] = el;
2020
}
2121
};
@@ -33,17 +33,15 @@ const ExamplesSection = () => {
3333
(entries) => {
3434
entries.forEach((entry) => {
3535
if (entry.isIntersecting && !animationTriggered.current) {
36-
gsap.set(items[0], { x: -100 });
37-
gsap.set(items[1], { y: 100 });
38-
gsap.set(items[2], { x: 100 });
39-
4036
const tl = gsap.timeline({
41-
defaults: { duration: 0.8, ease: 'power2.in' }
37+
defaults: { duration: 0.8, ease: 'power2.out' }
38+
});
39+
tl.to(items, {
40+
y: 0,
41+
opacity: 1,
42+
stagger: 0.15,
43+
ease: 'power2.out'
4244
});
43-
44-
tl.to(items[0], { x: 0, opacity: 1, delay: 0.1 })
45-
.to(items[1], { y: 0, opacity: 1 }, '-=0.6')
46-
.to(items[2], { x: 0, opacity: 1 }, '-=0.6');
4745

4846
animationTriggered.current = true;
4947
observer.unobserve(entry.target);

website/src/components/HomePage/FeaturesSection.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
transition: all 0.2s ease;
135135
text-decoration: none;
136136
color: inherit;
137-
opacity: 0;
137+
138138

139139
&:hover {
140140
background: radial-gradient(

website/src/components/HomePage/FeaturesSection.tsx

Lines changed: 14 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,6 @@ const FeaturesSection = () => {
3434
const FeatureLink = () => {
3535
const linkRef = useRef<HTMLAnchorElement>(null);
3636

37-
useEffect(() => {
38-
if (!linkRef.current) return;
39-
40-
gsap.fromTo(linkRef.current,
41-
{ x: 50, opacity: 0 },
42-
{
43-
x: 0,
44-
opacity: 1,
45-
duration: 0.8,
46-
delay: 0.3,
47-
ease: 'power2.in'
48-
}
49-
);
50-
}, []);
51-
5237
return (
5338
<Link
5439
ref={linkRef}
@@ -79,16 +64,25 @@ function FeatureBlock({
7964
index: number;
8065
}) {
8166
const blockRef = useRef<HTMLDivElement>(null);
67+
const imageRef = useRef<HTMLDivElement>(null);
8268
const isSecondFeature = index === 1;
8369

8470
useEffect(() => {
85-
if (!blockRef.current) return;
71+
if (!imageRef.current) return;
8672

8773
const observer = new IntersectionObserver(
8874
(entries) => {
8975
entries.forEach((entry) => {
9076
if (entry.isIntersecting) {
91-
animateBlock(entry.target);
77+
gsap.fromTo(imageRef.current,
78+
{ y: 100, opacity: 0 },
79+
{
80+
y: 0,
81+
opacity: 1,
82+
duration: 0.8,
83+
ease: 'power2.out'
84+
}
85+
);
9286
observer.unobserve(entry.target);
9387
}
9488
});
@@ -99,61 +93,13 @@ function FeatureBlock({
9993
}
10094
);
10195

102-
observer.observe(blockRef.current);
96+
observer.observe(imageRef.current);
10397

10498
return () => {
10599
observer.disconnect();
106100
};
107101
}, []);
108102

109-
const animateBlock = (block: Element) => {
110-
const image = block.querySelector(`.${styles.featureImageContainer}`);
111-
if (image) {
112-
gsap.fromTo(image,
113-
{ y: 100, opacity: 0 },
114-
{ y: 0, opacity: 1, duration: 0.8, ease: 'power2.in' }
115-
);
116-
}
117-
118-
const items = Array.from(block.querySelectorAll(`.${styles.featureItem}`));
119-
120-
items.forEach((item, itemIndex) => {
121-
let direction = {};
122-
switch(itemIndex % 4) {
123-
case 0: direction = { x: -100, y: -50 }; break;
124-
case 1: direction = { x: 100, y: -50 }; break;
125-
case 2: direction = { x: -100, y: 50 }; break;
126-
case 3: direction = { x: 100, y: 50 }; break;
127-
}
128-
129-
gsap.fromTo(item,
130-
{ ...direction, opacity: 0 },
131-
{
132-
x: 0,
133-
y: 0,
134-
opacity: 1,
135-
duration: 0.8,
136-
delay: 0.1 * itemIndex,
137-
ease: 'power2.in)'
138-
}
139-
);
140-
});
141-
142-
const idElement = block.querySelector(`.${styles.featureId}`);
143-
if (idElement) {
144-
gsap.fromTo(idElement,
145-
{ scale: 0.5, opacity: 0 },
146-
{
147-
scale: 1,
148-
opacity: 1,
149-
duration: 0.5,
150-
delay: 0.5,
151-
ease: 'power2.in'
152-
}
153-
);
154-
}
155-
};
156-
157103
return (
158104
<div
159105
ref={blockRef}
@@ -163,7 +109,7 @@ function FeatureBlock({
163109
>
164110
{!isSecondFeature ? (
165111
<>
166-
<div className={styles.featureImageContainer}>
112+
<div ref={imageRef} className={styles.featureImageContainer}>
167113
<ThemeImage
168114
width={395}
169115
height={275}
@@ -191,7 +137,7 @@ function FeatureBlock({
191137
))}
192138
</div>
193139

194-
<div className={styles.featureImageContainer}>
140+
<div ref={imageRef} className={styles.featureImageContainer}>
195141
<ThemeImage
196142
width={395}
197143
height={275}
@@ -222,16 +168,8 @@ function FeatureItem({
222168
item: (typeof PlatformFeatures)[0]['features'][0];
223169
index: number;
224170
}) {
225-
const itemRef = useRef<HTMLAnchorElement>(null);
226-
227-
useEffect(() => {
228-
if (!itemRef.current) return;
229-
gsap.set(itemRef.current, { opacity: 0 });
230-
}, []);
231-
232171
return (
233172
<Link
234-
ref={itemRef}
235173
prefetch={false}
236174
target='_blank'
237175
href={item.link}

0 commit comments

Comments
 (0)