Здравствуйте! Можете подсказать, как задать ограничения для перетаскиваемого объекта внутри элемента div, чтобы его движение происходило в диапазоне от 0% до 100%? В данный момент я могу перемещать его без ограничений вверх и вниз, но мне необходимо, чтобы он двигался от 0% вверх до 100% вниз. Вот фрагмент кода, который я использую: <code>import { useEffect, useState } from "react";</code> <pre><code class="typescript">const [isDragging, setIsDragging] = useState(false); const [yTranslate, setYTranslate] = useState(0); const [initialMousePosition, setInitialMousePosition] = useState(undefined);</code></pre> <pre><code class="javascript">const onMouseDown = ({ clientY }) => { setInitialMousePosition({ y: clientY }); setIsDragging(true); }; useEffect(() => { const onMouseMove = (e) => { setYTranslate(yTranslate + e.clientY - initialMousePosition.y); }; if (isDragging) { window.addEventListener("mousemove", onMouseMove); } return () => window.removeEventListener("mousemove", onMouseMove); }, [isDragging, initialMousePosition]); useEffect(() => { const onMouseUp = () => setIsDragging(false); window.addEventListener("mouseup", onMouseUp); return () => window.removeEventListener("mouseup", onMouseUp); }, []);</code></pre> <pre><code class="javascript"><div style={{"cover": yTranslate + "%"}}> <div onMouseDown={onMouseDown}>Тащи меня</div> </div></code></pre>
Чтобы ограничить перемещение элемента по оси Y в диапазоне от 0% до 100%, вам нужно добавить проверку перед тем, как обновить состояние `yTranslate`. Вы можете сделать это, используя функцию `Math.min` и `Math.max`, чтобы удостовериться, что значение остается в пределах заданного диапазона. Вот обновленный код с добавленными ограничениями: ```javascript import { useEffect, useState } from "react"; const MyComponent = () => { const [isDragging, setIsDragging] = useState(false); const [yTranslate, setYTranslate] = useState(0); const [initialMousePosition, setInitialMousePosition] = useState(undefined); const onMouseDown = ({ clientY }) => { setInitialMousePosition({ y: clientY }); setIsDragging(true); }; useEffect(() => { const onMouseMove = (e) => { // Вычисляем новое значение yTranslate const newYTranslate = yTranslate + e.clientY - initialMousePosition.y; // Ограничиваем его в диапазоне от 0% до 100% const boundedYTranslate = Math.max(0, Math.min(100, newYTranslate)); setYTranslate(boundedYTranslate); setInitialMousePosition({ y: e.clientY }); // Обновляем начальную позицию курсора }; if (isDragging) { window.addEventListener("mousemove", onMouseMove); } return () => window.removeEventListener("mousemove", onMouseMove); }, [isDragging, initialMousePosition, yTranslate]); useEffect(() => { const onMouseUp = () => setIsDragging(false); window.addEventListener("mouseup", onMouseUp); return () => window.removeEventListener("mouseup", onMouseUp); }, []); return ( <div style={{ "height": "100vh", "position": "relative", "overflow": "hidden" }}> <div style={{ transform: `translateY(${yTranslate}%)`, transition: 'transform 0.1s ease' }}> <div onMouseDown={onMouseDown} style={{ cursor: 'grab' }}>Тащи меня</div> </div> </div> ); }; export default MyComponent; ``` ### Изменения и пояснения: 1. **Проверка границ:** Используйте `Math.max(0, Math.min(100, newYTranslate))`, чтобы гарантировать, что `yTranslate` не может выходить за пределы от 0 до 100. 2. **Обновление начальной позиции курсора:** После того, как вы обновили значение `yTranslate`, важно обновить `initialMousePosition`, чтобы избежать резких скачков при перетаскивании. Это делается для того, чтобы учитывать текущее положение мыши как новое начальное. 3. **Стиль и структурирование:** Вы можете добавить стили к контейнеру, если необходимо, чтобы обеспечить правильное поведение и внешний вид. Теперь ваш элемент будет ограничен в движении по оси Y в пределах от 0% до 100%.
Для реализации ограничения движения элемента по оси Y в пределах от 0% до 100%, необходимо добавить логику, которая будет проверять текущее значение yTranslate и ограничивать его в указанных границах.
const Draggable = () => { const [isDragging, setIsDragging] = useState(false); const [yTranslate, setYTranslate] = useState(0); // % const [initialMousePosition, setInitialMousePosition] = useState(null); const onMouseDown = ({ clientY }) => { setInitialMousePosition(clientY); setIsDragging(true); }; useEffect(() => { const onMouseMove = (e) => { if (isDragging && initialMousePosition !== null) { const deltaY = e.clientY - initialMousePosition; const containerHeight = document.querySelector(".relative").offsetHeight; // px -> % const deltaYPercent = (deltaY / containerHeight) * 100; let newTranslate = yTranslate + deltaYPercent; // [0%, 100%] newTranslate = Math.max(0, Math.min(100, newTranslate)); setYTranslate(newTranslate); setInitialMousePosition(e.clientY); } }; if (isDragging) { window.addEventListener("mousemove", onMouseMove); } return () => window.removeEventListener("mousemove", onMouseMove); }, [isDragging, initialMousePosition, yTranslate]); useEffect(() => { const onMouseUp = () => setIsDragging(false); window.addEventListener("mouseup", onMouseUp); return () => window.removeEventListener("mouseup", onMouseUp); }, []); return ( <div className="text-[15px]/[22px] bg-white"> <div style={{ '--coverY': `${yTranslate}%` }} className="relative aspect-[640_/_200] bg-[#e5e5e5] overflow-hidden"> {/* не забудь повесить onMouseDown на нужный элемент */} </div> </div> ); };