diff --git a/landing/src/components/KeyBusinessSegments/index.tsx b/landing/src/components/KeyBusinessSegments/index.tsx
index f929e47..c747333 100644
--- a/landing/src/components/KeyBusinessSegments/index.tsx
+++ b/landing/src/components/KeyBusinessSegments/index.tsx
@@ -293,6 +293,35 @@ const RightBrand = styled.div`
}
`;
+function usePreloadImages(urls: string[]) {
+ useEffect(() => {
+ if (!urls?.length) return;
+ const unique = Array.from(new Set(urls.filter(Boolean)));
+
+ unique.forEach((url) => {
+ if (!url) return;
+
+ // Проверяем, есть ли уже preload в
+ const exists = document.querySelector(
+ `link[rel="preload"][as="image"][href="${url}"]`
+ );
+ if (!exists) {
+ const link = document.createElement("link");
+ link.rel = "preload";
+ link.as = "image";
+ link.href = url;
+ document.head.appendChild(link);
+ }
+
+ // Дополнительно сразу грузим в memory cache
+ const img = new Image();
+ img.src = url;
+ });
+ }, [urls]);
+}
+
+
+
/* ===================== Component ===================== */
export default function KeyBusinessSegments() {
@@ -304,20 +333,19 @@ export default function KeyBusinessSegments() {
const segments = useMemo(() => mapSegments(data), [data]);
// --- предзагрузка иконок ---
- useEffect(() => {
- if (!segments?.length) return;
- const urls = segments.flatMap((seg) =>
- seg.info.flatMap((block) =>
- block.items
- .map((item) => item.infoLogo)
- .filter((u): u is string => Boolean(u))
- )
- );
- urls.forEach((url) => {
- const img = new Image();
- img.src = url;
- });
+ // собираем все картинки для предзагрузки
+ const preloadUrls = useMemo(() => {
+ if (!segments?.length) return [];
+ return segments.flatMap((seg) =>
+ seg.info.flatMap((block) => [
+ block.brandLogo, // ← бренд
+ ...block.items.map((item) => item.infoLogo), // ← иконки
+ ])
+ ).filter((u): u is string => Boolean(u));
}, [segments]);
+
+ // предзагрузка всех логотипов
+ usePreloadImages(preloadUrls);
// ---------------------------
@@ -328,11 +356,42 @@ export default function KeyBusinessSegments() {
const denom = Math.max(1, N - 1);
const defaultCenterIndex = useMemo(() => Math.floor(N / 2), [N]);
- const [activeIndex, setActiveIndex] = useState(defaultCenterIndex);
+ const [activeIndex, _setActiveIndex] = useState(defaultCenterIndex);
const [hoverIndex, setHoverIndex] = useState(null);
const [isOverflow, setIsOverflow] = useState(false);
const [isMobile, setIsMobile] = useState(false);
+ const [isLocked, setIsLocked] = useState(false);
+ const lockTimer = useRef(null);
+
+ // обёртка для смены индекса
+ const setActiveIndex = (idx: number) => {
+ if (idx === activeIndex) return;
+ _setActiveIndex(idx);
+ setIsLocked(true);
+ if (lockTimer.current) clearTimeout(lockTimer.current);
+ lockTimer.current = window.setTimeout(() => {
+ setIsLocked(false);
+ }, 250); // чуть больше transition
+ };
+
+
+ useEffect(() => {
+ const el = scrollerRef.current;
+ if (!el) return;
+ let raf = 0;
+ const onScroll = () => {
+ cancelAnimationFrame(raf);
+ raf = requestAnimationFrame(() => {
+ if (isLocked) return; // 🔒 во время анимации не пересчитываем
+ setActiveIndex(indexFromScroll(el.scrollLeft));
+ });
+ };
+ el.addEventListener("scroll", onScroll, { passive: true });
+ return () => el.removeEventListener("scroll", onScroll);
+ }, [denom, isLocked]);
+
+
/* ===== reserve-height measuring ===== */
const gridWrapRef = useRef(null);
const [gridMinHeight, setGridMinHeight] = useState(0);
@@ -393,20 +452,6 @@ export default function KeyBusinessSegments() {
return () => window.removeEventListener("resize", onResize);
}, [defaultCenterIndex, N]);
- useEffect(() => {
- const el = scrollerRef.current;
- if (!el) return;
- let raf = 0;
- const onScroll = () => {
- cancelAnimationFrame(raf);
- raf = requestAnimationFrame(() => {
- setActiveIndex(indexFromScroll(el.scrollLeft));
- });
- };
- el.addEventListener("scroll", onScroll, { passive: true });
- return () => el.removeEventListener("scroll", onScroll);
- }, [denom]);
-
const realActiveIndex = hoverIndex ?? activeIndex;
const activeSegment = segments[Math.min(Math.max(realActiveIndex, 0), N - 1)];
@@ -471,9 +516,16 @@ export default function KeyBusinessSegments() {
{block.items.map((item) => (
-
`
display: flex;
gap: ${(p) => p.$gap}px;
visibility: ${(p) => (p.$hidden ? "hidden" : "visible")};
- padding: 0px 10px;
+ margin-left:10px;
`;
const Frame = styled.div`