gpt4 book ai didi

reactjs - React-dnd 的 connectDragPreview() 是如何工作的?

转载 作者:行者123 更新时间:2023-12-03 13:29:59 25 4
gpt4 key购买 nike

我一直在查看文档和 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, 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 };

如果您想使用自定义标记,可以使用 getEmptyImage 参数调用 connectDragPreview,然后实现 CustomDragLayer。

您的 token 类别:

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

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 解决方案,该解决方案适用于图像和标记。您可以上传它们并运行:
yarn 安装
yarn 开始
解决方案:https://github.com/xnimorz/stackoverflow-example/tree/dragAndDrop

关于reactjs - React-dnd 的 connectDragPreview() 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48811165/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com