在 React + Konva 中拖动后如何 return <Rect/> 元素返回到原始位置
How to return <Rect/> element back to original position after drag in React + Konva
这是我尝试让 Rect 组件快速返回到其原始位置 (ReactKonva) 的尝试:
var toolBarWidth = window.innerWidth * 0.2;
var toolBarHeight = window.innerHeight * 0.2;
class Toolbar extends Component {
state = {
x: toolBarWidth / 4,
y: toolBarHeight / 4
};
render() {
return (
<Stage width={toolBarWidth} height={toolBarHeight} fill="red">
<Layer>
<Rect width={toolBarWidth} height={toolBarHeight} fill="blue" />
<Rect
x={this.state.x}
y={this.state.y}
width={toolBarWidth / 5}
height={toolBarWidth / 5}
fill="red"
draggable
onDragStart={() => {
console.log("hi");
}}
onDragEnd={() => {
this.setState({ x: toolBarWidth / 4, y: toolBarHeight / 4 });
this.forceUpdate();
}}
/>
</Layer>
</Stage>
);
}
}
export default Toolbar;
所以矩形的位置默认设置为state.x,state.x为toolBarWidth/4。然后在拖动结束时,我再次设置状态,我认为这会引发另一个渲染,但 React 仅在感知到更新时才渲染,因此再次将状态设置为相同的东西是行不通的,因此我做了 this.forceUpdate();这没有任何运气。有趣的是,如果我这样做 this.setState({1 + toolBarWidth/4...}) 它确实有效,当然只是第一次。
我觉得一定有一些 konva 方法可以设置元素的属性,但我找不到。我也尝试过 document.getElementId("the canva id") 和 document.getContext("canva element id") 但停止了,因为我找不到为我的 canva 定义 ID 的地方,因为它似乎写入 Stage 元素。
要使用内部 konva 方法,您必须为每个 Layer 和 Rectangle 定义 refs
<Layer ref="layer">
<Rectangle ref="rectangle">
并在 dragEnd 函数中使用 refs 将矩形的位置设置为
{x: 0, y: 0}
onDragEnd={() => {
var rectangle = this.refs.rectangle,
layer = this.refs.layer
rectangle.position({ x: 0, y: 0 });
layer.draw()
}}
您的最终 JSX 代码可能看起来像
<Stage width={400} height={400} fill="red">
<Layer ref="layer">
<Rect width={400} height={400} fill="blue" />
<Rect
ref="rectangle"
x={this.state.x}
y={this.state.y}
width={400 / 5}
height={400 / 5}
fill="red"
draggable
onDragStart={() => {
console.log("hi");
}}
onDragEnd={() => {
var rectangle = this.refs.rectangle,
layer = this.refs.layer
rectangle.position({ x: 0, y: 0 });
layer.draw()
}}
/>
</Layer>
</Stage>
还创建了一个代码沙箱供您参考
https://codesandbox.io/s/set-rectangle-back-to-original-position-on-drag-end-kg9bg
这是我尝试让 Rect 组件快速返回到其原始位置 (ReactKonva) 的尝试:
var toolBarWidth = window.innerWidth * 0.2;
var toolBarHeight = window.innerHeight * 0.2;
class Toolbar extends Component {
state = {
x: toolBarWidth / 4,
y: toolBarHeight / 4
};
render() {
return (
<Stage width={toolBarWidth} height={toolBarHeight} fill="red">
<Layer>
<Rect width={toolBarWidth} height={toolBarHeight} fill="blue" />
<Rect
x={this.state.x}
y={this.state.y}
width={toolBarWidth / 5}
height={toolBarWidth / 5}
fill="red"
draggable
onDragStart={() => {
console.log("hi");
}}
onDragEnd={() => {
this.setState({ x: toolBarWidth / 4, y: toolBarHeight / 4 });
this.forceUpdate();
}}
/>
</Layer>
</Stage>
);
}
}
export default Toolbar;
所以矩形的位置默认设置为state.x,state.x为toolBarWidth/4。然后在拖动结束时,我再次设置状态,我认为这会引发另一个渲染,但 React 仅在感知到更新时才渲染,因此再次将状态设置为相同的东西是行不通的,因此我做了 this.forceUpdate();这没有任何运气。有趣的是,如果我这样做 this.setState({1 + toolBarWidth/4...}) 它确实有效,当然只是第一次。
我觉得一定有一些 konva 方法可以设置元素的属性,但我找不到。我也尝试过 document.getElementId("the canva id") 和 document.getContext("canva element id") 但停止了,因为我找不到为我的 canva 定义 ID 的地方,因为它似乎写入 Stage 元素。
要使用内部 konva 方法,您必须为每个 Layer 和 Rectangle 定义 refs
<Layer ref="layer">
<Rectangle ref="rectangle">
并在 dragEnd 函数中使用 refs 将矩形的位置设置为
{x: 0, y: 0}
onDragEnd={() => {
var rectangle = this.refs.rectangle,
layer = this.refs.layer
rectangle.position({ x: 0, y: 0 });
layer.draw()
}}
您的最终 JSX 代码可能看起来像
<Stage width={400} height={400} fill="red">
<Layer ref="layer">
<Rect width={400} height={400} fill="blue" />
<Rect
ref="rectangle"
x={this.state.x}
y={this.state.y}
width={400 / 5}
height={400 / 5}
fill="red"
draggable
onDragStart={() => {
console.log("hi");
}}
onDragEnd={() => {
var rectangle = this.refs.rectangle,
layer = this.refs.layer
rectangle.position({ x: 0, y: 0 });
layer.draw()
}}
/>
</Layer>
</Stage>
还创建了一个代码沙箱供您参考 https://codesandbox.io/s/set-rectangle-back-to-original-position-on-drag-end-kg9bg