reactjs – react-dnd的connectDragPreview()如何工作?
我一直在审查文档和
github问题,connectDragPreview对我来说仍然是一个谜.我想定义一个自定义预览,以了解项目在拖动时的显示方式.它应该起作用,就像示例
here与拖动时出现的马图像一样.这是我的代码:
export const tokenCollector: DragSourceCollector = (connect,monitor) => { return { connectDragSource: connect.dragSource(),connectDragPreview: connect.dragPreview(),isDragging: monitor.isDragging() }; }; class TokenClass extends React.Component<TokenProps> { componentDidMount() { const { connectDragPreview } = this.props; const img = new Image(); img.src = '<encoded image>'; img.onload = () => connectDragPreview(<div>{img}</div>); } render() { const { connectDragSource,isDragging,children } = this.props; return connectDragSource( <div style={{ opacity: isDragging ? 0.5 : 1 }}> {children} </div> ); } } const dragSource = DragSource(DropType.Token,tokenSpec,tokenCollector)(TokenClass); export { dragSource as Token }; 此代码将显示标准预览. 然后我尝试使用connectDragPreview将我的connectDragSource包装在我的组件的render()方法中,但这只会改变从中拾取它的拖动源,而不是它在被拖动时的显示方式. 如何指定应该用作拖动视觉的标记?
它似乎你正在使用react-dnd-html5-backend.
React-dnd-html5-backend提供connectDragSource: https://github.com/react-dnd/react-dnd-html5-backend/blob/85fc956c58a5d1a9fde2fca3c7fca9115a7c87df/src/HTML5Backend.js#L100 而react-dnd-html5-backend仅适用于html5拖放事件:https://github.com/react-dnd/react-dnd-html5-backend/blob/85fc956c58a5d1a9fde2fca3c7fca9115a7c87df/src/HTML5Backend.js#L65-L74 因此,您只能为拖动效果设置图像:https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage 您只需更改img.onload回调即可: export const tokenCollector: DragSourceCollector = (connect,isDragging: monitor.isDragging() }; }; class TokenClass extends React.Component<TokenProps> { componentDidMount() { const { connectDragPreview } = this.props; const img = new Image(); img.src = 'base64-image'; img.onload = () => connectDragPreview(img); } render() { const { connectDragSource,tokenCollector)(TokenClass); export { dragSource as Token }; 如果要使用自定义标记,可以使用getEmptyImage参数调用connectDragPreview,然后实现CustomDragLayer. 你的TokenClass: import React,{ Component } from "react"; import { DragSource } from "react-dnd"; import logo from "./logo.svg"; import { getEmptyImage } from "react-dnd-html5-backend"; export const tokenCollector = (connect,isDragging: monitor.isDragging() }; }; class TokenClass extends React.Component { componentDidMount() { const { connectDragPreview } = this.props; // Use empty image as a drag preview so browsers don't draw it // and we can draw whatever we want on the custom drag layer instead. connectDragPreview(getEmptyImage()); } render() { const { connectDragSource,children } = this.props; return connectDragSource( <div style={{ opacity: isDragging ? 0.5 : 1,backgroundColor: "green" }}> {children} </div> ); } } const tokenSpec = { beginDrag() { return {}; } }; export default DragSource("DropType.Markup",tokenCollector)( TokenClass ); CustomDragLayer实现: import React,{ Component } from "react"; import { DragLayer } from "react-dnd"; function getItemStyles(props) { const { initialOffset,currentOffset } = props; if (!initialOffset || !currentOffset) { return { display: "none" }; } let { x,y } = currentOffset; const transform = `translate(${x}px,${y}px)`; return { transform,WebkitTransform: transform }; } class CustomDragLayer extends Component { render() { const isDragging = this.props.isDragging; if (!isDragging) { return null; } // You can specify acceptable type: if (this.props.itemType !== "DropType.Markup") { return null; } // The component will work only when dragging return ( <div> <div style={getItemStyles(this.props)}>Custom drag layer!</div> </div> ); } } function collect(monitor) { return { item: monitor.getItem(),itemType: monitor.getItemType(),initialOffset: monitor.getInitialSourceClientOffset(),currentOffset: monitor.getSourceClientOffset(),isDragging: monitor.isDragging() }; } export default DragLayer(collect)(CustomDragLayer); // eslint-disable-line new-cap 此外,我上传到github解决方案,该解决方案适用于图像和标记.您可以上传并运行: 纱线安装 解决方案:https://github.com/xnimorz/stackoverflow-example/tree/dragAndDrop (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |