Skip to content

Commit 4825d65

Browse files
feat: animations added (#80)
Closes #79
1 parent 49eca5f commit 4825d65

File tree

1 file changed

+74
-0
lines changed
  • src/quant_research_starter/frontend/cauweb/src/utils

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Scroll animation observer
2+
export const initScrollAnimations = (): void => {
3+
if (typeof window === 'undefined') return;
4+
5+
const observer = new IntersectionObserver((entries) => {
6+
entries.forEach(entry => {
7+
if (entry.isIntersecting) {
8+
entry.target.classList.add('is-visible');
9+
}
10+
});
11+
}, { threshold: 0.1 });
12+
13+
const fadeElements = document.querySelectorAll('.fade-in-section');
14+
fadeElements.forEach((el) => {
15+
observer.observe(el);
16+
});
17+
};
18+
19+
// Parallax effect
20+
export const initParallax = (): void => {
21+
if (typeof window === 'undefined') return;
22+
23+
const handleScroll = (): void => {
24+
const scrolled = window.pageYOffset;
25+
const parallaxElements = document.querySelectorAll('[data-parallax]');
26+
27+
parallaxElements.forEach((el) => {
28+
const speed = parseFloat(el.getAttribute('data-parallax-speed') || '0.5');
29+
(el as HTMLElement).style.transform = `translateY(${scrolled * speed}px)`;
30+
});
31+
};
32+
33+
window.addEventListener('scroll', handleScroll);
34+
};
35+
36+
// Typewriter effect
37+
export const initTypewriter = (element: HTMLElement, text: string, speed: number = 100): void => {
38+
let i = 0;
39+
element.innerHTML = '';
40+
41+
const type = (): void => {
42+
if (i < text.length) {
43+
element.innerHTML += text.charAt(i);
44+
i++;
45+
setTimeout(type, speed);
46+
}
47+
};
48+
49+
type();
50+
};
51+
52+
// Initialize all animations
53+
export const initAllAnimations = (): void => {
54+
if (typeof window === 'undefined') return;
55+
56+
initScrollAnimations();
57+
initParallax();
58+
59+
// Initialize typewriter effects for elements with data-typewriter attribute
60+
const typewriterElements = document.querySelectorAll('[data-typewriter]');
61+
typewriterElements.forEach((el) => {
62+
const text = el.getAttribute('data-typewriter') || '';
63+
const speed = parseInt(el.getAttribute('data-typewriter-speed') || '100');
64+
initTypewriter(el as HTMLElement, text, speed);
65+
});
66+
};
67+
68+
// Cleanup function for useEffect
69+
export const cleanupAnimations = (): void => {
70+
if (typeof window === 'undefined') return;
71+
72+
// Remove scroll event listeners
73+
window.removeEventListener('scroll', () => {});
74+
};

0 commit comments

Comments
 (0)