Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 11.03.2014, 01:10
alexandrratush вне форума Посмотреть профиль Отправить личное сообщение для alexandrratush Найти все сообщения от alexandrratush
  № 1  
Ответить с цитированием
alexandrratush
 
Аватар для alexandrratush

Регистрация: Jul 2013
Адрес: Днепр
Сообщений: 529
Отправить сообщение для alexandrratush с помощью ICQ Отправить сообщение для alexandrratush с помощью Skype™
По умолчанию Копирование прямоугольной области, под маской

Здравствуйте! Помогите решить следующую проблему.
Есть компонент для редактирования аватара пользователя (можно перетягивать картинку).
В этом компоненте есть контейнер для аватара, на него накладывается маска. В него добавляется графический объект. После нужно скопировать эту область под маской.

В итоге есть две проблемы, над которыми просидел целый день:
1. Почему обрезается картинка, если переместить ее вправо или вниз до упора. И как это исправить?
2. Как убрать отступы слева и сверху у скопированной картинки? Как видно она добавляется в контейнер, который должен соприкасаться с черной линией, и верхней границей ролика, но этого не происходит.

Примечание: Если этот компонент размещен на сцене в точке (0;0), то все работает отлично.

Код главного класса:
Код AS3:
package  {
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.display.Sprite;
 
 
	public class Main extends MovieClip {
 
		private var _containerImage:Sprite = new Sprite();
 
 
		public function Main() {
			// Компонент
			_componentAvatar.addAvatar(new TestMC());
 
			// Контейнер изображения
			_containerImage = new Sprite();
			addChild(_containerImage);
 
			// Кнопка
			_btnSaveImage.addEventListener(MouseEvent.CLICK, saveHandler);
		}
 
		private function saveHandler(e:MouseEvent):void {
 
			while (_containerImage.numChildren > 0) _containerImage.removeChildAt(0);
 
			// Добавляем в контейнер копию из нашего компонента
			_containerImage.addChild(_componentAvatar.avatarImage);
			_containerImage.x = 275;
			_containerImage.y = 0;
		}
	}
}

