konva icon indicating copy to clipboard operation
konva copied to clipboard

After the element is rotated or scaled by transformer, the element cannot be rotated around the center manually

Open wyyx50 opened this issue 2 years ago • 2 comments

There is an element in the canvas. Each time I click the button, I want it to rotate 90 degrees around its center point. So when I judge that the origin of this element is not at the center point, I will manually specify its origin to the center point. When I do not use the transformer to rotate or scale it, it works well and can rotate around the center point.However, when I rotate or scale this element through transformer, and then click the button to rotate it, its position is offset, and it can rotate around the center point if I continue to click it. I want it to always rotate 90 degrees around the center point,But I don't know how to solve it. The code is as follows

<button @click="rotate">rotate</button>

let stage = new Konva.Stage({
	container: container,
	width: 800,
	height: 800,
});

let layer = new Konva.Layer();
stage.add(layer);

let rect = new Konva.Rect({
	x:50,
	y:50,
	width: 200,
	height: 150
});
layer.add(rect);

let transformer = new Konva.Transformer({
	rotationSnaps: [0, 90, 180, 270],
	nodes:[rect]
});
layer.add(transformer);

function rotate(){
	if(!rect.attrs.offsetX){
		rect.setAttrs({
			offsetX:rect.attrs.width/2,
			offsetY:rect.attrs.height/2,
			x:rect.attrs.x + rect.attrs.width/2,
			y:rect.attrs.y + rect.attrs.height/2
		})
	}
	rect.rotate(90);
}

wyyx50 avatar Sep 15 '22 13:09 wyyx50

Doing math when you have all offset, scale and rotation on a node is very hard. Instead you may avoid using offset it rotate around center using math. See example here https://konvajs.org/docs/posts/Position_vs_Offset.html. Just need to apply scale in rotateAroundCenter sample

lavrton avatar Sep 16 '22 17:09 lavrton

Doing math when you have all offset, scale and rotation on a node is very hard. Instead you may avoid using offset it rotate around center using math. See example here https://konvajs.org/docs/posts/Position_vs_Offset.html. Just need to apply scale in rotateAroundCenter sample

Thank you. This method is really useful, but there is still a small problem after scaling. It does not rotate around the center. I think scaling causes the difference between the calculated x and y in multiples, so I try to multiply the calculated x and y by the scaling multiple, and then it can always rotate around the center. I didn't look at Konva's source code in depth, but I found that after using the transformer to rotate the node, its offset was not changed. I think Konva's transformer uses the same method as you said.

function rotateAroundCenter(node, rotate) {
	const topLeft = { x: -node.width() / 2, y: -node.height() / 2 };
	const current = rotatePoint(topLeft, Konva.getAngle(node.rotation()));
	const rotated = rotatePoint(topLeft, Konva.getAngle(node.rotation()+rotate));
	const dx = rotated.x - current.x,dy = rotated.y - current.y;
	let scaleX = node.scaleX()||1;
	let scaleY = node.scaleY()||1;
	node.rotate(rotate);
	node.x(node.x() + dx*scaleX);
	node.y(node.y() + dy*scaleY);
}

wyyx50 avatar Sep 17 '22 01:09 wyyx50

兄弟,回复你的那个是作者本人

Mt-Youya avatar Oct 10 '23 07:10 Mt-Youya