Return to Snippet

Revision: 23544
at February 9, 2010 04:39 by adrianparr


Initial Code
package uk.soulwire.utils.display 
{
	/**
	 * uk.soulwire.utils.display.DisplayUtils
	 * 
	 * @version v1.0
	 * @since May 26, 2009
	 * 
	 * @author Justin Windle
	 * @see http://blog.soulwire.co.uk
	 * 
	 * About DisplayUtils
	 * 
	 * DisplayUtils is a set of static utility methods for dealing 
	 * with DisplayObjects
	 * 
	 * Licensed under a Creative Commons Attribution 3.0 License
	 * http://creativecommons.org/licenses/by/3.0/
	 */
	 
	import flash.display.PixelSnapping;	
	import flash.display.Bitmap;	
	import flash.display.BitmapData;	 
	import flash.geom.Matrix;	
	import flash.geom.Rectangle;	
	import flash.display.DisplayObject;	

	public class DisplayUtils 
	{	

		//---------------------------------------------------------------------------
		//------------------------------------------------------------ PUBLIC METHODS
		
		/**
		 * Fits a DisplayObject into a rectangular area with several options for scale 
		 * and alignment. This method will return the Matrix required to duplicate the 
		 * transformation and can optionally apply this matrix to the DisplayObject.
		 * 
		 * @param displayObject
		 * 
		 * The DisplayObject that needs to be fitted into the Rectangle.
		 * 
		 * @param rectangle
		 * 
		 * A Rectangle object representing the space which the DisplayObject should fit into.
		 * 
		 * @param fillRect
		 * 
		 * Whether the DisplayObject should fill the entire Rectangle or just fit within it. 
		 * If true, the DisplayObject will be cropped if its aspect ratio differs to that of 
		 * the target Rectangle.
		 * 
		 * @param align
		 * 
		 * The alignment of the DisplayObject within the target Rectangle. Use a constant from 
		 * the DisplayUtils class.
		 * 
		 * @param applyTransform
		 * 
		 * Whether to apply the generated transformation matrix to the DisplayObject. By setting this 
		 * to false you can leave the DisplayObject as it is but store the returned Matrix for to use 
		 * either with a DisplayObject's transform property or with, for example, BitmapData.draw()
		 */

		public static function fitIntoRect(displayObject : DisplayObject, rectangle : Rectangle, fillRect : Boolean = true, align : String = "C", applyTransform : Boolean = true) : Matrix
		{
			var matrix : Matrix = new Matrix();
			
			var wD : Number = displayObject.width / displayObject.scaleX;
			var hD : Number = displayObject.height / displayObject.scaleY;
			
			var wR : Number = rectangle.width;
			var hR : Number = rectangle.height;
			
			var sX : Number = wR / wD;
			var sY : Number = hR / hD;
			
			var rD : Number = wD / hD;
			var rR : Number = wR / hR;
			
			var sH : Number = fillRect ? sY : sX;
			var sV : Number = fillRect ? sX : sY;
			
			var s : Number = rD >= rR ? sH : sV;
			var w : Number = wD * s;
			var h : Number = hD * s;
			
			var tX : Number = 0.0;
			var tY : Number = 0.0;
			
			switch(align)
			{
				case Alignment.LEFT :
				case Alignment.TOP_LEFT :
				case Alignment.BOTTOM_LEFT :
					tX = 0.0;
					break;
					
				case Alignment.RIGHT :
				case Alignment.TOP_RIGHT :
				case Alignment.BOTTOM_RIGHT :
					tX = w - wR;
					break;
					
				default : 					
					tX = 0.5 * (w - wR);
			}
			
			switch(align)
			{
				case Alignment.TOP :
				case Alignment.TOP_LEFT :
				case Alignment.TOP_RIGHT :
					tY = 0.0;
					break;
					
				case Alignment.BOTTOM :
				case Alignment.BOTTOM_LEFT :
				case Alignment.BOTTOM_RIGHT :
					tY = h - hR;
					break;
					
				default : 					
					tY = 0.5 * (h - hR);
			}
			
			matrix.scale(s, s);
			matrix.translate(rectangle.left - tX, rectangle.top - tY);
			
			if(applyTransform)
			{
				displayObject.transform.matrix = matrix;
			}
			
			return matrix;
		}

		/**
		 * Creates a thumbnail of a BitmapData. The thumbnail can be any size as 
		 * the copied image will be scaled proportionally and cropped if necessary 
		 * to fit into the thumbnail area. If the image needs to be cropped in order 
		 * to fit the thumbnail area, the alignment of the crop can be specified
		 * 
		 * @param image
		 * 
		 * The source image for which a thumbnail should be created. The source 
		 * will not be modified
		 * 
		 * @param width
		 * 
		 * The width of the thumbnail
		 * 
		 * @param height
		 * 
		 * The height of the thumbnail
		 * 
		 * @param align
		 * 
		 * If the thumbnail has a different aspect ratio to the source image, although 
		 * the image will be scaled to fit along one axis it will be necessary to crop 
		 * the image. Use this parameter to specify how the copied and scaled image should 
		 * be aligned within the thumbnail boundaries. Use a constant from the Alignment 
		 * enumeration class
		 * 
		 * @param smooth
		 * 
		 * Whether to apply bitmap smoothing to the thumbnail
		 */

		public static function createThumb(image : BitmapData, width : int, height : int, align : String = "C", smooth : Boolean = true) : Bitmap
		{
			var source : Bitmap = new Bitmap(image);
			var thumbnail : BitmapData = new BitmapData(width, height, false, 0x0);
			
			thumbnail.draw(image, fitIntoRect(source, thumbnail.rect, true, align, false), null, null, null, smooth);
			source = null;
			
			return new Bitmap(thumbnail, PixelSnapping.AUTO, smooth);
		}
	}
}






