1

我有以下示例阶段。

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();

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

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

JSBIN 示例:

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

4

2 回答 2

2

首先,当您引用旧版本时,您需要在 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();

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

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())  
于 2021-03-28T10:39:14.427 回答
0

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

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>

于 2021-03-28T10:26:16.467 回答