Просмотр полной версии : Вращение изображения вокруг центра ViewPort
Ситуация такова: есть изображение, которое лежит внутри контейнера фиксированного размера, оно может быть как больше так и меньше контейнера; у контейнра установлено свойство clipAndEnableScrolling, поэтому все, что за пределами контейнера невидимо. Надо уметь вращать изображение вокруг точки, которая является центром видимой зоны.
public static function rotateImageAroundCenterOfViewPort(image:Image, value:Number):void
{
var bounds:Rectangle = image.getBounds(image.parent);
// Calculate rotation and shifts
var angle:Number = value - image.rotation;
var radians:Number = angle * (Math.PI / 180.0);
var shiftByX:Number = image.parent.width / 2 - bounds.x;
var shiftByY:Number = image.parent.height / 2 - bounds.y;
// Perform rotation
var matrix:Matrix = new Matrix();
matrix.translate(-shiftByX, -shiftByY);
matrix.rotate(radians);
matrix.translate(+shiftByX, +shiftByY);
matrix.concat(image.transform.matrix);
image.transform.matrix = matrix;
}
Данная функция работает правильно только 1 раз (шаг вращения 90 градусов в любую сторону) и почему-то частенько не работает, если изображение имеет сдвиг или скейл. Что надо поменять, чтобы она работала всегда?
Akopalipsis
14.01.2014, 15:55
Попробуйте вот так, point это точка во круг которой крутится объект.
Если работать не будет, хотя вроде должно, то на форуме много тем, Вы напишите если что, я попробую найти..
Аааа, я Вас вспомнил:) я тоже сейчас делаю трансформацию и мне кажется, что подход предложенный мной, может не подойти.
private static var DEG_TO_RAD:Number = 3.1415926535897932 / 180;
public static function rotationPointMatrix(target:DisplayObject, angle:Number, point:Point = null):void
{
var matrix:Matrix = target.transform.matrix;
matrix.translate( -point.x, -point.y);
matrix.rotate( -target.rotation * DEG_TO_RAD);
matrix.rotate(angle * DEG_TO_RAD);
matrix.translate(point.x, point.y);
target.transform.matrix = matrix;
}
Пока не пробовал, но очень походе на мой способ. Мне кажется, что всю дело в:
matrix.translate(+shiftByX, +shiftByY);
Т.к. изображение к тому моменту уже как бы повернуто, то смешения должны задаваться относительно нового угла вращения, а не старого.
помещайте изображение в контейнер в координаты
img.x = -img.width*0.5;
img.y = -img.height*0.5;
и вращайте сам контейнер
Во-первых, мне надо вращать изображение не вокруг его центра (как это сделать я знаю), а вокруг центра контейнера, в котором оно находится.
Во-вторых, я могу двигать изображение с помощью мыши, так что фиксировать его позицию никак нельзя.
Akopalipsis
14.01.2014, 17:28
Способ с -х-у может подойти, но обяжет все расчёты делать с минусами и не позволит вращать во круг произвольно взятой точки, что обязательно должно присутствовать в трансформе. я как сделаю, то покужу в Вашей теме, что у меня получилось, но пока я застрял на неопределённое время с рамкой, как в FS.
public static function rotateImageAroundCenterOfViewPort(image:Image, value:int):void
{
trace("rotation Begin: x ", image.x, " y: ", image.y);
var bounds:Rectangle = image.getBounds(image.parent);
trace("rotation Begin: bounds.x ", bounds.x, " bounds.y: ", bounds.y);
// Calculate rotation and shifts
var angle:Number = value - Math.round(image.rotation);
var radians:Number = angle * (Math.PI / 180.0);
var shiftByX:Number;
var shiftByY:Number;
// Perform rotation
switch(Math.round(image.rotation) / 90 % 4)
{
case 0:
{
shiftByX = image.parent.width / 2 - bounds.x;
shiftByY = image.parent.height / 2 - bounds.y;
break;
};
case 1:
{
shiftByX = image.parent.height / 2 - bounds.y;
shiftByY = bounds.width - (image.parent.width / 2 - bounds.x);
break;
};
case -2:
case 2:
{
shiftByX = bounds.width - (image.parent.width / 2 - bounds.x);
shiftByY = bounds.height - (image.parent.height / 2 - bounds.y);
break;
};
case -1:
{
shiftByX = bounds.height - (image.parent.height / 2 - bounds.y);
shiftByY = image.parent.width / 2 - bounds.x;
break;
};
default:
{
break;
}
}
var matrix:Matrix = new Matrix();
matrix.translate(-shiftByX, -shiftByY);
matrix.rotate(radians);
matrix.translate(+shiftByX, +shiftByY);
matrix.concat(image.transform.matrix);
image.transform.matrix = matrix;
trace("rotation End: x ", image.x, " y: ", image.y);
trace("rotation: xShift ", shiftByX, " yShift: ", shiftByY);
}
Немного поизучал тему. Выяснил на практике, что смещение надо задавать от текущего положения top-left точки. А нахождение этой точки в свою очередь связано с углом поворота. Но вот незадача: в image.rotation накапливается погрешность, из-за чего через некоторое число поворотов метод начинает сбоить и появляется лишний угол поворота.
Akopalipsis
14.01.2014, 18:19
в image.rotation накапливается погрешность, из-за чего через некоторое число поворотов метод начинает сбоить и появляется лишний угол поворота
Есть такое, но почему вы мой код не используете, там нет погрешностей.
Добавлено через 21 минуту
И погрешности не только в rotation накапливаются, это касается и x,y и может ещё чего.
Потому что, как и мой первый вариант, он вращает правильно всего 1 раз.
public static function rotateImageAroundCenterOfViewPort(image:Image, value:int):void
{
var bounds:Rectangle = image.getBounds(image.parent);
trace("rotation Begin: bounds.x ", bounds.x, " bounds.y: ", bounds.y);
// Calculate rotation and shifts
var shiftByX:Number;
var shiftByY:Number;
// Perform rotation
shiftByX = image.parent.width / 2 - bounds.x;
shiftByY = image.parent.height / 2 - bounds.y;
var matrix:Matrix = image.transform.matrix;
matrix.translate( -shiftByX, -shiftByY);
matrix.rotate( -image.rotation * DEG_TO_RAD);
matrix.rotate(value * DEG_TO_RAD);
matrix.translate(shiftByX, shiftByY);
image.transform.matrix = matrix;
}
Ыот во что он превратился у меня. Проблема в неверном вычислении точки поворота (т.е. с точки зрения смотрящего на экран - она верная, с точки зрения компонента - нет). Эту проблему я решил выше "свитчем", но возникла новая - с погрешностью.
Akopalipsis
14.01.2014, 21:14
Sonet конечно я могу ошибаться, но я столько уже экспериментировал с трансформацией, что могу сказать - в коде нет ошибок. Вы можете просто включить его на EF и смотреть, как он крутится и крутится и не сбивается, даже если угол подавать вот 0,0000545454545 такими значениями.
Ошибка может крыться в том, что я пока тоже не делал, а именно, расчёт угла в зависимости от курсора.
Хотя сложного вроде не чего в этом нет.
Ну не знаю. Мне надо вращать относительно видимой области. Наверное я не понимаю, как правильно вычислить эту точку (хотя скейлинг, без помощи матрицы, сделал).
Если не трудно, можете сделать пример, где есть изображение 200*200 внутри контейнера 100*100 с clipAndEnableScrolling = true. И чтобы оно вот так по таймеру вращалось вокруг центра видимой области.
Во-первых, мне надо вращать изображение не вокруг его центра (как это сделать я знаю), а вокруг центра контейнера, в котором оно находится.
Во-вторых, я могу двигать изображение с помощью мыши, так что фиксировать его позицию никак нельзя.
Вращение контейнера, содержащего изображение, относительно произвольной точки по-прежнему не подходит?
И, судя по clipAndEnableScrolling тема переезжает во флекс.
Вращение контейнера, содержащего изображение, относительно произвольной точки по-прежнему не подходит?
И, судя по clipAndEnableScrolling тема переезжает во флекс.
Крайне не желательно, т.к. потому надо будет вычислять смещения и т.п. С точки хрения пользователя,а не приложения.
Это свойство я использую, и привел в пример только, чтобы пояснить, что контйенер скрывает части изображения, выступающие за его границы. Геометрия от этого не меняется, поэтому я создал тему в более популярном разделе AS 3.0.
Akopalipsis
14.01.2014, 23:26
Геометрия от этого не меняется, поэтому я создал тему в более популярном разделе AS 3.0.
Тут я тоже согласен, так как ветку flex я вообще не посещаю.
где есть изображение 200*200 внутри контейнера 100*100 с clipAndEnableScrolling = true.
Что это такое я не знаю, но сделал аналог в as3 -( покликайте по сцене )
package
{
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
public class RotationTest extends Sprite
{
[Embed(source = "../../../bin/14-01-2014 21-30-06.jpg")]
private var Picture:Class;
private var _viewPort:Sprite;
private var _isScrollRectVisible:Boolean;
private var _transformContainer:Sprite;
private var _rect:Rectangle;
private var _centerTransformConteiner:Point;
public function RotationTest()
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mouseDownHandler);
_viewPort = new Sprite();
_viewPort.graphics.beginFill(0x2E2E2E);
_viewPort.graphics.drawRect(0, 0, 500, 300);
_viewPort.x = 50;
_viewPort.y = 50;
super.addChild(_viewPort);
var img:Bitmap = new Picture();
_rect = new Rectangle(0, 0, 100, 100);
_transformContainer = new Sprite();
_transformContainer.scrollRect = _rect;
_transformContainer.x = 100;
_transformContainer.y = 100;
img.x -= 40;
img.y -= 30;
_transformContainer.addChild(img);
_viewPort.addChild(_transformContainer);
_isScrollRectVisible = true;
_centerTransformConteiner = new Point(_transformContainer.x + _rect.width * 0.5, _transformContainer.y + _rect.height * 0.5);
this.drawPoint(_centerTransformConteiner);
var frame:Shape = new Shape();
frame.graphics.lineStyle(1, 0xFFFFFF);
frame.graphics.drawRect(0, 0, _rect.width, _rect.height);
frame.graphics.endFill();
frame.x = _transformContainer.x;
frame.y = _transformContainer.y;
_viewPort.addChild(frame);
stage.addEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
}
private var _angle:Number = 0;
private function stage_enterFrameHandler(event:Event):void
{
this.rotationPointMatrix(_transformContainer, (_angle++), _centerTransformConteiner);
}
private var DEG_TO_RAD:Number = 3.1415926535897932 / 180;
public function rotationPointMatrix(target:DisplayObject, angle:Number, point:Point = null):void
{
var matrix:Matrix = target.transform.matrix;
matrix.translate( -point.x, -point.y);
matrix.rotate( -target.rotation * DEG_TO_RAD);
matrix.rotate(angle * DEG_TO_RAD);
matrix.translate(point.x, point.y);
target.transform.matrix = matrix;
}
private function stage_mouseDownHandler(event:MouseEvent):void
{
if (_isScrollRectVisible)
{
_transformContainer.scrollRect = null;
_isScrollRectVisible = false;
}else
{
_transformContainer.scrollRect = _rect;
_isScrollRectVisible = true;
}
}
private function drawPoint(point:Point):void
{
var circle:Shape = new Shape();
circle.graphics.beginFill(0xFF0006);
circle.graphics.drawCircle(0, 0, 2);
circle.graphics.endFill();
circle.x = point.x;
circle.y = point.y;
_viewPort.addChild(circle);
}
}
}
scrollRect.swf
А почему вы вращаете _transformContainer да еще и относительно такой точки ( не понимаю, почему учитываются его x и y координаты)? У меня максимально просто случай: изображение и контейнер с установленным scrollRect. Метод будет просто принимать на вход изображение и угол и поворачивать его относительно центра scrollrect (еще одно несоответствие, т.к. у вас scrollRect тоже поворачивается, а мне надо, чтобы я всегда видел прямоугольник, полностью заполненный изображением, которое в свою очередь может быть повернуто).
Я попытался перенести этот код к себе, но у меня не работает ну никак.
private static var DEG_TO_RAD:Number = 3.1415926535897932 / 180;
public static function rotateImageAroundCenterOfViewPort(image:Image, value:int):void
{
var xShift:Number = image.x + image.parent.width / 2;
var yShift:Number = image.y + image.parent.height / 2;
var matrix:Matrix = image.transform.matrix;
matrix.translate( -image.x, -image.y);
matrix.rotate( -image.rotation * DEG_TO_RAD);
matrix.rotate(value * DEG_TO_RAD);
matrix.translate(xShift, yShift);
image.transform.matrix = matrix;
}
У меня компонент Image лежит внутри контейнера, scrollRect которого - он сам (т.е. прямоугольник (0, 0, w, h)). Вроде по сути все то же самое, но не работает.
Кстати, у вас похоже тоже погрешность накапливается (от этого никуда не деться?) - после нескольких минут вращения изображение прилично так сдвинулось.
Akopalipsis
15.01.2014, 14:19
А почему вы вращаете _transformContainer да еще и относительно такой точки
Прочтя -
И чтобы оно вот так по таймеру вращалось вокруг центра видимой области.
мне показалось, что вращение нужно делать, от центра контейнера с картинкой.
еще одно несоответствие, т.к. у вас scrollRect тоже поворачивается, а мне надо, чтобы я всегда видел прямоугольник,
я тоже подумал что Вам именно так и надо, но тут уже сами, передавайте не контейнер, а картинку, не чего не изменится.
Кстати, у вас похоже тоже погрешность накапливается (от этого никуда не деться?)
Уже минут пять крутится и не смещается не на пиксель...
В случае передачи изображения, какую точку надо передать? Она у вас не в методе считается, и мне не понятно почему именно так (не ясно почему вообще в расчет берутся х и y координаты).
Akopalipsis
15.01.2014, 14:46
Координаты у точки должны быть те, во круг которых вы хотите вращать.
Она у вас не в методе считается, и мне не понятно почему именно так
Считать координаты вращающегося объекта в методе вращения - это как пилить сук на котором сидишь, да и зачем их пересчитывать каждый раз, координаты точки ведь не меняются... Но можно и в методе, но тогда нужно усложнять в два раза. Первым делом, нужно вернуть объект в исходное положение и начальные координаты, то есть рассчитать угол в обратную.. и ещё нужно координаты округлять, так как они смещаются.
Вот как можно ещё сделать. (http://flasher.ru/forum/showthread.php?t=175235)
Добавлено через 5 минут
Вы в коде считаете так, что ширина контейнера равна видимой области, но это не так.
Координаты у точки должны быть те, во круг которых вы хотите вращать.
Считать координаты вращающегося объекта в методе вращения - это как пилить сук на котором сидишь, да и зачем их пересчитывать каждый раз, координаты точки ведь не меняются... Но можно и в методе, но тогда нужно усложнять в два раза. Первым делом, нужно вернуть объект в исходное положение и начальные координаты, то есть рассчитать угол в обратную.. и ещё нужно координаты округлять, так как они смещаются.
Вот как можно ещё сделать. (http://flasher.ru/forum/showthread.php?t=175235)
Добавлено через 5 минут
Вы в коде считаете так, что ширина контейнера равна видимой области, но это не так.
У меня так.
+ я должен считать точку внутри метода, т.к. я могу двигать изображение и т.о. точка всегда меняется.
Мне не ясно почему вы учитываете х и у координаты вращаемого объекта, ведь точку надо задавать в координатах этого же объекта.
Akopalipsis
15.01.2014, 15:23
+ я должен считать точку внутри метода, т.к. я могу двигать изображение и т.о. точка всегда меняется.
Если честно, то я уже не понимаю, что Вы хотите сделать. Если Вы изображение кладете в контейнер и двигаете при этом само изображение, то зачем вообще контейнер...
Но это уже Ваша история и помочь Вам я не могу. Удачи Вам! А я пойду экспериментировать с рамкой :)
Как бы есть некая область, куда пользователь может загрузить изображение (размеры получаются с сервера) - контейнер. Туда пользователь имеет возможность загрузить изображение. Оно может быть больше или меньше этой области, показываться должно изначально как есть. Соответственно если зображение больше, то лишние края прячутся контейнером. Пользователь может двигать, вращать и скейлить изображение внутри контейнера. Сам контейнер при этом должен оставаться неподвижен и не изменен. Получаается как бы окно, через которое мы видим кусок изображения и все модоификации должны производиться относительно этого окошка: скейлинг и вращение относительно центра окна, перемещение с учетом отступа относительно топлефт угла окна, а не картинки. И я все сделал, кроме поворота. Поворот работать не хочет никак. Лучший вариант валится из-за погрешности.
Akopalipsis
15.01.2014, 16:28
Мне кажется я видел такое в ВК, аватара там вроде так же сделана.
И тут опять-таки мне кажется, что Вы немного сбились. Вот загрузил я большое фото и мне нужно его по желанию подогнать под размер. Во первых я должен видеть всё изображение , по верх которого нарисована рамка конечного результата. Вращение и скейл должен проходить относительно центра этой рамки. Как бы я фото не скейлил и не перемещал, то всё это для того, чтобы в итоге я мог подкрутить по отношению центра контейнера. А если сделать вращение да и скейл по отношению не центра рамк конечного результата, то получится не плохая головоломка. Код который показал Вам я, рабочий и если делать как у меня то не чего не смещается. Проблема не в коде а в Вашем видении.
Для примера разберём эту строчку -
var xShift:Number = image.x + image.parent.width / 2;
Контейнер 100 на 100 в координатах 100 и 100.
Для поиска его центра нужно к координате х прибавить половину его ширины 50.
Но мы поворачиваем его на 45 градусов. Теперь его ширина не 100, а равна его диагонали в состоянии без вращения и координаты смещены. Под углом 90 градусов его координаты будут в 200, 200 и прибавив к ним ещё половину ширины вы центр смещаете воооообще не туда. Вам нужен центр РАМКИ!
вы отбраковываете нормальные варианты, и пытаетесь все усложнить.
есть главный контейнер- окно (назовем его window), в него в центр помещается другой контейнер(назщовем его innerBox и этот контейнер больше не двигается, или двигается при изменении размеров window ставится опять по центру ), в inner box помещаем изображение в координаты
img.x = -img.width *0.5;
img.y = -img.height *0.5;
далеее картинка перемещается внутри innerBox -а , а если нужно повернуть картинку вокруг точки(а точка - будет центр innerBox ), то вращаем сам innerBox.
вы отбраковываете нормальные варианты, и пытаетесь все усложнить.
есть главный контейнер- окно (назовем его window), в него в центр помещается другой контейнер(назщовем его innerBox и этот контейнер больше не двигается, или двигается при изменении размеров window ставится опять по центру ), в inner box помещаем изображение в координаты
img.x = -img.width *0.5;
img.y = -img.height *0.5;
далеее картинка перемещается внутри innerBox -а , а если нужно повернуть картинку вокруг точки(а точка - будет центр innerBox ), то вращаем сам innerBox.
Если innerBox не квадрат, то после его поворота стороны меняются местами. Такого быть не должно.
Akopalipsis
Это у меня очевидно не верная версия. Я пытался подогнать ваш код под свои нужны. Дело в том, что у меня картинка находится внутри статичного контейнера, который сам себе scrollRect. Т.е. скролл рект как бы имеет координаты (0,0) и ширину/высоту такую же, как у контейнера. И эти значения не меняются никогда.
Картинка внутри может иметь отрицательные координаты по этой причине. Поэтому по-хорошему должны быть вот такие сещения:
var bounds:Rectangle = image.getBounds(image.parent);
shiftByX = image.parent.width / 2 - bounds.x;
shiftByY = image.parent.height / 2 - bounds.y;
Но они не работают. Хотя я проверял - получаются координаты точки вращения (центра моего контейнера, который сам и является рамкой) внутри изображения.
стороны меняются местами
можно тут поподробнее?
можно тут поподробнее?
Была у вас высоту иннербокса 100 и шририна 200, при повороте на 90 градусов станет наоборот.
Akopalipsis
15.01.2014, 17:59
shiftByX = image.parent.width / 2 - bounds.x;
Парент, это скрол 100 на 100?
у меня картинка находится внутри статичного контейнера, который сам себе scrollRect.
Т.е. да.
У меня всего 2 объекта: контейнер, который обрезает все, что за его пределами (т.е. его ширина, высота фиксированы, если в него поместить что-то большее, чем он сам, то они не изменятся, лишний контент будет невидим, контент может иметь отрицательные координаты), и картинка внутри него.
Была у вас высоту иннербокса 100 и шририна 200, при повороте на 90 градусов станет наоборот.
не берите "getRect" - размеры, внутри себя этот inner-box не изменил размеры, вытаскивайте размеры из него
К чему эта картинка? Кстати у меня задача немного проще, т.к. шаг поворота 90 градусов.
Akopalipsis
15.01.2014, 18:35
К чему эта картинка?
я сделал все что мог, но Вы не как не понимаете :(
Akopalipsis
Я не понимаю, что вы хотите мне сказать. Всем ясно как будут менять координаты. Приклдадываю некоторую иллюстрацию.
Перед поворотом, как я понимаю, мы транслируем точку внутри изображения, которая для пользователя видна, как точка-центр контейнера в topLeft. Потом поворачиваем и транслируем обратно.
Кстати, вы не пробовали мой метод со switch-блоком? Он работает полностью как надо, но накапливает погрешность.
Он статический, на вход нужен компонент, который будем вращать (в моем случае объект класса Image, но подойдет любой) и новый угол вращения (90, 180, 270 и т.п. кратное 90).
Создайте контейнер, установите ему clipRect равный его же размерам и засуньте в него изображение.
Akopalipsis
15.01.2014, 20:57
Делаю ещё одну попытку :)
Кстати, вы не пробовали мой метод со switch-блоком? Он работает полностью как надо, но накапливает погрешность.
Вам нужно нарисовать на листочке этот блок-switch и как следует подумать над тем, что Вы делаете.
Мой примитивный код, построен на том, что центр, будь то рект-контейнер или что-то другое, ПОСТОЯНЕН!
Тут я немного объясню то, что Вы должны знать, но все-же..
Есть сцена, у неё точка регистрации находится в topLeft. Вот мы создаём контейнер и присваеваем его точки регистрации (300, 300). В этот контейнер кладем картинку в координаты (0,0) и выглядеть это будет так, как буд-то она находится в координатах (300,300), так-как у контейнера уже другая система координат.
Продолжаю, если Вы двигаете картинку ( видимую её часть ) в пространстве, то это не как не должно сказываться на координаты центра контейнера!!!! Вы понимаете? Двигать контейнер или что-то в нем, это не значит, что его собственная система координат меняется! Точка центра как была в координатах (50,50), так она там и будет, даже если Вы сам контейнер за пределы монитора сдвинете!
Продолжаю, Вам нужно, как Вы сами говорите, двигать ОТНОСИТЕЛЬНО ЦЕНТРА КОНТЕЙНЕРА, ширина и высота которого ВСЕГДА ПОСТОЯННА! Так зачем же точку центра искать исходя из-за положения картинки? Центр как был в (50,50) так он там и будет.
Продолжаю, смотрите на свою картинку, видите в topLeft невидимой области находится настоящая точка регистрации картинки. Противоположная часть называется topRight. Вот Вы повернули картинку на 90 градусов, где будет точка регистрации картинки? Там, где в самом начале была точка topRight и то это с условием, что картинка КВАДРАТНАЯ!!! А ширина становиться равной длине!
Возьмите и нарисуйте мои слова и свои слова. Когда Вы это поймете, то я скажу что делать дальше.
Akopalipsis
15.01.2014, 21:48
Расскажите какая у Вас вложенность, что в какой контейнер вставляется, и на сколько градусов Вам нужно крутить и относительно чего. я сделаю так же и покажу.
У меня 1 контейнер (сцену я не считаю за контейнер, т.к. мне не надо создавать ее вручную). Я задаю ему позицию и размеры, они никогда не меняются. В него я вкладываю изображение, которое может быть как больше, так и меньше, чем контейнер. У контейнера выставлено проперти clipAndEnableScrolling. Как я понимаю это равносильно выставлению проперти scrollRect со значниеми (0, 0, container.width, container.height) - контейнер сам себе scrollRect.
Вращение на величину кратную +-90 градусов. Повернуть надо изображение (внутри контейнера) относительно центра видимой области. В любой момент изображение может быть сдвинуто (просто меняю х и у координаты) или промасштабированно (тоже относительно центра, делаю без матрицы, просто применяю новый scale фактор и смещения по х и у).
Akopalipsis
15.01.2014, 22:18
Пока могу сказать только одно, не знаю как у clipAndEnableScrolling, но у scrollRect ширина и высота равняется, так же как и у обычного контейнера, его содержимому.
Хмм. clipAndEnableScrolling влияет только на видимость контейнера. Т.е. допустим я выставил ширину и высоту контейнера по 100, а картинку вставил 200*200. Если это проперти установлено, то я буду видеть только то, что попало в прямоугольник 100*100 и размеры контейнера не будут увеличены.
У меня вопрос возник: matrix.translate изменяет x и y координаты компонента, или перемещает pivot point на заданные величины? Я почему-то считал, что последнее.
Akopalipsis
15.01.2014, 23:10
я пока воздерживаюсь от комментариев, так как сам на данный момент не знаю железного решения.
Без сохранения начальных координат сделать можно, но на столько затратно, что я лучше промолчу..
Нашел решение без свича. Работает, но накапливает погрешность.
public static function rotateImageAroundCenterOfViewPort(image:Image, value:int):void
{
// Calculate rotation and shifts
var center:Point = new Point(image.parent.width / 2, image.parent.height / 2);
center = image.parent.localToGlobal(center);
center = image.globalToLocal(center);
var angle:Number = value - image.rotation;
var radians:Number = angle * (Math.PI / 180.0);
var shiftByX:Number = center.x;
var shiftByY:Number = center.y;
// Perform rotation
var matrix:Matrix = new Matrix();
matrix.translate(-shiftByX, -shiftByY);
matrix.rotate(radians);
matrix.translate(+shiftByX, +shiftByY);
matrix.concat(image.transform.matrix);
image.transform.matrix = matrix;
}
Добавлено через 24 часа 16 минут
Финальный вариант, может быть кому-то будет полезен. В конце чуть-чуть хитрим - округляем итоговый угол. На глаз все работает вроде хорошо.
public static function rotateImageAroundCenterOfViewPort(image:Image, value:int):void
{
// Calculate rotation and shifts
var center:Point = new Point(image.parent.width / 2, image.parent.height / 2);
center = image.parent.localToGlobal(center);
center = image.globalToLocal(center);
var angle:Number = value - image.rotation;
var radians:Number = angle * (Math.PI / 180.0);
var shiftByX:Number = center.x;
var shiftByY:Number = center.y;
// Perform rotation
var matrix:Matrix = new Matrix();
matrix.translate(-shiftByX, -shiftByY);
matrix.rotate(radians);
matrix.translate(+shiftByX, +shiftByY);
matrix.concat(image.transform.matrix);
image.transform.matrix = matrix;
image.rotation = Math.round(image.rotation);
}
Первый параметр - компонент Image, который надо повернуть, второй - новый угол вращения (тестировал только с углами, кратными 90 градусов).
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.