Задать вопрос
@Golopolos

Как двигать элемент по Y с заданным значением?

Приветствую.
Подскажите, как задать границы перетаскиваемого объекта внутри div, от 0% до 100%

Сейчас я могу его двигать бесконечное количество процентов вверх и вниз, а нужно вверх 0 вниз 100%

import { useEffect, useState } from "react";
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) => {
      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);
  }, []);


<div className="text-[15px]/[22px] bg-white">
      <div className="relative aspect-[640_/_200] bg-[#e5e5e5] overflow-hidden" style={{'coverY': yTranslate + '%'}}>
        <div className="w-full h-full overflow-hidden grid grid-cols-[100%] grid-rows-[100%]" style={{aspectRatio: '1 / 1', maxWidth: 'none'}}>
          <picture className="block w-full h-full col-[1] row-[1]">
            <img src="/1.jpg" alt="" className="object-[0_var(coverY,50%)] object-cover w-full h-full" />
          </picture>
        </div>
        <div className="group flex absolute w-full h-full select-none left-0 top-0 cursor-move">
          <div className="absolute w-full h-full z-[1] left-0 top-0" onMouseDown={onMouseDown}></div>
        </div>
      </div>
    </div>
  • Вопрос задан
  • 97 просмотров
Подписаться 1 Простой 4 комментария
Решения вопроса 1
@andry36
Для реализации ограничения движения элемента по оси 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>
  );
};
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы