我一直在审查文档和github问题,connectDragPreview对我来说仍然是一个谜.我想定义一个自定义预览,以了解项目在拖动时的显示方式.它应该起作用,就像这里的例子适用于拖动时出现的马图像一样.这是我的代码:
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 };
Run Code Online (Sandbox Code Playgroud)
此代码将显示标准预览.
然后我尝试connectDragSource用我的组件的render()方法包装connectDragPreview,但这只会改变从中拾取它的拖动源,而不是它被拖动时的显示方式.
如何指定应该用作拖动视觉的标记?
看来您正在使用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, 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 = 'base64-image';
img.onload = () => connectDragPreview(img);
}
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 };Run Code Online (Sandbox Code Playgroud)
如果要使用自定义标记,可以使用getEmptyImage参数调用connectDragPreview,然后实现CustomDragLayer。
您的令牌类:
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, monitor) => {
return {
connectDragSource: connect.dragSource(),
connectDragPreview: connect.dragPreview(),
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, isDragging, 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", tokenSpec, tokenCollector)(
TokenClass
);Run Code Online (Sandbox Code Playgroud)
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-capRun Code Online (Sandbox Code Playgroud)
另外,我上传到github解决方案,该解决方案可同时处理图像和标记。您可以上传它们并运行:
yarn install
yarn start
解决方案:https : //github.com/xnimorz/stackoverflow-example/tree/dragAndDrop
尝试更改您的直接img.onload使用img而不是将其包装在 a 中div:
img.onload = () => connectDragPreview(img);
Run Code Online (Sandbox Code Playgroud)
据我所知,这是您的代码与示例中唯一真正的区别。
| 归档时间: |
|
| 查看次数: |
3228 次 |
| 最近记录: |