PDA

Просмотр полной версии : Перемещение, ресайзинг и т.п. объектов с помощью мыши.


Sonet
04.01.2014, 15:21
Здравствуйте.
Необходимо сделать некий компонент, который поддерживает рисование в нем прямоугольников их перемещение и изменение размеров. Все с помощью мыши. Несмотря на то, что задача довольно простая - у меня возникли с ней некоторые трудности.
Я год не разрабатывал на флексе, поэтому первым делом появилась такая идея: иметь некий контейнер фиксированного размера; иметь некий компонент, который будет отвечать за отрисовку прямоугольников их перемещение и изменение размеров, будет помещаться в описанный ранее контейнер и занимать всю его высоту и ширину. В компоненте-прямоугольнике я хотел в mxml описать собственно сам прямоугольник и 4 квадрата по бокам, которые будут выполнять роль рамки для ресайзинга, как-то по-хитрому забайндить их координаты и размеры между собой и применить стандартный механизм пермещения - startDrag/stopDrag. Тут же всплыл первый подводный камень - во время перетаскивания координаты объекта не меняются (ведь создается временный объект) и соответственно координаты и размерности прямоугольника не обновляются.
Хорошо. Я написал свою обработку событий мыши в компоненте-прямоугольнике. Сейчас имеется различие нажатий на рамку, прямоугольник, перемещение, ресайзинг и т.п. Но, всплыл другой "косяк" - компонент-прмоугольник занимает всю ширину/высоту контейнера, в то время как сам прямоугольник внтри него мал. Т.е. у меня огромная прозрачная зона, которая либо перехватывает все события от мыши, либо нет. В первом случае из всех компонентов-прямоугольников из контейнера я могу работать только с одним ("верхним"). Во втором при захвате и перемещении рамки или границы курсор часто выходит за пределы отрисованной зоны и попадает в зону прозрачности, которая событий от мыши не получает и соотвественно происходят застревания.

Как лучше всего решить поставленную задачу? Могу предоставить код, который я уже написал.

Akopalipsis
04.01.2014, 15:48
Вот тут drag (http://www.flasher.ru/forum/showpost.php?p=1147117&postcount=24), которого не глючит от выхода мышки за пределы. Но Вам нужно на flex... по этому мой пример может и не поможет..

Sonet
04.01.2014, 17:50
Вроде как я сделал то, что хотел. Но есть 1 нюанс. Я изменяю компонентам ширину, высоту и позицию динамически, когда получаю mouseMove. Это приводит к тому, что компоненты моргают при перерисовке, остаются видны старые позиции на некоторое время и т.п. Как можно этого избежать?

Akopalipsis
04.01.2014, 18:12
Сгладить мерцание, поможет -
private function mouseMoveHandler(event:MouseEvent):void
{
event.updateAfterEvent();
}
а если не поможет, то это, скорее всего, из-за не округлённых координат. И я не знаю как с этим бороться.
остаются видны старые позиции на некоторое время и т.п.

Такого я не когда не видел, вроде не должно такого быть..

Добавлено через 12 минут
Может быть я могу куда-то залить билд, чтобы было ясно в чем дело?
Самый лучший вариант, если Вы прям в сообщение вставите swf, чтобы было видно мерцание и код,
который у Вас за это отвечает. А то немного не представляется, как у Вас там всё :)

Sonet
04.01.2014, 18:26
Предложенное вами решение сделало отрисовку гораздо плавнее, но проблемы с мерцанием остались.
Прикладываю исходники. Там всего 2 компонента.

Akopalipsis
04.01.2014, 18:38
Sonet Вам придётся ждать тех, кто понимает flex, я если честно даже запустить не могу. Да и как решить проблему с мерцанием я тоже не знаю, ещё не дошел до этого.
На сколько я знаю, мерцать может из-за не округлённых координат, то есть, координата object.x = 3.0015, а не object.x=3. И вот флеш плеер плохо рисует по расчётам таких координат. Решается вроде маленьким blur'ом, размытием, но возможно есть какие то более простые решения. У bitmap есть вроде - сглаживание.

Sonet
04.01.2014, 18:42
Akopalipsis
Попробовал округлять координаты перед высталвением - не помогло.
Значит подожду)

Sonet
08.01.2014, 19:43
Самый лучший вариант, если Вы прям в сообщение вставите swf, чтобы было видно мерцание и код,
который у Вас за это отвечает. А то немного не представляется, как у Вас там всё :)
Вот swf.

Isfet
08.01.2014, 20:16
скорее всего продлема в точке регистрации, когда вы задаете box.width = newWidth;
так как точка регистрации находится по центру, то и прямоугольник будет растянут в две стороны.

попробуйте поменять местами строки вот так:


box.width = newWidth;
box.height = newHeight;
box.x = newX;
box.y = newY;

почему бы не отрисовывать прямоугольники через графикс?

Sonet
09.01.2014, 13:31
скорее всего продлема в точке регистрации, когда вы задаете box.width = newWidth;
так как точка регистрации находится по центру, то и прямоугольник будет растянут в две стороны.

попробуйте поменять местами строки вот так:


box.width = newWidth;
box.height = newHeight;
box.x = newX;
box.y = newY;

почему бы не отрисовывать прямоугольники через графикс?

Не помогло.

Потому что мне удобнее иметь его как отдельный компонент-контейнер, т.к. я планировал помещать в него текстовые поля или изображения. Хотя как обходной путья держу этот вариант при себе.

Isfet
09.01.2014, 14:28
тоже не юзал никогда, флекс, вроде экспортировал проект его во флешдевелоп из билдера, но после компиляции стэйдж пустая, поэтому не могу ниче потрейсить, а просто так глядя на код не могу особо ничего скзать, будет время - переделаю на as и потестю.

Добавлено через 44 часа 41 минуту
я тут подумал над вашей проблемой, как-то у вас реализовано все сильно сложно, есть решения - потривиальней. Я бы делал так:
1. Есть 4 точки(Point), по которым расстягивается фигура
2. По маус дауну делаем точку "активной" (тоесть при перерисовке все останые точки будут обновлять свои координаты по ней ).
3. когда тащим один из прямоугольников, и по маусмуву изменяем координаты активной точки
4.прерисовываем фигуру(обновляем точки по активной, расставляем прямоугольники по точкам), растягиваем контент.