开发者

Why does Flex's Matrix Transform Snap Child Back to Top Corner of Parent?

开发者 https://www.devze.com 2023-02-25 02:34 出处:网络
I\'m having trouble with Matrix Transforms in Flex. I have a Flex Canvas with nothing but an Image in it, like so.

I'm having trouble with Matrix Transforms in Flex.

I have a Flex Canvas with nothing but an Image in it, like so.

<mx:Canvas>
 <mx:Image id="img" source="/some/Url" />
</mx:Canvas>

To this image I am applying zoom/rotation transforms using开发者_C百科 code like this:

private function _rotateAndZoomImage(zoom:Number, angle:Number):void{
 var radians:Number = angle * (Math.PI / 180.0);
 var offsetWidth:Number = ( img.contentWidth/2.0 );
 var offsetHeight:Number = (  img.contentHeight/2.0 );
 var matrix:Matrix = new Matrix();

 matrix.translate(-offsetWidth, -offsetHeight);
 matrix.rotate(radians);
 //Do the zoom
 matrix.scale (zoom/100, zoom/100);
 matrix.translate(+offsetWidth, +offsetHeight);
 img.transform.matrix = matrix;
}

This all works. BUT. The image is draggable. The user can move it anywhere inside the canvas that is it's parent.

Once the image has been moved and the transform is applied the image gets "snapped" back to the original 0,0 (top left of the canvas) location before being transformed and is left there afterwards - not where the user would expect it to be.

After messing about with this for the best part of a day I still can't work out why on earth it's doing this. Anybody?

Edit: Note that the same happens without the two calls to .translate() in the above code. So the following code also snaps the image back to 0,0 of the canvas after it has been moved:

private function _rotateAndZoomImage(zoom:Number, angle:Number):void{
 var radians:Number = angle * (Math.PI / 180.0);

 var matrix:Matrix = new Matrix();
 matrix.rotate(radians);
 matrix.scale (zoom/100, zoom/100);
 img.transform.matrix = matrix;
}

Jake


Here is how I fixed it. I overrode the 'move' function in my Image class, called super.move(), and then reset the transform matrix to the value I originally set it to (in this case _affineTransform).

    override public function move(x:Number, y:Number):void
    {
        super.move(x,y);
        this.transform.matrix = _affineTransform;
    }

Hacky, but watcha gonna do...if someone has a cleaner solution, please let me know!


If you look in the source code for the set x() override in mx.core.UIComponent, you'll see the following line:

 _layoutFeatures.layoutX = value

Basically, it ignores the default display list x value and stores the position elsewhere. The real x is probably set later once the full layout has been processed (replacing your translation value). You should probably always use x, y, scaleX, scaleY, rotation and any other relevant properties. It seems that Adobe doesn't intend for Flex to support the regular display object transform matrix.


I think you may have to add the x,y values to your translation:

private function _rotateAndZoomImage(zoom:Number, angle:Number):void{
 var radians:Number = angle * (Math.PI / 180.0);
 var offsetWidth:Number = ( img.contentWidth/2.0 );
 var offsetHeight:Number = (  img.contentHeight/2.0 );
 var matrix:Matrix = new Matrix();

 matrix.translate(-offsetWidth, -offsetHeight);
 matrix.rotate(radians);
 //Do the zoom
 matrix.scale (zoom/100, zoom/100);
 matrix.translate(img.x + offsetWidth, img.y + offsetHeight);
 img.transform.matrix = matrix;
}


try setting this.

matrix.tx
matrix.ty


The solution/workaround to this is quite simple. Instead of this:

<mx:Canvas>
 <mx:Image id="img" source="/some/Url" mouseDown="img.startDrag()" />
</mx:Canvas>

I now have this:

<mx:Canvas>
 <mx:Canvas id="inner" mouseDown="inner.startDrag()" clipContent="false">
  <mx:Image id="img" source="/some/Url" />
 </mx:Canvas>
</mx:Canvas>

The draggable image no longer lives directly inside the main Canvas. Instead it lives inside a child Canvas. The image is no longer draggable itself. It's the inner Canvas that gets dragged.

Now, when a transformation is applied to the image, it stays put as its parent's 0,0 coords are now where they're supposed to be, as it's where you dragged the canvas to.

Hope this helps somebody and saves them the time I've wasted on this. Jake

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号