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; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 100vh; height: 100vh;
height: 100dvh;
padding: var(--space-3xl) 0; padding: var(--space-3xl) 0;
overflow: hidden; overflow: hidden;
} }
@@ -105,6 +106,10 @@
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
z-index: 1; z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-sm);
} }
.scrollMouse { .scrollMouse {
@@ -124,6 +129,15 @@
border-radius: 2px; 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) { @media (max-width: 768px) {
.typed { .typed {
min-width: auto; min-width: auto;

View File

@@ -1,3 +1,4 @@
import { useState, useEffect } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { motion } from 'motion/react'; import { motion } from 'motion/react';
import { useTranslation } from '../../i18n'; import { useTranslation } from '../../i18n';
@@ -8,6 +9,16 @@ import styles from './Hero.module.css';
export function Hero() { export function Hero() {
const { t } = useTranslation(); 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({ const { text } = useTypingEffect({
words: t.hero.rotatingWords, words: t.hero.rotatingWords,
@@ -78,15 +89,24 @@ export function Hero() {
</motion.div> </motion.div>
</div> </div>
<div className={styles.scrollIndicator}> {showScrollIndicator && (
<motion.div <motion.div
className={styles.scrollMouse} className={styles.scrollIndicator}
animate={{ y: [0, 8, 0] }} initial={{ opacity: 0 }}
transition={{ repeat: Infinity, duration: 1.5, ease: 'easeInOut' }} 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> </motion.div>
</div> )}
</section> </section>
); );
} }

View File

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

View File

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