【问题标题】:scale konva image from the center and hold position on redraw从中心缩放 konva 图像并在重绘时保持位置
【发布时间】:2020-11-13 01:24:56
【问题描述】:

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

这是我的 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

【问题讨论】:

  • 代码太大,看不懂怎么回事。请尝试创建尽可能小的演示。

标签: positioning konvajs


【解决方案1】:

将 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 中,它会将锚点放在您需要它们的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 2015-01-21
    相关资源
    最近更新 更多