Показать сообщение отдельно
Старый 17.11.2013, 00:58
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 5  
Ответить с цитированием
Akopalipsis
Banned

Регистрация: Mar 2013
Сообщений: 1,864
Вообще я когда думал, для чего может понадобится класс масштабирования, то не задавался вопросом о "как будет", я делал, чтобы по всякому мог. Но наверное, он будет только bitmap увеличивать ширина\высота и так же с Graphics. Вот если я зарисовал десять спрайтов biginFill и потом самый главный контейнер буду увеличивать в ширину и высоту ( пропорционально ), отображение всё испортится?
Вот класс... Но он ужасен наверное
Код AS3:
package 
{
	import a_test.IAnimator;
	import a_test.IScaleCenter;
	import flash.events.EventDispatcher;
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	/**
	 * IScaleCenter - интерфейс служит дополнительным типом
	 * IAnimator - интерфейс содержит метод advanceTime(time:Number):void
	 */
	public class ScaleContainer  extends EventDispatcher implements IScaleCenter,IAnimator
	{
		private var _object:DisplayObject;
		private var _point:Point;
		private var _bounding:Rectangle;
 
		private var _factorWidth:Number;
		private var _factorHeight:Number;
 
		private var _defaultWidth:Number;
		private var _defaultHeight:Number;
 
		private var _finishWidth:Number;
		private var _finishHeight:Number;
 
		private var _speedWidth:Number;
		private var _speedHeight:Number;
 
		private var _speedX:Number;
		private var _speedY:Number;
 
		private var _finishX:Number;
		private var _finishY:Number;
 
		private var _offsetWidth:Number;
		private var _offsetHeight:Number;
 
		private var _offsetX:Number;
		private var _offsetY:Number;
 
		private var _moreWidth:Boolean;
		private var _lessWidth:Boolean;
 
		private var _moreHeight:Boolean;
		private var _lessHeight:Boolean;
 
		private var _moreX:Boolean;
		private var _lessX:Boolean;
 
		private var _moreY:Boolean;
		private var _lessY:Boolean;
 
		private var _isWidth:Boolean;
		private var _isHeight:Boolean;
 
		private var _isX:Boolean;
		private var _isY:Boolean;
 
 
 
		public function ScaleContainer() 
		{
 
		}
		public function add(object:DisplayObject,
										   scaleX:Number = 1.0,
										   scaleY:Number = 1.0,
										   speedX:Number = 1.0,
										   speedY:Number = 1.0,
										   point:Point = null,
										   bounding:Rectangle=null):ScaleContainer
		{
			if (!_object)
			{
				_object = object;
				_defaultWidth = _object.width;
				_defaultHeight = _object.height;
				_bounding = bounding;
 
				//коэфициент размеров ( 1% от размеров по умолчанию )
				_factorWidth = _defaultWidth / 100;
				_factorHeight = _defaultHeight / 100;
			}
			if (!point) 
			{
				_point = new Point();
				_point.x = _object.width / 2 + _object.x;
				_point.y = _object.height / 2 + _object.y;
			}
			else 
			{
				_point = point;
			}
 
			_moreWidth = false;
			_lessWidth = false;
			_moreHeight = false;
			_lessHeight = false;
			_moreX = false;
			_lessX = false;
			_moreY = false;
			_lessY = false;
			_isWidth = false;
			_isHeight = false;
			_isX = false;
			_isY = false;
 
			_finishWidth = _defaultWidth * scaleX;
			_finishHeight = _defaultHeight * scaleY;
 
			//коэфициент скорости ( 1% скорости )
			var factorSpeedX:Number = speedX * 1000 / 100;
			var factorSpeedY:Number = speedY * 1000 / 100;
 
			//разница между текущеми и финишными размерами
			var differenceWidth:Number = _finishWidth - _object.width;
			var differenceHeight:Number = _finishHeight - _object.height;
 
			//время которое будет затрачено на увеличение
			var timeScaleWidth:Number = differenceWidth / _factorWidth * factorSpeedX;
			var timeScaleHeight:Number = differenceHeight / _factorHeight * factorSpeedY;
 
			//если время отрицательное делаем его положительным
			if (timeScaleWidth < 0) timeScaleWidth *= -1;
			if (timeScaleHeight < 0) timeScaleHeight *= -1;
 
			_speedWidth = differenceWidth / timeScaleWidth;
			_speedHeight = differenceHeight / timeScaleHeight;
 
			//узнаем разницу между выбранной точкой и координатами обьекта
			var shiftX:Number = _point.x -_object.x;
			var shiftY:Number = _point.y - _object.y;
 
			//вычитаемое - растояние, уменьшив на которое значение координат обьекта, получим финишные координаты
			var subtrahendX:Number = shiftX - _finishWidth / (_object.width / shiftX);
			var subtrahendY:Number = shiftY - _finishHeight / (_object.height / shiftY);
 
			_finishX = _object.x + subtrahendX;
			_finishY = _object.y + subtrahendY;
 
			if (_bounding)
			{
				if (_finishX > _bounding.x)_finishX = _bounding.x;
				if (_finishY > _bounding.y)_finishY = _bounding.y;
				if (_finishX < _bounding.x - (_finishWidth - _defaultWidth))_finishX = _bounding.x - (_finishWidth - _defaultWidth);
				if (_finishY < _bounding.y - (_finishHeight - _defaultHeight))_finishY = _bounding.y - (_finishHeight - _defaultHeight);
			}
 
			_speedX = (_finishX - _object.x) / timeScaleWidth;
			_speedY = (_finishY - _object.y) / timeScaleHeight;
 
			_offsetWidth = _object.width;
			_offsetHeight = _object.height;
			_offsetX = _object.x;
			_offsetY = _object.y;
 
			if (_finishWidth >= _object.width)_moreWidth = true;
			else _lessWidth = true;
			if (_finishHeight >= _object.height)_moreHeight = true;
			else _lessHeight = true;
			if (_finishX >= _object.x)_moreX = true;
			else _lessX = true;
			if (_finishY >= _object.y)_moreY = true;
			else _lessY = true;
 
			return this;
		}
		public function restart():void
		{
			//
		}
		private function state():void
		{
			if (_isWidth && _isHeight && _isX && _isY)
			{
				//сли мы тут, то масштабирование закончено  
			}
		}
		/* INTERFACE a_test.IAnimator */
		public function advanceTime(time:Number):void 
		{
			_offsetWidth += time * _speedWidth;
			if (_moreWidth)
			{
				if (_offsetWidth >= _finishWidth)
				{
					_offsetWidth = _finishWidth;
					_isWidth = true;
					this.state();
				}
			}
			else 
			{
				if (_offsetWidth <= _finishWidth)
				{
					_offsetWidth = _finishWidth;
					_isWidth = true;
					this.state();
				}
			}
			_object.width = _offsetWidth;
 
			_offsetHeight += time * _speedHeight;
			if (_moreHeight)
			{
				if (_offsetHeight >= _finishHeight)
				{
					_offsetHeight = _finishHeight;
					_isHeight = true;
					this.state();
				}
			}
			else
			{
				if (_offsetHeight <= _finishHeight)
				{
					_offsetHeight = _finishHeight;
					_isHeight = true;
					this.state();
				}
			}
			_object.height = _offsetHeight;
			_offsetX += time * _speedX;
			if (_moreX)
			{
				if (_offsetX >= _finishX)
				{
					_offsetX = _finishX;
					_isX = true;
					this.state();
				}
			}
			else
			{
				if (_offsetX <= _finishX)
				{
					_offsetX = _finishX;
					_isX = true;
					this.state();
				}
			}
			_object.x = _offsetX;
			_offsetY += time * _speedY;
			if (_moreY)
			{
				if (_offsetY >= _finishY)
				{
					_offsetY = _finishY;
					_isY = true;
					this.state();
				}
			}
			else
			{
				if (_offsetY <= _finishY)
				{
					_offsetY = _finishY;
					_isY = true;
					this.state(); 
				}
			}
			_object.y = _offsetY;
		}
		override public function toString():String
		{
			return '[ScaleCenter] width - ' + _object.width + ' height - ' + _object.height + ' x - ' + _object.x + ' y - ' + _object.y;
		}
	}
 
}