feat: add scroll indicator with animation and translations

This commit is contained in:
Melvin Ragusa
2026-01-21 23:05:37 +01:00
parent b63b9d64f8
commit b4ae9093bc
4 changed files with 43 additions and 7 deletions

View File

@@ -3,7 +3,8 @@
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
height: 100vh;
height: 100dvh;
padding: var(--space-3xl) 0;
overflow: hidden;
}
@@ -105,6 +106,10 @@
left: 50%;
transform: translateX(-50%);
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-sm);
}
.scrollMouse {
@@ -124,6 +129,15 @@
border-radius: 2px;
}
.scrollText {
font-size: 0.75rem;
font-weight: 500;
color: var(--md-sys-color-on-surface);
opacity: 0.4;
text-transform: uppercase;
letter-spacing: 0.1em;
}
@media (max-width: 768px) {
.typed {
min-width: auto;

View File

@@ -1,3 +1,4 @@
import { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { motion } from 'motion/react';
import { useTranslation } from '../../i18n';
@@ -8,6 +9,16 @@ import styles from './Hero.module.css';
export function Hero() {
const { t } = useTranslation();
const [showScrollIndicator, setShowScrollIndicator] = useState(true);
useEffect(() => {
const handleScroll = () => {
setShowScrollIndicator(window.scrollY < 50);
};
window.addEventListener('scroll', handleScroll, { passive: true });
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const { text } = useTypingEffect({
words: t.hero.rotatingWords,
@@ -78,15 +89,24 @@ export function Hero() {
</motion.div>
</div>
<div className={styles.scrollIndicator}>
{showScrollIndicator && (
<motion.div
className={styles.scrollMouse}
animate={{ y: [0, 8, 0] }}
transition={{ repeat: Infinity, duration: 1.5, ease: 'easeInOut' }}
className={styles.scrollIndicator}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
>
<span className={styles.scrollWheel} />
<motion.div
className={styles.scrollMouse}
animate={{ y: [0, 8, 0] }}
transition={{ repeat: Infinity, duration: 1.5, ease: 'easeInOut' }}
>
<span className={styles.scrollWheel} />
</motion.div>
<span className={styles.scrollText}>{t.hero.scroll}</span>
</motion.div>
</div>
)}
</section>
);
}

View File

@@ -14,6 +14,7 @@ export const de = {
rotatingWords: ['Webentwicklung', 'IT-Support', 'Digitale Lösungen', 'Tech-Beratung'],
cta: 'Projekt starten',
ctaSecondary: 'Mehr erfahren',
scroll: 'Scrollen',
},
// Services

View File

@@ -16,6 +16,7 @@ export const en: Translations = {
rotatingWords: ['Web Development', 'IT Support', 'Digital Solutions', 'Tech Consulting'],
cta: 'Start Project',
ctaSecondary: 'Learn More',
scroll: 'Scroll',
},
// Services