mirror of
https://github.com/FluxaMedia/fluxa-desktop.git
synced 2026-08-18 13:05:54 +00:00
fix: reliably restart hero slide indicator fill animation
The dot indicator relied on a React key remount to restart the CSS heroIndicatorFill keyframe on each slide change, which WebKitGTK sometimes fails to pick up as a fresh animation start, leaving the active dot frozen at 0% while the underlying slide timer kept advancing normally. Drive the restart imperatively via a ref with a forced reflow instead.
This commit is contained in:
parent
674921e250
commit
da8ef1dfb5
1 changed files with 16 additions and 7 deletions
|
|
@ -56,6 +56,7 @@ export const HeroSection = React.memo(function HeroSection({
|
|||
const pendingRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const activeIndexRef = useRef(activeIndex);
|
||||
activeIndexRef.current = activeIndex;
|
||||
const indicatorFillRef = useRef<HTMLSpanElement | null>(null);
|
||||
|
||||
const activeMeta = items[activeIndex] ?? meta;
|
||||
const canSlide = items.length > 1;
|
||||
|
|
@ -140,6 +141,20 @@ export const HeroSection = React.memo(function HeroSection({
|
|||
return () => window.clearInterval(id);
|
||||
}, [canSlide, items.length, isActive, trailerPending, slideIntervalMs]);
|
||||
|
||||
useEffect(() => {
|
||||
const el = indicatorFillRef.current;
|
||||
if (!el) return;
|
||||
el.style.animation = 'none';
|
||||
void el.offsetWidth;
|
||||
el.style.animation = `heroIndicatorFill ${slideIntervalMs}ms linear forwards`;
|
||||
el.style.animationPlayState = trailerPending || !isActive ? 'paused' : 'running';
|
||||
}, [activeIndex, slideIntervalMs]);
|
||||
|
||||
useEffect(() => {
|
||||
const el = indicatorFillRef.current;
|
||||
if (el) el.style.animationPlayState = trailerPending || !isActive ? 'paused' : 'running';
|
||||
}, [trailerPending, isActive]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!canSlide) return;
|
||||
const next = items[(activeIndex + 1) % items.length];
|
||||
|
|
@ -346,16 +361,10 @@ export const HeroSection = React.memo(function HeroSection({
|
|||
onClick={() => goTo(i)}
|
||||
>
|
||||
<span
|
||||
key={i === activeIndex ? `${activeIndex}` : `${i}-static`}
|
||||
ref={i === activeIndex ? indicatorFillRef : undefined}
|
||||
style={{
|
||||
...styles.indicatorFill,
|
||||
...(i < activeIndex ? styles.indicatorFillDone : null),
|
||||
...(i === activeIndex
|
||||
? {
|
||||
animation: `heroIndicatorFill ${slideIntervalMs}ms linear forwards`,
|
||||
animationPlayState: trailerPending || !isActive ? 'paused' : 'running',
|
||||
}
|
||||
: null),
|
||||
}}
|
||||
/>
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Reference in a new issue