这是我的Konva对象设计:一个阶段包括两层。一层是我从中拖放形状的工具栏,一层是我将元素拖放到其中的画布。该画布层可以放大和缩小并且可以拖动(从lavtron的演示https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.html实现的相对缩放功能)。
当用户从工具栏上放下一个形状时,新形状将添加到画布层,并且应该与用户注视它的位置相同。因此,在放大程序之前,唯一需要考虑的是根据图层的偏移量来修改位置,方法是:
toPush.x = toPush.x - this.refs.layer2.attrs.x; //toPush.x = Stage mouseX position
toPush.y = toPush.y - this.refs.layer2.attrs.y; //toPush.y = Stage mouseY position
我使用基于鼠标位置的lavtron缩放功能来缩放和移动图层,以达到效果。
我的反应代码如下:
<Stage ...>
<Layer onWheel={this.onWheel} x={this.state.layerX} y={this.state.layerY} >
... all the shapes...
</Layer>
</Stage>
onWheel = () => {
const scaleBy = 1.1;
const stage = this.refs.graphicStage;
const layer = this.refs.layer2;
const oldScale = layer.scaleX();
const mousePointTo = {
x: stage.getPointerPosition().x / oldScale - this.state.layerX / oldScale,
y: stage.getPointerPosition().y / oldScale - this.state.layerY / oldScale
};
const newScale =
event.evt.deltaY < 0 ? oldScale * scaleBy : oldScale / scaleBy;
layer.scale({ x: newScale, y: newScale });
this.setState({
layerScale: newScale,
layerX:
-(mousePointTo.x - stage.getPointerPosition().x / newScale) * newScale,
layerY:
-(mousePointTo.y - stage.getPointerPosition().y / newScale) * newScale
});
}
但是在执行缩放之后,当我拖放形状时,它们不会落在我眼球所盯的位置,有趣的是,随着我放下形状的位置离(x:0,y:0)越来越远,他们将朝(0,0)转移。
这是我尝试计算新位置的最合理的代码,以使对象降落在应该放置的位置。
toPush.x = toPush.x - this.state.layerX; //this.state.layerX = layer's X offset
toPush.y = toPush.y - this.state.layerY;
2。
toPush.x = toPush.x - (this.state.layerX) * layer's scale;
toPush.y = toPush.y - this.state.layerY * layer's scale;
答案 0 :(得分:1)
您可以使用此演示计算相对位置:https://konvajs.org/docs/sandbox/Relative_Pointer_Position.html
使用react-konva
可能看起来像这样:
import React from "react";
import { render } from "react-dom";
import { Stage, Layer, Circle } from "react-konva";
const App = () => {
const [localPos, setPos] = React.useState({ x: 0, y: 0 });
const layerRef = React.useRef();
return (
<React.Fragment>
Try to move the mouse over stage
<Stage
width={window.innerWidth}
height={window.innerHeight}
onMouseMove={e => {
var transform = layerRef.current.getAbsoluteTransform().copy();
// to detect relative position we need to invert transform
transform.invert();
// now we find relative point
const pos = e.target.getStage().getPointerPosition();
var circlePos = transform.point(pos);
setPos(circlePos);
}}
>
<Layer x={50} y={50} scaleX={0.5} scaleY={2} ref={layerRef}>
<Circle radius={50} fill="green" x={localPos.x} y={localPos.y} />
</Layer>
</Stage>
</React.Fragment>
);
};
render(<App />, document.getElementById("root"));
https://codesandbox.io/s/react-konva-relative-pos-demo-k6num