реагировать на перетаскивание, падение и стрелку соединения (или что-то еще) с анимацией между элементами - PullRequest
1 голос
/ 16 июня 2020

после нескольких дней безуспешных попыток, я пришел сюда (снова ..), ко всем вам, эксперты.

прежде всего: живая демонстрация! потому что все мы любим живые демонстрации.

Codesandbox

https://codesandbox.io/s/drag-with-not-animation-b3eh7?file= / src / App. js

Я пытаюсь сделать интерактивным перетаскиваемые и перетаскиваемые стрелки между контейнерами (означает - есть соединитель с блоком, вы можете перетащить указатель мыши из одного из контейнеров в другой блок, и между ними будет создана стрелка).

  • реализация 1: я могу получить анимацию перетаскиваемой стрелки при перетаскивании, но событие onDrop не срабатывает.
  • реализация 2: во второй реализации я могу сделать эффект перетаскивания, но не анимацию.

НИКОГДА И НИХ! ПОМОГИТЕ! ; <</p>

более подробные объяснения внутри кода.

то, что я уже пробовал:

  • response-dnd - не сработало еще и потому, что оно основано на та же система событий DOM, собственный API перетаскивания браузера на основе (или, может быть (и, возможно), я сделал это неправильно?).

(если вам понравился мой вопрос / предварительный просмотр, пожалуйста, нажмите вверх, он уже стоил мне 50 репутаций, чтобы привлечь внимание к этому посту)

1 Ответ

1 голос
/ 22 июня 2020

Здесь вы go:

Чтобы нарисовать Xarrow, вам нужны начальная и конечная точки

  • Начальная точка: всегда будет перетаскиваться из
  • Конечная точка: куда вы падаете

Здесь у нас есть 2 refs,

  • ref0: Начальная точка перетаскивания (которая будет рамкой)
  • ref1: Перетаскиваемая точка (будет перетаскиваемой точкой)

Вот код, который необходимо изменить, пожалуйста, прочтите также комментарии, которые сделают поток понятным .

const ConnectPointsWrapper = ({ boxId, handler, ref0 }) => {
    const ref1 = useRef();

    const [position, setPosition] = useState({});
    const [beingDragged, setBeingDragged] = useState(false);
    return (
        <React.Fragment>
            <div
                className="connectPoint"
                ref={ref1} // <---- referencing the point
                style={{
                    ...connectPointStyle,
                    ...connectPointOffset[handler],
                    ...position // <----- Updating the position as we drags
                }}
                draggable
                onDragStart={e => {
                    setBeingDragged(true);
                    e.dataTransfer.setData("arrow", boxId);
                }}
                onDrag={e => {
                    setPosition({ // <---- Setting up the position to draw line as we drags
                        position: "fixed",
                        left: e.clientX,
                        top: e.clientY,
                        transform: "none",
                        opacity: 0
                    });
                }}
                onDragEnd={e => {
                    setPosition({});
                    setBeingDragged(false);
                }}
            />
            {beingDragged ? <Xarrow start={ref0} end={ref1} /> : null} // <---- this will draw the arrow b/w ref0 and ref1
        </React.Fragment>
    );
};

const Box = ({ text, handler, addArrow, boxId }) => {
    const ref0 = useRef(); 
    return (
        <div
            id={boxId}
            style={boxStyle}
            ref={ref0} // <---- referencing the box it self
            onDragOver={e => e.preventDefault()}
            onDrop={e => {
                if (e.dataTransfer.getData("arrow") === boxId) {
                    console.log(e.dataTransfer.getData("arrow"), boxId);
                } else {
                    const refs = { start: e.dataTransfer.getData("arrow"), end: boxId };
                    addArrow(refs);
                }
            }}
        >
            {text}
            <ConnectPointsWrapper {...{ boxId, handler, ref0 }} /> // <---- Passing the `ref0` to `ConnectPointsWrapper` to draw line from point
        </div>
    );
};

РАБОЧАЯ ДЕМО:

image

<div
        className="connectPoint"
        style={{
          ...connectPointStyle,
          ...connectPointOffset[handler]
        }}
        draggable
        onDragStart={e => {
          setBeingDragged(true);
          e.dataTransfer.setData("arrow", boxId);
        }}
        onDrag={e => {
          setPosition({}); // <---- just to force re-rendering, to draw arrow with updated value
          ref1.current.style.position = "fixed";
          ref1.current.style.left = e.clientX + "px";
          ref1.current.style.top = e.clientY + "px";
          ref1.current.style.transform = "none";
          ref1.current.style.opacity = 0;
        }}
        ref={ref1}
        onDragEnd={e => {
          ref1.current.style.position = "absolute";
          ref1.current.style.left = connectPointOffset[handler].left;
          ref1.current.style.top = connectPointOffset[handler].top;
          ref1.current.style.transform = connectPointOffset[handler].transform;
          ref1.current.style.opacity = 0.5;
          setBeingDragged(false);
        }}
      />

РАБОЧАЯ ДЕМО: (это просто другой способ)

Edit #SO-drag-anim-optimization


EDIT :

WORKING DEMO : ( With draggable box also )

Редактировать drag-anim-with-draggable

...