Best way to set position of a node to another node?

Suppose I have nodeA & node B with paths:

Canvas/parentA/nodeA
Canvas/parentB/nodeB

The way I used to make nodeA to be positioned exactly at position of nodeB currently is
(making nodeA overlap & hide nodeB under)

var canvas = cc.find('Canvas');
var posAGlobal = canvas.convertToNodeSpaceAR( nodeA.convertToWorldSpaceAR( cc.v2() ) );
var posBGlobal = canvas.convertToNodeSpaceAR( nodeB.convertToWorldSpaceAR( cc.v2() ) );
var positionDiffGlobal = posBGlobal.sub( posAGlobal );

var posALocal = nodeA.getPosition();
nodeA.setPositon( posALocal.add( positionDiffGlobal  ) );

As you can see, my code looks so long and use an intermediate node as “canvas”, which is not kind of convenient.

Besides, I found out that node.convertToWorldSpaceAR() will give me wrong result if scale of parentA or parentB is not equal to 1. Or maybe, anchor point of parentA, parentB could spoil the result.

So, could any one give me a right way to achieve this?
Thanks in advance.

1 Like

Same problem here. Anyone know a better way to do this?

I was having the same issue, when I was trying to attach a node to a different parent node, all the transformation were changed due to different parents’ matrices.

So I wrote a method to switch a node’s parent to another without changing the visual position/scale/rotation. Here it is:

function switchParent(node, newParent) {
	let localPos = (node.parent || node).convertToWorldSpaceAR(node.getPosition());
	let worldPos = newParent.convertToNodeSpaceAR(localPos);

	let rotationAttr = typeof node.rotation === 'undefined' ? 'angle' : 'rotation';
	let localScaleX = 1;
	let localScaleY = 1;
	let localAngleX = 0;
	let localAngleY = 0;
	for (let parent = node; parent; parent = parent.parent) {
		localScaleX *= parent.scaleX;
		localScaleY *= parent.scaleY;
		localAngleX += parent[rotationAttr + 'X'];
		localAngleY += parent[rotationAttr + 'Y'];
	}

	let worldScaleX = 1;
	let worldScaleY = 1;
	let worldAngleX = 0;
	let worldAngleY = 0;
	for (let parent = newParent; parent; parent = parent.parent) {
		worldScaleX /= parent.scaleX;
		worldScaleY /= parent.scaleY;
		worldAngleX -= parent[rotationAttr + 'X'];
		worldAngleY -= parent[rotationAttr + 'Y'];
	}

	node.setParent(newParent);
	node[rotationAttr + 'X'] = localAngleX + worldAngleX;
	node[rotationAttr + 'Y'] = localAngleY + worldAngleY;
	node.setScale(localScaleX * worldScaleX, localScaleY * worldScaleY);
	node.setPosition(worldPos);
}

So theoretically if you use this method to switch the parent of nodeA to parentB , and then set its transform identical to nodeB, then switch back should do the trick. Like this:

switchParent(nodeA, parentB);
nodeA.x = nodeB.x;
nodeA.y = nodeB.y;
switchParent(nodeA, parentA);
1 Like

OMG
I can not imagine you’ve gone this far
I’d try your function but thank you so much !