Konva 中 position 与 offset 的区别
Konva 中有几个属性看起来相似,可能引起混淆,但它们的作用和用途不同。
本文介绍 position(x 和 y 坐标)与 offset(offsetX 和 offsetY)之间的区别。
x 和 y 属性定义节点在 Canvas 上的位置。如果设置 draggable = true 属性并开始拖动,Konva 会更改节点的 x 和 y 属性。此逻辑适用于所有节点,包括 Konva.Line。
矩形图形的位置定义其左上角点。圆形的位置定义其中心。
为什么需要 offset 属性?
更改 offset 属性时,看起来可能像是在更改节点的位置,但实际并非如此。你更改的是图形的原点。
什么是原点?可以将其理解为“开始绘制图形的点”“图形的中心”或“图形旋转时围绕的点”。
补充说明:很久以前,在 Konva 还是 KineticJS 项目时,代码库中的 offset 属性称为“center”。后来,它被重构为“offset”。
查看此示例。这里的所有矩形都有相同的 y 位置,但 offset 属性不同。
需要注意,Konva 主要使用两种方式定义图形的原点。
“类似圆形”的图形以实际中心作为原点,例如 Circle、Ellipse、Wedge、Star 和 Ring 等。
设置圆形的 {x, y} 时,定义的是“圆心的位置”。
“类似矩形”的图形以左上角作为原点,例如 Rectangle、Sprite、Text 和 Image 等。
设置矩形的 {x, y} 时,定义的是“矩形左上角点的位置”。
图形会围绕其原点(即其“中心”)旋转。因此,如果将星形的旋转角度设置为 45 度,它会围绕实际中心旋转。
但是,如果将矩形的旋转角度设置为 45 度,它会围绕左上角旋转。在某些情况下,这并不方便。你可能希望图形围绕其中心旋转。
在这种情况下,可以设置 offset 属性。该属性会告诉 Konva:“使用此点作为图形的新原点”。
如何设置图形的旋转点?
假设在 x = 0, y = 0 处放置了一个 100x100 的矩形,现在想让它围绕中心旋转。
如果不使用 offset,就必须重新计算矩形左上角的位置(回想一下学校学过的三角函数)。
可以使用类似以下的代码:
const rotatePoint = ({ x, y }, rad) => {
const rcos = Math.cos(rad);
const rsin = Math.sin(rad);
return { x: x * rcos - y * rsin, y: y * rcos + x * rsin };
};
// will work for shapes with top-left origin, like rectangle
function rotateAroundCenter(node, rotation) {
//current rotation origin (0, 0) relative to desired origin - center (node.width()/2, node.height()/2)
const topLeft = { x: -node.width() / 2, y: -node.height() / 2 };
const current = rotatePoint(topLeft, Konva.getAngle(node.rotation()));
const rotated = rotatePoint(topLeft, Konva.getAngle(rotation));
const dx = rotated.x - current.x,
dy = rotated.y - current.y;
node.rotation(rotation);
node.x(node.x() + dx);
node.y(node.y() + dy);
}
// then use it
rotateAroundCenter(rect, 180);
也可以设置 offsetX = width / 2 和 offsetY = height / 2。但是,矩形会在 Canvas 上移动,因为其原点发生了变化。因此,还需要调整位置。
仍有疑问?请在评论中提问。