package uk.soulwire.utils.display 
{

	/**
	 * @author Justin Windle ([email protected])
	 */
	public class Alignment 
	{
		/**
		 * Specifies that alignment is at the bottom.
		 */
		public static const BOTTOM : String = "B";
		/**
		 * Specifies that alignment is in the bottom-left corner. 
		 */
		public static const BOTTOM_LEFT : String = "BL";
		/**
		 * Specifies that alignment is in the bottom-right corner. 
		 */
		public static const BOTTOM_RIGHT : String = "BR";
		/**
		 * Specifies that alignment is on the left. 
		 */
		public static const LEFT : String = "L";
		/**
		 * Specifies that alignment is in the middle
		 */
		public static const MIDDLE : String = "C";
		/**
		 * Specifies that alignment is on the right. 
		 */
		public static const RIGHT : String = "R";
		/**
		 * Specifies that alignment is at the top. 
		 */
		public static const TOP : String = "T";
		/**
		 * Specifies that alignment is in the top-left corner. 
		 */
		public static const TOP_LEFT : String = "TL";
		/**
		 * Specifies that alignment is in the top-right corner. 
		 */
		public static const TOP_RIGHT : String = "TR";
	}
}

Initial URL
http://blog.soulwire.co.uk/code/actionscript-3/fit-a-displayobject-into-a-rectangle

Initial Description
DisplayUtils.as and Alignment.as

These two classes by Justin Windle (aka Soulwire) can be used to scale a DisplayObject to fit within (fill) a rectangle, without distorting the image.

Example Usage

Fit a DisplayObject into a Rectangle

var area:Rectangle = new Rectangle( 0, 0, 200, 100 );
DisplayUtils.fitIntoRect( myDisplayObject, area, true, Alignment.MIDDLE );

Create a fullscreen background image

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

function onStageResized( event:Event = null ):void
{
	var area:Rectangle = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
	DisplayUtils.fitIntoRect( myDisplayObject, area, true, Alignment.MIDDLE );
}

stage.addEventListener( Event.RESIZE, onStageResized );
onStageResized();

Create a thumbnail

var thumb:Bitmap = DisplayUtils.createThumb( myBitmap.bitmapData, 100, 100, Alignment.MIDDLE, true );
addChild( thumb );

Initial Title
AS3  Fit DisplayObject into Rectangle

Initial Tags


Initial Language
ActionScript 3