【问题标题】:Place node centred on rotated note以旋转音符为中心放置节点
【发布时间】:2021-06-24 15:31:59
【问题描述】:

我有以下示例阶段。

const rectangle = new Konva.Rect({
  width: 300,
  height: 100,
  x: stage.width() / 2,
  y: stage.height() / 2,
  fill: 'blue',
  rotation: 140
});
layer.add(rectangle);
layer.draw();


const tooltip = new Konva.Label({
  x: rectangle.x() + (rectangle.width() / 2),
  y: rectangle.y() + (rectangle.height() / 2),
  opacity: 0.75
});
tooltip.add(
  new Konva.Tag({
    fill: 'green',
    pointerDirection: 'down',
    pointerWidth: 6,
    pointerHeight: 4,
    lineJoin: 'round'
  })
);
tooltip.add(new Konva.Text({
  text: 'Hello world',
  fontSize: 12,
  padding: 5,
  fill: 'white',
}));
layer.add(tooltip);
layer.draw();

当矩形没有旋转时,我可以将工具提示正确地放置在节点的中心。当矩形有一些旋转时,工具提示不再居中。

在不改变矩形属性或旋转tooltip的情况下,如何将tooltip放在矩形节点的中心?

JSBIN 示例:

https://jsbin.com/wopoxuligi/edit?html,js,output

【问题讨论】:

    标签: javascript konvajs konva


    【解决方案1】:

    首先,您需要在 html 脚本标签中更新您对 Konva 的声明,因为您引用的是旧版本。

    <script src="https://unpkg.com/konva@7.0.3/konva.min.js"></script>
    

    因为这个形状是一个矩形,你可以调用 rectangle.getClientRect() 来获取舞台上的位置,然后使用简单的中心数学来放置你的标签。将此代码插入当前代码的最后一个 layer.draw();

    const cliRect = rectangle.getClientRect();
    let pos = {
            x: cliRect.x + (cliRect.width )/2,
            y: cliRect.y + (cliRect.height )/2
    };
    tooltip.x(pos.x)
    tooltip.y(pos.y)
    layer.draw();
    

    这将使标签的指针指向旋转矩形的中心,而标签不旋转。在下面工作 sn-p - 全屏运行。

    const stage = new Konva.Stage({
      container: 'container',
      width: window.innerWidth,
      height: window.innerHeight,
      draggable: true
    });
    
    const layer = new Konva.Layer();
    stage.add(layer);
    
    const rectangle = new Konva.Rect({
      width: 300,
      height: 100,
      x: stage.width() / 2,
      y: stage.height() / 2,
      fill: 'blue',
      rotation: 140
    });
    layer.add(rectangle);
    layer.draw();
     
    const tooltip = new Konva.Label({
      x: rectangle.x() + (rectangle.width() / 2),
      y: rectangle.y() + (rectangle.height() / 2),
      opacity: 0.75
    });
     
    tooltip.add(
      new Konva.Tag({
        fill: 'green',
        pointerDirection: 'down',
        pointerWidth: 6,
        pointerHeight: 4,
        lineJoin: 'round'
      })
    );
    tooltip.add(new Konva.Text({
      text: 'Hello world',
      fontSize: 12,
      padding: 5,
      fill: 'white',
    }));
    layer.add(tooltip);
    
    
    const cliRect = rectangle.getClientRect();
    // Extra red rect to illustrate client rect. Not needed in solution
    const rectangle1 = new Konva.Rect({
      width: cliRect.width,
      height: cliRect.height,
      x: cliRect.x,
      y: cliRect.y,
      stroke: 'red'
    });
    layer.add(rectangle1);
    
    
    let pos = {
            x: cliRect.x + (cliRect.width )/2,
            y: cliRect.y + (cliRect.height )/2
    };
     
    // Set tooltip position taking account of stage draggind
    tooltip.x(pos.x - stage.x())
    tooltip.y(pos.y - stage.y())  
    
    console.log(pos)
    
    
    
    layer.draw();
    <script src="https://unpkg.com/konva@7.0.3/konva.min.js"></script>
      <div id="container"></div>

    编辑:在评论中,OP 指出,真正的用例要求舞台在添加标签之前是可拖动的,并且在拖动之后标签位置的计算失败。这是因为 getClientRect() 给出了客户端容器中的位置,而无需针对舞台移动进行调整。要使代码与拖动的舞台一起工作,请将设置 tooltip.x & y 的两行更改为通过 stage.x & y 进行调整,如下所示:

    tooltip.x(pos.x - stage.x())
    tooltip.y(pos.y - stage.y())  
    

    【讨论】:

    • 感谢这项工作!但是我在实际用例中遇到了限制。舞台是可拖动的。只要您移动舞台,然后添加工具提示,它就不在正确的位置。我已经用“添加工具提示”按钮jsbin.com/vabutomoqo/edit?html,js,output 更新了示例
    【解决方案2】:

    我为矩形添加了偏移量,使其按中心点旋转,并设法使工具提示居中。

    const stage = new Konva.Stage({
      container: 'container',
      width: window.innerWidth,
      height: window.innerHeight
    });
    
    const layer = new Konva.Layer();
    stage.add(layer);
    
    var group1 = new Konva.Group({
      draggable: true
    });
    const rectWidth = 300;
    const rectHeight = 100;
    
    const rectangle = new Konva.Rect({
      width: rectWidth,
      height: rectHeight,
      x: stage.width() / 2,
      y: stage.height() / 2,
      fill: 'blue',
      rotation: 140,
      offset: {
        x: rectWidth / 2,
        y: rectHeight / 2,
      },
    });
    
    const tooltip = new Konva.Label({
      x: rectangle.x() + (rectangle.width() / 2),
      y: rectangle.y() + (rectangle.height() / 2),
      offset: {
        x: rectangle.width() / 2,
        y: rectangle.height() / 2,
      },
      opacity: 0.75
    });
    tooltip.add(
      new Konva.Tag({
        fill: 'green',
        pointerDirection: 'down',
        pointerWidth: 6,
        pointerHeight: 4,
        lineJoin: 'round'
      })
    );
    tooltip.add(new Konva.Text({
      text: 'Hello world',
      fontSize: 12,
      padding: 5,
      fill: 'white',
    }));
    
    layer.add(rectangle);
    layer.add(tooltip);
    layer.draw();
    <script src="https://unpkg.com/konva@^2/konva.min.js"></script>
    
    <div id="container"></div>

    【讨论】:

    • 一个有价值的解决方案,尽管更改偏移量可能会在以后的代码中导致一些意想不到的后果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 2014-10-05
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多