feat: Добавлены названия периодов с анимацией появления

This commit is contained in:
Ilia Mashkov
2025-11-23 13:14:20 +03:00
parent 2958cc734a
commit 38785cce94
2 changed files with 55 additions and 7 deletions

View File

@@ -46,15 +46,30 @@
background-clip: padding-box; background-clip: padding-box;
} }
&:hover .label, &:hover .number,
&.active .label { &.active .number {
display: block; display: block;
} }
.label { .number {
display: none; display: none;
color: var(--color-text); color: var(--color-text);
font-size: 20px; font-size: 20px;
} }
.title {
position: absolute;
left: 100%;
margin-left: 20px;
color: var(--color-text);
font-weight: 700;
font-size: 20px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
}
} }

View File

@@ -67,6 +67,9 @@ export const CircleTimeline = memo(function CircleTimeline({
// Реф для массива точек периодов // Реф для массива точек периодов
const pointsRef = useRef<(HTMLDivElement | null)[]>([]) const pointsRef = useRef<(HTMLDivElement | null)[]>([])
// Реф для заголовков периодов
const titlesRef = useRef<(HTMLSpanElement | null)[]>([])
/** /**
* Эффект для анимации поворота круга и контр-поворота точек * Эффект для анимации поворота круга и контр-поворота точек
* Запускается при изменении rotation * Запускается при изменении rotation
@@ -82,16 +85,38 @@ export const CircleTimeline = memo(function CircleTimeline({
} }
// Контр-поворот точек, чтобы текст оставался читаемым // Контр-поворот точек, чтобы текст оставался читаемым
pointsRef.current.forEach((point) => { pointsRef.current.forEach((point, index) => {
if (point) { if (point) {
gsap.to(point, { gsap.to(point, {
rotation: -rotation, rotation: -rotation,
duration: 0, duration: 0,
ease: ANIMATION_EASE, ease: ANIMATION_EASE,
}) })
// Анимация заголовка
const title = titlesRef.current[index]
if (title) {
// Сбрасываем предыдущие анимации для этого элемента
gsap.killTweensOf(title)
if (index === activeIndex) {
gsap.to(title, {
opacity: 1,
visibility: 'visible',
duration: 0.5,
delay: ANIMATION_DURATION, // Ждем окончания вращения
})
} else {
gsap.to(title, {
opacity: 0,
visibility: 'hidden',
duration: 0.2,
})
}
}
} }
}) })
}, [rotation]) }, [rotation, activeIndex])
/** /**
* Мемоизированный расчет позиций точек на круге * Мемоизированный расчет позиций точек на круге
@@ -138,7 +163,15 @@ export const CircleTimeline = memo(function CircleTimeline({
aria-label={`Period ${index + 1}: ${period.label}`} aria-label={`Period ${index + 1}: ${period.label}`}
aria-current={index === activeIndex ? 'true' : 'false'} aria-current={index === activeIndex ? 'true' : 'false'}
> >
<span className={styles.label}>{index + 1}</span> <span className={styles.number}>{index + 1}</span>
<span
className={styles.title}
ref={(el) => {
titlesRef.current[index] = el
}}
>
{period.label}
</span>
</div> </div>
) )
})} })}