为什么Flex的Matrix变换捕捉孩子回到父母的顶角?

时间:2011-04-14 18:42:54

标签: flex matrix transform

我在Flex中使用Matrix变换时遇到了麻烦。

我有一个Flex Canvas,只有一个图像,就像这样。

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

对于此图像,我使用以下代码应用缩放/旋转变换:

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;
}

这一切都有效。但。图像是可拖动的。用户可以将其移动到画布中的任何位置,即它的父级。

一旦移动了图片并且应用了变换图像被“快照”后退到之前的原始0,0(画布的左上角)位置被改造后被留在那里 - 而不是用户期望的那样。

在一天中的最佳时刻搞砸了这件事之后,我仍然无法理解为什么它在做这件事。任何人

编辑:请注意,如果没有在上面的代码中对.translate()进行两次调用,也会发生同样的情况。因此,以下代码在移动后将图像捕捉回画布的0,0:

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;
}

杰克

5 个答案:

答案 0 :(得分:1)

以下是我修复它的方法。我超越了移动&#39;函数在我的Image类中,名为super.move(),然后将变换矩阵重置为我最初设置的值(在本例中为_affineTransform)。

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

Hacky,但是,如果某人有更清洁的解决方案,那么请告诉我!

答案 1 :(得分:1)

如果您在set x()中查看mx.core.UIComponent覆盖的源代码,您会看到以下行:

 _layoutFeatures.layoutX = value

基本上,它忽略默认显示列表x值并将位置存储在其他位置。真正的x可能会在处理完整版布局后再设置(替换您的翻译值)。您应该始终使用xyscaleXscaleYrotation以及任何其他相关属性。似乎Adobe并不打算让Flex支持常规显示对象变换矩阵。

答案 2 :(得分:0)

我认为您可能需要在翻译中添加x,y值:

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;
}

答案 3 :(得分:0)

尝试设置此项。

matrix.tx
matrix.ty

答案 4 :(得分:0)

解决方案/解决方法非常简单。而不是:

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

我现在有了这个:

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

可拖动的图像不再直接存在于主画布内。相反,它生活在儿童画布内。图像不再是可拖动的。这是被拖动的内部画布。

现在,当一个转换应用于图像时,它会保持为其父级的0,0坐标现在应该是它们的位置,因为它是将画布拖动到的位置。

希望这可以帮助某人并节省他们浪费在这上面的时间。 杰克