Files
ridebus-website/modules/home/header.tsx
2026-10-02 20:31:49 +03:00

119 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import styles from '@/modules/home/home.module.scss';
import useLocale from '@/utils/useLocale';
import { LocalesMap } from '@/utils/useLocale';
import clsx from 'clsx';
import { manrope, caveat } from '@/styles/fonts';
import ThinStarBig from '@/assets/images/thin-star-big.svg';
import ThickRoundStar5 from '@/assets/images/thick-round-star-5.svg';
import ThickRoundStar6 from '@/assets/images/thick-round-star-6.svg';
import ridebusFlat from '@/assets/images/cities-backdrop.jpg';
import Image from 'next/image';
import { Gradients } from '@/components/gradients';
import { useEffect, useRef, Fragment } from 'react';
import GradientPrimary from '@/assets/images/header-gradient-primary.svg';
import GradientTertiary from '@/assets/images/header-gradient-tertiary.svg';
import useScroll from '@/utils/useScroll';
import { TopBar } from '@/components/topBar';
import useFrame from '@/utils/useFrame';
import useMediaQuery from '@/utils/useMediaQuery';
import noise from '@/assets/images/noise.png';
const locales: LocalesMap = {
ru: {
slogan_line: (
<>
<span>Приложение,</span>
<span>которое</span>
<span>поможет</span>
<span>вам</span>
<span>с</span>
<span className={styles.spendWord}>лёгкостью</span>
<span>смотреть</span>
<span>расписание</span>
<span className={clsx(caveat.className, styles.wiselyWord)}>транспорта</span>
</>
),
},
en: {
slogan_line: (
<>
<span>Small</span>
<span>app</span>
<span>that</span>
<span>helps</span>
<span>you</span>
<span className={styles.spendWord}>conveniently</span>
<span>view</span>
<span className={clsx(caveat.className, styles.wiselyWord)}>
public
</span>
<span className={clsx(caveat.className, styles.wiselyWord)}>
transport
</span>
<span className={clsx(caveat.className, styles.wiselyWord)}>
schedules
</span>
</>
),
},
};
export default function Header() {
const t = useLocale(locales);
const sloganLineRef = useRef<HTMLSpanElement>(null);
const transitionToBackgoundRef = useRef<HTMLDivElement>(null);
const thickRoundStar6 = useRef<HTMLDivElement>(null);
const thickRoundStar5 = useRef<HTMLDivElement>(null);
const breakpoint600 = false;//useMediaQuery('(max-width: 600px)');
useScroll((scrollY, deltaTime, time) => {
const childs: HTMLSpanElement[] = [
...Array.from(sloganLineRef.current?.children || []),
] as HTMLSpanElement[];
childs.forEach((child, index) => {
const rawOffset = Math.min(-scrollY * 2 + index * 50, 0);
const offset = Math.max(-Math.pow(rawOffset / 50, 2), -500);
const rotateDirection = index % 2 === 0 ? 1 : -1;
child.style.transform = `translate3D(0px, ${offset}px, 0px) rotate(${(offset / 10) * rotateDirection}deg)`;
});
if (transitionToBackgoundRef.current && scrollY + 300 < window.innerHeight) {
transitionToBackgoundRef.current.style.height = `${scrollY + 300}px`;
}
if (thickRoundStar6.current && scrollY - 300 < window.innerHeight) {
thickRoundStar6.current.style.transform = `translate3D(0px, ${scrollY / 2}px, 0px) rotate(${scrollY / 8 + (time * 0.01) % 360}deg)`;
}
if (thickRoundStar5.current && scrollY - 300 < window.innerHeight) {
thickRoundStar5.current.style.transform = `translate3D(0px, ${scrollY / 8}px, 0px) rotate(${scrollY / 8 + (time * 0.01) % 360}deg)`;
}
}, { accelerator: 0.06 });
return (
<Fragment>
<header className={styles.header}>
<TopBar />
<div className={styles.thickRoundStar6}
ref={thickRoundStar6}>
<ThickRoundStar6 />
</div>
<div className={styles.thickRoundStar5}
ref={thickRoundStar5}>
<ThickRoundStar5 />
</div>
<h1 className={clsx(styles.slogan, manrope.className)}>
<span ref={sloganLineRef} className={styles.line1}>
{t('slogan_line')}
</span>
</h1>
<div className={styles.gradientContainer}>
<GradientPrimary className={styles.greenGradient} />
<GradientTertiary className={styles.orangeGradient} />
</div>
</header>
</Fragment>
);
}