Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
9
rated 0 times [  13] [ 4]  / answers: 1 / hits: 5256  / 4 Years ago, tue, june 16, 2020, 12:00:00

after few days of trying with no success, I came here (again..), to all of you experts.


first of all: live demo! because we all love live demos.


Codesandbox


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


I'm trying to make interactive draggable and dropable arrows between containers(means - there is a connector to a box, you can drag your mouse from one of the containers to another box and an arrow between them will be created).



  • implementation 1: I can get an animation of a draggable arrow while dragging - but the onDrop event does not fire.

  • implementation 2: in the second implementation I can make the drop effect happen but not the animation.


NEVER THEM BOTH!
HELP! ;<


more detailed explanations inside the code.


what I've already tried:



  • react-dnd - did not work also because it's based on the same DOM event system the native browser drag & drop API based on(or maybe(and probably) I did it wrong?).


More From » reactjs

 Answers
2

Here you go :


To draw a Xarrow you need a starting point and ending point



  • Start point : will always be dragging from

  • End Point : Where you are dropping


Here We have 2 refs ,



  • ref0 : Starting drag point ( which will be the box )

  • ref1 : Draggable point ( Will be the draggable point )


Here is the code that needs to be changed, please do read the comments also, that will make the flow clear.


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>
);
};

WORKING DEMO :


Edit





NOTE :


I was trying to set style just via ref1 and not with setPosition,
you can check the below code snippet for that,





<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);
}}
/>





WORKING DEMO : ( this is just another way )


Edit<br #SO-drag-anim-optimization />





EDIT :


WORKING DEMO : ( With draggable box also )


Edit


[#3470] Saturday, June 13, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
reed

Total Points: 725
Total Questions: 85
Total Answers: 89

Location: Singapore
Member since Sat, Jul 25, 2020
4 Years ago
;