Для реализации эффекта, где горизонтальный скролл блока переключается на вертикальный скролл вниз при достижении конца, можно использовать React вместе с хуками и обработчиками событий. Давайте рассмотрим, как это можно сделать.
### Шаги реализации
1. **Создание компонента с горизонтальным скроллом**.
2. **Отслеживание события скролла и изменение направления**.
3. **Переключение обратно на вертикальный скролл**.
### Пример кода
Вот базовый пример, как это можно реализовать:
```jsx
import React, { useRef, useEffect, useState } from 'react';
import './App.css'; // добавьте стили для демонстрации
const App = () => {
const scrollRef = useRef(null);
const [isHorizontalScroll, setIsHorizontalScroll] = useState(true);
const items = Array.from({ length: 20 }, (_, i) => (
<div className="item" key={i}>
Item {i + 1}
</div>
));
useEffect(() => {
const handleScroll = (e) => {
if (isHorizontalScroll) {
e.preventDefault();
scrollRef.current.scrollLeft += e.deltaY; // Горизонтальный скролл
}
};
const handleScrollEnd = () => {
const scrollWidth = scrollRef.current.scrollWidth;
const clientWidth = scrollRef.current.clientWidth;
// Проверяем достигли ли конца горизонтального скролла
if (scrollRef.current.scrollLeft + clientWidth >= scrollWidth) {
setIsHorizontalScroll(false);
window.scrollTo(0, window.scrollY + 200); // Переключаем на вертикальный скролл
} else if (scrollRef.current.scrollLeft === 0) {
setIsHorizontalScroll(true);
window.scrollTo(0, window.scrollY - 200); // Вернуться вверх
}
};
const ref = scrollRef.current;
if (ref) {
ref.addEventListener('wheel', handleScroll);
ref.addEventListener('scroll', handleScrollEnd);
}
return () => {
if (ref) {
ref.removeEventListener('wheel', handleScroll);
ref.removeEventListener('scroll', handleScrollEnd);
}
};
}, [isHorizontalScroll]);
return (
<div className="container">
<div className="horizontal-scroll" ref={scrollRef}>
{items}
</div>
</div>
);
};
export default App;
```
### Стили (App.css)
```css
.container {
height: 100vh; /* Высота экрана */
overflow-y: scroll; /* Вертикальный скролл */
}
.horizontal-scroll {
display: flex;
overflow-x: auto; /* Горизонтальный скролл */
white-space: nowrap;
height: 200px; /* Высота блока с горизонтальным скроллом */
}
.item {
width: 200px; /* Ширина элемента */
height: 100%; /* Высота 100% от родителя */
border: 1px solid #ccc;
display: flex;
align-items: center;
justify-content: center;
margin: 1rem;
}
```
### Как это работает
1. **Горизонтальное прокручивание**: Используем `e.deltaY` для горизонтального скролла, когда `isHorizontalScroll` равно `true`.
2. **Смена направления скролла**: При достижении конца или начала горизонтального скролла `setIsHorizontalScroll` переключается на `false` или `true`, а затем осуществляется прокрутка страницы вниз или вверх.
3. **Очистка событий**: Не забывайте убирать обработчики событий при размонтировании компонента.
### Заказ рисовки и оптимизация
В реальном приложении потребуется учесть производительность и UX. Можно добавить анимации, плавный переход между прокрутками и более продвинутую логику для определения момента, когда переключаться между прокрутками.