2
votes

I have a problem with keeping same transform of display object when re-parenting from one hierarchy to another. In image below you can see movie clip "mc1" that has nested child "mc2". "mc2" has its own child "mc3" and so on. Each descendant is somehow transformed (rotation, scale, etc..). I want to take "mc4" from hierarchy "mc1" and put inside on "do3" of hierarchy "do1" (that also has different transformations in each level).

So how do I put square "mc4" without changing it's appearance (except location) into other hierarchy? (Imagine drag and drop).

I tried doing it with Transform.concatenedMatrix property but I got lost.

Thanks!

nested movie clips

2

2 Answers

3
votes

After few experiments I found right answer myself:

    import flash.display.DisplayObject;
    import flash.display.DisplayObjectContainer;
    import flash.geom.Matrix; 


function changeParent ( displayObject : DisplayObject, newParent : DisplayObjectContainer, depth : int = -1 ) : void {

    var concatenedChildMatrix       : Matrix = displayObject.transform.concatenatedMatrix;

    var concatenedNewParentMatrix   : Matrix = newParent.transform.concatenatedMatrix;

    // invert matrix. It couses visual removal of transformations (movie clip looks like it wasn't transformed )
    concatenedNewParentMatrix.invert();

    concatenedChildMatrix.concat( concatenedNewParentMatrix );

    // if you want to add clip not on top level
    if ( depth >= 0 ) {
        newParent.addChildAt( displayObject, depth );
    } else {
        newParent.addChild( displayObject );
    }

    // assign matrix back
    displayObject.transform.matrix = concatenedChildMatrix;

}       
1
votes

You could try this, it works for my situations (when all you do is modify scale/x/y/rotation properties), but may not work properly when using transformation matrices.

function changeParent(displayObj:DisplayObject, newParent:DisplayObjectContainer, depth:Number = -1, retainRelativeSize:Boolean = false):void {
var tmpParent:DisplayObjectContainer = displayObj.parent;

    while (tmpParent) {
        displayObj.scaleX *= tmpParent.scaleX;
        displayObj.scaleY *= tmpParent.scaleY;
        displayObj.rotation += tmpParent.rotation;
        tmpParent = tmpParent.parent;
    }

    tmpParent = newParent;
    while(tmpParent){
        displayObj.scaleX = displayObj.scaleX / tmpParent.scaleX;
        displayObj.scaleY = displayObj.scaleX / tmpParent.scaleY;
        displayObj.rotation -= tmpParent.rotation;
        tmpParent = tmpParent.parent;
    }

    var point1:Point= displayObj.localToGlobal(new Point());
    var point2:Point = newParent.globalToLocal(point1);

    if (depth >= 0) {
        newParent.addChildAt(displayObj, depth);
    }else {
        newParent.addChild(displayObj);
    }

    displayObj.x = point2.x;
    displayObj.y = point2.y;

}