Почему матрица Flex преобразует привязанный дочерний элемент в верхний родительский угол? - PullRequest
1 голос
/ 14 апреля 2011

У меня проблемы с матричными преобразованиями во Flex.

У меня есть 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 ]

1 голос
/ 15 апреля 2011

Если вы посмотрите в исходном коде переопределение set x() в mx.core.UIComponent, вы увидите следующую строку:

 _layoutFeatures.layoutX = value

По сути, он игнорирует список отображения по умолчанию x значениеи сохраняет позицию в другом месте.Реальная x, вероятно, устанавливается позже, после того, как полный макет был обработан (заменяя значение перевода).Вам, вероятно, следует всегда использовать x, y, scaleX, scaleY, rotation и любые другие соответствующие свойства.Похоже, что Adobe не планирует, чтобы Flex поддерживал обычную матрицу преобразования экранных объектов.

1 голос
/ 15 апреля 2011

Вот как я это исправил. Я переопределил функцию 'move' в своем классе Image, которая называется super.move (), а затем сбросил матрицу преобразования до значения, которое я изначально установил (в данном случае _affineTransform).

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

Хаки, но смотри, что поделаешь ... если у кого-то есть более чистое решение, пожалуйста, дай мне знать!

0 голосов
/ 16 апреля 2011

Решение / обходной путь к этому довольно прост. Вместо этого:

<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 его родителя теперь там, где они должны быть, как и там, куда вы перетащили холст.

Надеюсь, это поможет кому-то и сэкономит время, которое я потратил на это. Джейк

0 голосов
/ 15 апреля 2011

попробуйте установить это.

matrix.tx
matrix.ty
0 голосов
/ 14 апреля 2011

Я думаю, вам, возможно, придется добавить значения 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...