缩放舞台和拖动元素的相对位置不起作用
Scale stage and drag element relative positions not working
我在 KonvaJS
React
中计算实时位置时遇到了小问题。在我的示例中,我有两个 Rect
的小(红色)位置是相对于大 Rect
(黄色)的,拖动大矩形时,小的相对于大的移动,但是当我向上或向下缩放时小的在x, y位置跳跃了一些像素。
import React from "react";
import ReactDOM from "react-dom";
import { Rect, Stage, Layer } from "react-konva";
import "./styles.css";
function Box({ attrs, draggable, updateAttr }) {
const onDragStart = e => {
const element = e.target;
if (typeof updateAttr === "function") {
updateAttr(element._lastPos);
}
};
const onDragMove = e => {
const element = e.target;
if (typeof updateAttr === "function") {
updateAttr(element._lastPos);
}
};
const onDragEnd = e => {
const element = e.target;
if (typeof updateAttr === "function") {
updateAttr(element._lastPos);
}
};
return (
<Rect
draggable={draggable}
onDragEnd={onDragEnd}
onDragMove={onDragMove}
onDragStart={onDragStart}
fill={attrs.fill}
x={attrs.x}
y={attrs.y}
width={attrs.width}
height={attrs.height}
/>
);
}
const calculatePos = ({ r1, r2 }) => ({
...r2,
x: parseInt(r1.width + r1.x + 10, 10),
y: parseInt(r1.y + r1.height / 2 - r2.height / 2, 10)
});
const boxAttr = {
x: 50,
y: 50,
width: 200,
height: 150,
fill: "yellow"
};
const secondAttr = calculatePos({
r2: {
fill: "red",
width: 20,
height: 20
},
r1: boxAttr
});
class App extends React.Component {
state = {
scale: 1,
boxAttr,
secondAttr
};
updateScale = scale => {
this.setState({ scale });
};
updateAttr = pos => {
const { secondAttr, boxAttr } = this.state;
this.setState({
secondAttr: calculatePos({
r2: secondAttr,
r1: { ...boxAttr, ...pos }
})
});
};
render() {
const { scale, boxAttr, secondAttr } = this.state;
return (
<div className="App">
<button
onClick={() => {
this.updateScale((parseFloat(scale) + 0.1).toFixed(1));
}}
>
+ Scale ({scale})
</button>
<button
onClick={() => {
this.updateScale((parseFloat(scale) - 0.1).toFixed(1));
}}
>
- Scale ({scale})
</button>
<Stage
scaleX={scale}
scaleY={scale}
width={window.innerWidth}
height={window.innerHeight}
>
<Layer>
<Box
updateAttr={this.updateAttr}
draggable={true}
attrs={boxAttr}
/>
<Box draggable={false} attrs={secondAttr} />
</Layer>
</Stage>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
请帮我更新红色矩形的正确 x,y。
I know Grouped Draggable solution will fix this issue, but I cannot
implement in my real application due to complex relations that cannot
be group for draggable reason
拖动第一个框时,您必须将 canvas 上的鼠标坐标转换为缩放后 canvas 内的坐标系才能移动第二个框。
我为此修改了 updateAttr 方法。
但是有一个问题,当 konva 本身调用 updateAttr 时(在 dragEnd 事件之后),它会使用转换后的坐标。这就是为什么我向名为 doScale 的 updateAttr 添加了第二个参数。自己调用时,设置为真,它会平移坐标,如果konva调用它,没有第二个参数,它的计算结果为假,不做平移。
我在 KonvaJS
React
中计算实时位置时遇到了小问题。在我的示例中,我有两个 Rect
的小(红色)位置是相对于大 Rect
(黄色)的,拖动大矩形时,小的相对于大的移动,但是当我向上或向下缩放时小的在x, y位置跳跃了一些像素。
import React from "react";
import ReactDOM from "react-dom";
import { Rect, Stage, Layer } from "react-konva";
import "./styles.css";
function Box({ attrs, draggable, updateAttr }) {
const onDragStart = e => {
const element = e.target;
if (typeof updateAttr === "function") {
updateAttr(element._lastPos);
}
};
const onDragMove = e => {
const element = e.target;
if (typeof updateAttr === "function") {
updateAttr(element._lastPos);
}
};
const onDragEnd = e => {
const element = e.target;
if (typeof updateAttr === "function") {
updateAttr(element._lastPos);
}
};
return (
<Rect
draggable={draggable}
onDragEnd={onDragEnd}
onDragMove={onDragMove}
onDragStart={onDragStart}
fill={attrs.fill}
x={attrs.x}
y={attrs.y}
width={attrs.width}
height={attrs.height}
/>
);
}
const calculatePos = ({ r1, r2 }) => ({
...r2,
x: parseInt(r1.width + r1.x + 10, 10),
y: parseInt(r1.y + r1.height / 2 - r2.height / 2, 10)
});
const boxAttr = {
x: 50,
y: 50,
width: 200,
height: 150,
fill: "yellow"
};
const secondAttr = calculatePos({
r2: {
fill: "red",
width: 20,
height: 20
},
r1: boxAttr
});
class App extends React.Component {
state = {
scale: 1,
boxAttr,
secondAttr
};
updateScale = scale => {
this.setState({ scale });
};
updateAttr = pos => {
const { secondAttr, boxAttr } = this.state;
this.setState({
secondAttr: calculatePos({
r2: secondAttr,
r1: { ...boxAttr, ...pos }
})
});
};
render() {
const { scale, boxAttr, secondAttr } = this.state;
return (
<div className="App">
<button
onClick={() => {
this.updateScale((parseFloat(scale) + 0.1).toFixed(1));
}}
>
+ Scale ({scale})
</button>
<button
onClick={() => {
this.updateScale((parseFloat(scale) - 0.1).toFixed(1));
}}
>
- Scale ({scale})
</button>
<Stage
scaleX={scale}
scaleY={scale}
width={window.innerWidth}
height={window.innerHeight}
>
<Layer>
<Box
updateAttr={this.updateAttr}
draggable={true}
attrs={boxAttr}
/>
<Box draggable={false} attrs={secondAttr} />
</Layer>
</Stage>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
请帮我更新红色矩形的正确 x,y。
I know Grouped Draggable solution will fix this issue, but I cannot implement in my real application due to complex relations that cannot be group for draggable reason
拖动第一个框时,您必须将 canvas 上的鼠标坐标转换为缩放后 canvas 内的坐标系才能移动第二个框。
我为此修改了 updateAttr 方法。
但是有一个问题,当 konva 本身调用 updateAttr 时(在 dragEnd 事件之后),它会使用转换后的坐标。这就是为什么我向名为 doScale 的 updateAttr 添加了第二个参数。自己调用时,设置为真,它会平移坐标,如果konva调用它,没有第二个参数,它的计算结果为假,不做平移。