KonvaJS:如何根据当前鼠标位置获取缩放和移动图层的位置?

KonvaJS: How to get a scaled & moved layer's position based on current mouse position?

这是我的 Konva 对象设计:包含两层的一个阶段。一层是我从中拖放形状的工具栏,一层是 canvas,我将元素放入其中。canvas 层可以放大和缩小并且是可拖动的(实现了相对缩放功能来自 lavtron 的演示 https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.html)。

当用户从工具栏上放下一个形状时,一个新形状会添加到 canvas 层,并且应该与用户注视它的位置相同。所以在我把放大放到我的程序之前,唯一关心的是根据层的偏移量修改位置: 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) 移动。

这是我尝试计算新位置以使物体降落在它们应该掉落的位置的最合理的代码。

  1. 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;

您可以使用此演示计算相对位置: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