Для реализации ограничения движения элемента по оси 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>
);
};