如何在React中一次拖动多个对象?

问题描述 投票:0回答:1

我想一次拖动多个对象(在DOM中保留它们的位置)。因此,如果对象重叠,则重叠顺序应保持不变。

enter image description here

我正在尝试使用react-draggablereact-dnd-Google上最受欢迎的拖放框架来实现这一目标。

react-dnd中,建议的解决方案是跟踪所选项目并实现自定义drag-layer。但是,这种方式将丢失DOM中的位置,因此视觉上的对象将以不同的方式彼此重叠。

我还没有在反应可拖动中找到如何做的方法。也许有一种方法可以使用某种[[draggableGroup属性来指示一组可拖动对象?有人以前实现过类似的东西吗?

这是我的可拖动反应的实验:codepen.io/markvital/pen/gOaRMNX

可以选择多个对象,但是只能拖动一个。

const canvasSize = {width:"600", height:"400"} function DraggableItem({id, selected, onSelect, children}) { const [isDragging, setIsDragging] = React.useState(false); const isSelected = selected && selected.indexOf(id) >= 0; function handleClick (e, idx) { if (e.shiftKey) { onSelect(idx); } } return ( <ReactDraggable onStart={ () => setIsDragging(true) } onStop={ () => { setIsDragging(false); } } disabled={!isSelected} > <g> <g className={`item ${isSelected ? "selected" : ""} ${isDragging ? "dragging" : ""}`} onClick={e => handleClick(e, id)}> {children} </g> </g> </ReactDraggable> ) } function DraggableElements(props) { const {children, ...restProps } = props; const draggable = children.map((child, idx) => <DraggableItem key={idx} id={idx} {...restProps}>{child}</DraggableItem>); return( <>{draggable}</> ) } function Canvas(props) { const [selected, setSelected] = React.useState([]); function select(idx){ const newSelection = selected.indexOf(idx) >= 0 ? selected.filter(item => item != idx) : [...selected, idx]; setSelected( newSelection ); } return ( <svg className="canvas" {...canvasSize} xmlns="http://www.w3.org/2000/svg" > <DraggableElements selected={selected} onSelect={select}> <rect x="120" y="250" width="100" height="100" fill="lightgrey" /> <circle cx="400" cy="100" r="75" fill="lightblue" /> <polygon points="160,300 200,100 350,230" fill="grey" /> <rect x="50" y="50" width="200" height="100" fill="lightgreen" /> <rect x="465" y="70" width="100" height="150" rx="25" fill="pink" /> <ellipse cx="400" cy="260" rx="130" ry="75" fill="lightyellow" /> </DraggableElements> </svg> ); } function App() { return ( <div className="App"> <Canvas /> <div> Hold SHIFT key to select multiple figures, than drag </div> </div> ); } let mountNode = document.getElementById("app"); ReactDOM.render(<App />, mountNode);

javascript reactjs drag-and-drop draggable react-dnd
1个回答
0
投票
使用react-draggable的解决方案之一是将某些状态存储在父组件中,该状态描述拖动时光标的位置偏移:

function Canvas(props) { const [delta, setDelta] = useState(null); // cursor offset while dragging, {x:0, y:0} const [selected, setSelected] = useState([]); return ( // draggable elements, each wrapped in react-draggable <DraggableElements delta={delta} onDrag={handleDrag}> //.. </DraggableElements> ) }

然后将该增量传递给包装在Draggable组件中的子代
<ReactDraggable onDrag={ (e, data) => { onDrag({x: data.x, y: data.y }, id) } }>
   <g style={delta ? {transform: `translate(${delta.x}px, ${delta.y}px)`} }>
      //...
   </g> 
</ReactDraggable>

这里是工作版本,根据我之前的示例:codepen.io/markvital/pen/vYNZXgW

希望看到更多最佳解决方案。
© www.soinside.com 2019 - 2024. All rights reserved.