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

时间:2019-07-03 03:31:42

标签: konvajs

这是我的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)转移。

这是我尝试计算新位置的最合理的代码,以使对象降落在应该放置的位置。

  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;

1 个答案:

答案 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