SceneNode.moveTo method relative to parent node

The question title says, “SceneNode.moveTo method relative to parent node” and it is about that but also it could have been written, “SceneNode.moveTo method relative to a parent node”:

You could pass in another node and it would calculate the position relative to the node supplied.

So you would say I want to position this rectangle at 10 x 10 in the artboard it is in and it’s the 10th artboard. You would write, element.moveTo(10, 10, element.artboard).

Or if it is grouped and it is nested in 10 groups you would write, element.moveTo(10, 10, element.parent) and it would be at 10 x 10 in the direct parent not the artboard.

If you left the third parameter out it would be positioned in the direct parent, not parent artboard, of the element.

Here is what I’m using now that positions an element in it’s direct parent. It uses the top left x and y position as the registration point.

function moveTo(element, x, y) {
    var bounds = getBoundsInParent(element);
    element.moveInParentCoordinates(-bounds.x+x, -bounds.y+y);
}

function getArtboard(item) {

    if (item instanceof Artboard) return item;
    var parent = item.parent;
    while (parent!=null) {
        if (parent instanceof Artboard) return parent;
        parent = parent.parent;
    }
}

function getBoundsInParent(item) {
    var bounds = {};
    var x = 0;
    var y = 0;
    var parentX = 0;
    var parentY = 0;
    var parentWidth= 0;
    var parentHeight = 0;
    var width= 0;
    var height = 0;
    var offsetX = 0;
    var offsetY = 0;
    var centerX = 0;
    var centerY = 0;
    var centerDeltaX = 0;
    var centerDeltaY = 0;
    var globalCenterX = 0;
    var globalCenterY = 0;
    var globalDeltaX = 0;
    var globalDeltaY = 0;
    var isLine = getType(item)==item.Line; // or use item instanceof Line
    var sizeAdjusted = false;
    var artboard = null;
    var xInArtboard = 0;
    var yInArtboard = 0;
    var parentXInArtboard = 0;
    var parentYInArtboard = 0;
    var parent = null;

    if (item.parent) {
        artboard = getArtboard(item);
        parent = item.parent;

        x = item.globalBounds.x;
        y = item.globalBounds.y;
        width = item.globalBounds.width;
        height = item.globalBounds.height;
        xInArtboard = artboard ? item.globalBounds.x - artboard.globalBounds.x : 0;
        yInArtboard = artboard ? item.globalBounds.y - artboard.globalBounds.y : 0;

        parentXInArtboard = artboard ? parent.globalBounds.x - artboard.globalBounds.x : 0;
        parentYInArtboard = artboard ? parent.globalBounds.y - artboard.globalBounds.y : 0;

        if (isLine && width==0) {
            width = item.strokeWidth;
            sizeAdjusted = true;
        }
        
        if (isLine && height==0) {
            height = item.strokeHeight;
            sizeAdjusted = true;
        }

        parentX = parent.globalBounds.x;
        parentY = parent.globalBounds.y;
        parentWidth = parent.globalBounds.width;
        parentHeight = parent.globalBounds.height;

        // center cartisian position
        centerX = parentWidth/2 - width/2;
        centerY = parentHeight/2 - height/2;

        offsetX = x - parentX;
        offsetY = y - parentY;
        
        globalCenterX = parentX + centerX;
        globalCenterY = parentY + centerY;
        
        centerDeltaX = centerX - offsetX;
        centerDeltaY = centerY - offsetY;
        
        globalDeltaX = x + centerDeltaX;
        globalDeltaY = y - centerDeltaY;

        bounds.xInArtboard = xInArtboard;
        bounds.yInArtboard = yInArtboard;

        bounds.parentXInArtboard = parentXInArtboard;
        bounds.parentYInArtboard = parentYInArtboard;

        bounds.x = offsetX;
        bounds.y = offsetY;

        bounds.globalX = item.globalBounds.x;
        bounds.globalY = item.globalBounds.y;

        bounds.xInGroup = offsetX;
        bounds.yInGroup = offsetY;
        
        bounds.centerX = centerX;
        bounds.centerY = centerY;
        
        bounds.width = item.globalBounds.width;
        bounds.height = item.globalBounds.height;

        bounds.centerDeltaX = centerDeltaX;
        bounds.centerDeltaY = centerDeltaY;

        bounds.globalDeltaX = globalDeltaX;
        bounds.globalDeltaY = globalDeltaY;

        bounds.globalCenterX = globalCenterX;
        bounds.globalCenterY = globalCenterY;

        bounds.sizeAdjusted = sizeAdjusted;

        bounds.computedCenterX = getCenterPoint(item).x;
        bounds.computedCenterY = getCenterPoint(item).y;

        bounds.parentWidth = parentWidth;
        bounds.parentHeight = parentHeight;

        bounds.parentX = parentX;
        bounds.parentY = parentY;

        bounds.offsetX = offsetX;
        bounds.offsetY = offsetY;
    }

    return bounds;
}


/**
 * 
 * @param {SceneNode} node 
 */
function getType(node) {
	var type = node && node.constructor && node.constructor.name;

	switch(type) {
	 
		case Types.ELLIPSE:
		   break;
		case Types.RECTANGLE:
		   break;
		case Types.PATH:
		   break;
		case Types.LINE:
		   break;
		case Types.TEXT:
		   break;
		case Types.GROUP:
		   break;
		case Types.BOOLEAN_GROUP:
		   break;
		case Types.REPEAT_GRID:
		   break;
		case Types.SYMBOL_INSTANCE:
		   break;
		case Types.ARTBOARD:
		   break;
		default:
	}

	return type;

}

function getCenterPoint(node) {
	return {
		x: node.boundsInParent.x + node.boundsInParent.width/2,
		y: node.boundsInParent.y + node.boundsInParent.height/2
	}
}

The getBoundsInParent adds additional properties most have been validated but if you use this a few values you may want to verify the values are correct.