Код компонента:
Код AS3:
package ui {
 
	import flash.display.Sprite;
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.display.Bitmap;
	import flash.display.PixelSnapping;
	import flash.display.BitmapData;
 
 
	public class ComponentAvatar extends Sprite {
 
		private var _contAvatar:Sprite;
		private var _mask:Sprite;
		private var _boundsRect:Rectangle;
 
 
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
 
		public function ComponentAvatar() {
			_contAvatar = new Sprite();
			_contAvatar.buttonMode = true;
			_contAvatar.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			addChild(_contAvatar);
 
			createMask();
 
			_boundsRect = getRect(this);
 
			if (stage) init(null);
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
 
//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
 
		public function addAvatar(d:DisplayObject):void {
			while (_contAvatar.numChildren > 0) _contAvatar.removeChildAt(0);
 
			_contAvatar.scaleX = _contAvatar.scaleY = 1;
			_contAvatar.x = _contAvatar.y = 0;
			_contAvatar.addChild(d);
 
			var minScaleX:Number = 200 / _contAvatar.width;
			var minScaleY:Number = 200 / _contAvatar.height;
//			_minScale = (minScaleX > minScaleY) ? minScaleX : minScaleY;
 
			dispatchEvent(new Event(Event.ADDED));
		}
 
 
//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
 
		private function createMask():void {
			_mask = new Sprite();
			_mask.graphics.beginFill(0x000000);
			_mask.graphics.drawRoundRect(2, 2, width - 4, height - 4, 15, 15);
			_mask.graphics.endFill();
 
			addChild(_mask);
 
			_contAvatar.mask = _mask;
		}
 
		private function moveCorrection():void {
			// move to right
			if (_contAvatar.x > _boundsRect.topLeft.x) {
				_contAvatar.x = _boundsRect.topLeft.x;
			}
 
			// move to bottom
			if (_contAvatar.y > _boundsRect.topLeft.y) {
				_contAvatar.y = _boundsRect.topLeft.y;
			}
 
			// move left
			if (_contAvatar.x < _boundsRect.bottomRight.x - _contAvatar.width) {
				_contAvatar.x = _boundsRect.bottomRight.x - _contAvatar.width;
			}
 
			// move top
			if (_contAvatar.y < _boundsRect.bottomRight.y - _contAvatar.height) {
				_contAvatar.y = _boundsRect.bottomRight.y - _contAvatar.height;
			}
		}
 
		private function cropBitmap( displayObject:DisplayObject, xC:Number = 0, yC:Number = 0, widthC:Number = 0, heightC:Number = 0 ):Bitmap {
			if (!widthC) widthC = displayObject.width;
			if (!heightC) heightC = displayObject.height;
 
			var cropArea:Rectangle = new Rectangle(0, 0, widthC, heightC );
 
			var bmpd:BitmapData = new BitmapData( widthC, heightC, true, 0x000000 );
 
			var croppedBitmap:Bitmap = new Bitmap( bmpd, PixelSnapping.ALWAYS, true );
 
			var cropMatrix:Matrix = croppedBitmap.transform.matrix;
				cropMatrix.translate( -xC, -yC );
 
			bmpd.draw( displayObject, cropMatrix, null, null, cropArea, true );
 
			return croppedBitmap;
		}
 
 
//- EVENT HANDLERS ----------------------------------------------------------------------------------------
 
		private function init(e:Event):void {
			if (e) removeEventListener(Event.ADDED_TO_STAGE, init);
 
			stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
 
		private function mouseDownHandler(e:MouseEvent):void {
			_contAvatar.startDrag();
			stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler);
		}
 
		private function stageMouseUpHandler(e:MouseEvent):void {
			_contAvatar.stopDrag();
		}
 
		private function enterFrameHandler(e:Event):void {
			moveCorrection();
		}
 
 
// - GETTER & SETTER --------------------------------------------------------------------------------------
 
		public function get avatarImage():DisplayObject {
			var ltPoint:Point = _contAvatar.globalToLocal( new Point(0, 0) );
			return cropBitmap( _contAvatar, ltPoint.x, ltPoint.y, x + ltPoint.x + 200, y + ltPoint.y + 200 );
		}
	}
}
Исходник демки CS6:
cropBitmapTest.rar

Вот демо:
Main.swf   (29.2 Кб)
Вложения
Тип файла: swf Main.swf (29.2 Кб, 52 просмотров)

Старый 11.03.2014, 06:33
Isfet вне форума Посмотреть профиль Отправить личное сообщение для Isfet Найти все сообщения от Isfet
  № 2  
Ответить с цитированием
Isfet

Регистрация: Mar 2012
Адрес: г.Новосибирск
Сообщений: 381
а вас не смущает что размер обрезки равен размеру маски ?
Название: 222.JPG
Просмотров: 142

Размер: 19.8 Кб

тут проблема в том , где лежит маска, так как она лежит в главном контейнере, она и режет относительно главного контейнера, а в других случаях или рект другой или еще что-то - нужно смотреть, и пересохраните проект в cs5, и в вашем случае, не нужно подписываться на энтерфрейм(из-за него у вас дергается изображение, когда перетаскиваешь его к краю), подписывайте стейдж на маусмув.

Насчет отступов, сделайте еще один контейнер, в котором битмап будет храниться без отступов, внутри него делайте маску, и относительно него копируйте.
И вообще у вас должно быть две КОНСТАНТЫ,
Код AS3:
WIDTH = 200;
HEIGHT = 200;
и относительно них вы пляшете, а не относительно абстрактного width и height вашего компонента, размер которых динамический и изменяется в зависимости от контента, и поведения которых сложно предугадать.


Последний раз редактировалось Isfet; 11.03.2014 в 06:47.
Старый 11.03.2014, 14:19
alexandrratush вне форума Посмотреть профиль Отправить личное сообщение для alexandrratush Найти все сообщения от alexandrratush
  № 3  
Ответить с цитированием
alexandrratush
 
Аватар для alexandrratush

Регистрация: Jul 2013
Адрес: Днепр
Сообщений: 529
Отправить сообщение для alexandrratush с помощью ICQ Отправить сообщение для alexandrratush с помощью Skype™
Большое спасибо за советы, которые помогли очень.
Да вы правы все это через маску. Вставил пока костыль, когда будет время разберусь с этим.

Вот типо так работает:

Код AS3:
public function get avatarImage():DisplayObject {
	var ltPoint:Point = _contAvatar.globalToLocal(_leftTopPoint);
 
	_contAvatar.mask = null;
 
	var bm:Bitmap =  DisplayUtils.cropBitmap( _contAvatar, ltPoint.x, ltPoint.y, 200, 200 );
 
	_contAvatar.mask = _mask;
 
	return bm;
}
Цитата:
Насчет отступов, сделайте еще один контейнер, в котором битмап будет храниться без отступов, внутри него делайте маску, и относительно него копируйте.
Вот это если честно не понял.

Цитата:
не нужно подписываться на энтерфрейм(из-за него у вас дергается изображение, когда перетаскиваешь его к краю), подписывайте стейдж на маусмув.
У меня просто есть эффект зума, так что я решил что это лучший вариант.

Цитата:
И вообще у вас должно быть две КОНСТАНТЫ,
Это тоже не выход, так как компонент будет иметь разные размеры в одном проекте.

Старый 11.03.2014, 14:45
Isfet вне форума Посмотреть профиль Отправить личное сообщение для Isfet Найти все сообщения от Isfet
  № 4  
Ответить с цитированием
Isfet

Регистрация: Mar 2012
Адрес: г.Новосибирск
Сообщений: 381
Цитата:
Вот это если честно не понял.
сделать контейнер(и сдвинуть его, а не битмапу), а внутри него битмапа будет лежать в координатах (0,0), и маска тоже.
Цитата:
У меня просто есть эффект зума, так что я решил что это лучший вариант.
почему не сделать 2 обработчика? move и wheel

Цитата:
Это тоже не выход, так как компонент будет иметь разные размеры в одном проекте.
значит не константы, а переменные, которые будут высчитываться 1 раз, смысл в том чтобы не использовать width , так как он может измениться при добавлении/сдвигании/растягивании чилда.

Создать новую тему Ответ Часовой пояс GMT +4, время: 23:25.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 23:25.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.