从中心缩放 konva 图像并在重绘时保持位置

scale konva image from the center and hold position on redraw

大家好,我有一个小问题,我有一个运行良好的 Konva.js 应用程序。我有一个名为 SET_STAGE_DATA 的函数,它应该将图像的当前位置保存在 canvas 上,以便在 canvas 消失时可以重新绘制。它有效,但是当您从左侧缩放图像时,图像会移动。我不确定如何解决这个问题。我以为我可以用偏移量来修复它,但没有用。

这是我的 SET_STAGE_DATA 函数

  [SET_STAGE_DATA](state){
    const isStage = state.stage;
    if(isStage){
    const groups = state.stage.find("Group");
    const stageData = [];
    for (let x = 0; x < groups.length; x++) {
      let g = groups[x];;
      let i = g.findOne("Image").getAttrs();
      let position = g.findOne("Image").position();
      console.log("this is position", position);
      let group = { x: g.getX(), y: g.getY() };
      let image = { x: i.width, y: i.height, position };
      let obj = { image, group };
      stageData.push(obj);
    }

我在像这样构建图像之前使用 stageData

  let groupPos; 
    let imagePos;
    if(state.stageData){
      console.log(true);
      for(let i =0; i<state.stageData.length; i++){
      imageObj.width = state.stageData[i].image.x;
      imageObj.height = state.stageData[i].image.y;
     imagePos = state.stageData[i].position;
      groupPos = state.stageData[i].group;
      }
    } else {
      groupPos = {
        x: state.stage.width() / 2 - imageObj.width / 2,
        y: state.stage.height() / 2 - imageObj.height / 2
      };
    }
    console.log("data", {groupPos, image: {width: imageObj.width, height: imageObj.height}});
    const image = new Konva.Image({
      image: imageObj,
      width: imageObj.width,
      height: imageObj.height,
      strokeWidth: 10,
      stroke: "blue",
      strokeEnabled: false
    });
    if(imagePos){
    image.position(imagePos)
    }
    const group = new Konva.Group({
      draggable: true,
      x: groupPos.x,
      y: groupPos.y
    });

我也有在文档中找到的典型更新功能:

  function update(activeAnchor) {
      const group = activeAnchor.getParent();

      let topLeft = group.get(".topLeft")[0];
      let topRight = group.get(".topRight")[0];
      let bottomRight = group.get(".bottomRight")[0];
      let bottomLeft = group.get(".bottomLeft")[0];
      let image = group.get("Image")[0];

      let anchorX = activeAnchor.getX();
      let anchorY = activeAnchor.getY();

      // update anchor positions
      switch (activeAnchor.getName()) {
        case "topLeft":
          topRight.y(anchorY);
          bottomLeft.x(anchorX);
          break;
        case "topRight":
          topLeft.y(anchorY);
          bottomRight.x(anchorX);
          break;
        case "bottomRight":
          bottomLeft.y(anchorY);
          topRight.x(anchorX);
          break;
        case "bottomLeft":
          bottomRight.y(anchorY);
          topLeft.x(anchorX);
          break;
      }
      // image.position(topLeft.position());
      let width = topRight.getX() - topLeft.getX();
      let height = bottomLeft.getY() - topLeft.getY();
      if (width && height) {
        image.width(width);
        image.height(height);
      }
    }
    function addAnchor(group, x, y, name) {
      let anchor = new Konva.Circle({
        x: x,
        y: y,
        stroke: "#666",
        fill: "#ddd",
        strokeWidth: 2,
        radius: 8,
        name: name,
        draggable: true,
        dragOnTop: false
      });
      anchor.on("dragmove", function() {
        update(this);
        state.layer.draw();
      });
      anchor.on("mousedown touchstart", function() {
        group.draggable(false);
        this.moveToTop();
      });
      anchor.on("dragend", function(evt) {
        group.draggable(true);
        commit(SET_STAGE_DATA);
        dispatch(UPDATE_ANIMATION, state.selectedNode);
        state.layer.draw();
      });
      // add hover styling
      anchor.on("mouseover", function() {
        document.body.style.cursor = "pointer";
        this.strokeWidth(4);
        state.layer.draw();
      });
      anchor.on("mouseout", function() {
        document.body.style.cursor = "default";
        this.strokeWidth(2);
        state.layer.draw();
      });

      group.add(anchor);
    }
    state.layer.draw();
  },

当我向左缩放时,图像在重绘时超出了锚点。我知道我可以在视觉上解决这个问题,只要我不通过执行 image.position(topLeft.position()); 重绘图像,正如您所看到的那样被注释掉了,但如果您从左侧拖动,它总是表现得好像没有设置定位一样。如果我从右下角开始缩放,一切都很好。它的作用就好像它回到了图像左上角的先前位置,但据我所知,使用 stage.find() 会给你当前的阶段。我完全不知所措。 在图像中查看它如何不留在盒子中。非常感谢这里的任何帮助。 [1]: https://i.stack.imgur.com/HEfHP.jpg

将 SET_STAGE_DATA 函数更新为如下所示

 [SET_STAGE_DATA](state){
    const isStage = state.stage;
    const isEditorMode = state.editorMode;
    if(isStage && !isEditorMode){
    const groups = state.stage.find("Group");
    const stageData = [];
    for (let x = 0; x < groups.length; x++) {
      let g = groups[x];
      let i = g.findOne("Image").getAttrs();
      let group = {x: g.getX() + i.x, y: g.getY() + i.y };
      let image = i;
      let obj = { image, group };
      stageData.push(obj);
    }
    state.stageData = stageData;
  } else {
    state.stageData = null;
  }
  }

group.x 和 y 不会按比例更新,但 image.x 和 y 会更新。在移动图像中,x 和 y 为 0,如果您将它们添加到 group.x 和 y,它将把锚点放在您需要的位置。