使用元素之间的动画来react拖放和连接箭头(或其他任何东西)

IT技术 javascript reactjs animation drag-and-drop
2021-05-24 11:51:56

经过几天的尝试但没有成功,我来到这里(再次..),给你们所有的专家。

首先:现场演示!因为我们都喜欢现场演示。

代码沙盒

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

我正在尝试在容器之间制作交互式可拖动和可放置箭头(意味着 - 有一个连接到框的连接器,您可以将鼠标从一个容器拖到另一个框,并且将在它们之间创建一个箭头)。

  • 实现 1:我可以在拖动时获得可拖动箭头的动画 - 但 onDrop 事件不会触发。
  • 实现 2:在第二个实现中,我可以使放置效果发生,但不能使动画发生。

从来没有他们两个!帮助!;<

代码中更详细的解释。

我已经尝试过的:

  • react-dnd - 也不起作用,因为它基于与本机浏览器拖放 API 相同的 DOM 事件系统(或者可能(并且可能)我做错了?)。
1个回答

干得好 :

要绘制一个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>
    );
};

工作演示:

编辑 #SO-drag-anim-done


笔记 :

我试图通过ref1而不是使用来设置样式setPosition,您可以查看下面的代码片段,

工作演示:(这只是另一种方式)

编辑#SO-drag-anim-optimization


编辑 :

工作演示:(也带有可拖动框)

编辑带有可拖动的拖动动画