negush blog

Flash, ActionScript and stuff…

March-8-09

Loader class with content scaling

posted by negush

Some time ago I needed a loader object that would allow scaling the content. So I simply created a class that extends the Loader class itself and adds that extra feature to it. The scaling occurs write after the content has been loaded and during resizing. I’ve named the class SimpleLoader and it has a Boolean property that allows the scaling when set to true, otherwise it just behaves like the standard Loader class.

I thought I should share it with you, so here it is. The class is documented so you should have no problem understanding it. Feel free to use it as you like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package {
 
	import flash.display.Loader;
	import flash.events.Event;
 
 
	/**
	 * class SimpleLoader
	 * 
	 * @author negush
	 */
	public class SimpleLoader extends Loader {
 
		/**
		 * The width and height setters have effect only after the content has been loaded.
		 */
 
		private var _scale:Boolean = false;
		private var _width:Number = 0;
		private var _height:Number = 0;
 
		private var scaleRatio:Number;
 
 
		/**
		 * Constructor.
		 */
		public function SimpleLoader() {
			super();
			this.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
		}
 
 
		/**
		 * Handler function for the Event.COMPLETE event. Initializes the width and height of the
		 * content and calculates the scale ratio of the image, used when the loader is resized
		 * with the content being scaled. Catches the Loader's event and dispatches it as SimpleLoader.
		 */
		private function completeHandler(evt:Event):void {
			// The initial size of the content.
			this._width = this.contentLoaderInfo.width;
			this._height = this.contentLoaderInfo.height;
			// The scale ratio content_width / content_height.
			this.scaleRatio = this.contentLoaderInfo.width / this.contentLoaderInfo.height;
			if (this.scale) scaleToWidth();
			var newEvent:Event = new Event(Event.COMPLETE);
			dispatchEvent(evt);
		}
 
 
		/**
		 * Resizes the loader keeping the aspect ratio according to the new width. In this case the
		 * new height is calculated so that the content keeps its aspect ratio according to the
		 * loader's new width.
		 */
		private function scaleToWidth():void {
			this._height = Math.round(this.width / this.scaleRatio);
			super.width = this._width;
			super.height = this._height;
		}
 
 
		/**
		 * Resizes the loader keeping the aspect ratio according to the new height. In this case the
		 * new width is calculated so that the content keeps its aspect ratio according to the
		 * loader's new height.
		 */
		private function scaleToHeight():void {
			this._width = Math.round(this.height * this.scaleRatio);
			super.width = this._width;
			super.height = this._height;
		}
 
 
		//***********************************************************************
		//
		//	getters and setters
		//
		//***********************************************************************
 
		/**
		 * Setter/getter for the _scale property. Activates or deactivates the scaling for the
		 * current loader instance. If the scale is set to true, the content's height will be
		 * recalculated so that the content keeps the current width but will have the original
		 * aspect ratio.
		 * 
		 * true = resize keeping content aspect ratio
		 * false = resize without keeping content aspect ratio
		 * 
		 */
		public function set scale(value:Boolean):void {
			if (this._scale == value) return;
			this._scale = value;
			if (value) scaleToWidth();
		}
 
		public function get scale():Boolean {
			return this._scale;
		}
 
 
		/**
		 * Overrides the Loader's width setter and getter. The setter resizes the content
		 * according to the scale property's value.
		 */
		override public function set width(value:Number):void {
			if (this._width == value) return;
			this._width = value;
			if (this.scale) scaleToWidth();
			else super.width = value;
		}
 
		override public function get width():Number {
			return this._width;
		}
 
 
		/**
		 * Overrides the Loader's height setter and getter. The setter resizes the content
		 * according to the scale property's value.
		 */
		override public function set height(value:Number):void {
			if (this._height == value) return;
			this._height = value;
			if (this.scale) scaleToHeight();
			else super.height = value;
		}
 
		override public function get height():Number {
			return this._height;
		}
 
	}
 
}

UPDATE:
And here is how you can use it. It works just like the Loader class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import SimpleLoader;
 
var ldr:SimpleLoader = new SimpleLoader();
ldr.load(new URLRequest("myimage.jpg"));
ldr.x = 20;
ldr.y = 20;
ldr.scale = true;
addChild(ldr);
 
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
 
function completeHandler(evt:Event):void {
	ldr.width = 300;
	ldr.height = 100;
	trace("loader size: "+ldr.width+" x "+ldr.height);
}