Tweener AS3 extension for color properties "_brightness", "_contrast" and "_saturation"

Posted on August 28, 2007

There are a lot of AS3 Animation packages out there, all with pros and cons. One of my favorite tools is Tweener AS3, but at its current version (v.1.0.1) it supports only few color properties such as _color, _color_ra, _color_rb and so on. However, you have the option to create your own special properties using Tweener.registerSpecialProperty. So I decided to write an extension for missing color properties _brightness, _contrast and _saturation based on the awesome ColorMatrix by Mario Klingemann. Check it out!

Example

To see this content latest Flash Player Plugin is required.

Instruction

1) Download the latest AS3 version of Tweener on Google Code.

2) Copy the following ColorMatrix.as to {yourTweenerFolder}/caurina/transitions.

  1 /**
  2  * ColorMatrix class, which provides special color properties
  3  * called "_contrast", "_brightness", "_saturation"
  4  * using Tweener AS3 (http://code.google.com/p/tweener/).
  5  *
  6  * Based on Mario Klingemanns awesome AS2 ColorMatrix v1.2
  7  * (http://www.quasimondo.com/archives/000565.php)
  8  *
  9  * @author Jens Krause [www.websector.de]
 10  * @date   08/28/07
 11  * @see        http://www.websector.de/blog/2007/08/28/tweener-as3-extension-for-color-properties-_brightness-_contrast-and-_saturation/
 12  *
 13  */
 14 
 15 package caurina.transitions
 16 {
 17     import flash.filters.ColorMatrixFilter;
 18 
 19     public class ColorMatrix
 20     {
 21         //
 22         // Luminance conversion constants
 23         private static const R_LUM:Number = 0.212671;
 24         private static const G_LUM:Number = 0.715160;
 25         private static const B_LUM: Number = 0.072169;
 26         //
 27         // min / max values for special tween properties called "_contrast"
 28         private static const MIN_CONTRAST: Number = -200;
 29         private static const MAX_CONTRAST: Number = 500;
 30         private static const STANDARD_CONTRAST: Number = 0;
 31         //
 32         // min / max values for special tween properties called "_brightness"
 33         private static const MIN_BRIGHTNESS: Number = -100;
 34         private static const MAX_BRIGHTNESS: Number = 100;
 35         private static const STANDARD_BRIGHTNESS: Number = 0;
 36         //
 37         // min / max values for special tween properties called "_saturation"
 38         private static const MIN_SATURATION: Number = -300;
 39         private static const MAX_SATURATION: Number = 300;
 40         private static const STANDARD_SATURATION: Number = 100;
 41         //
 42         // standard matrix
 43         private static const IDENTITY:Array = [ 1,0,0,0,0,
 44                                                 0,1,0,0,0,
 45                                                 0,0,1,0,0,
 46                                                 0,0,0,1,0 ];
 47         //
 48         // matrix
 49         public var matrix:Array;
 50 
 51         /**
 52         * Constructor of ColorMatrix
 53         *
 54         * @param       mat         Object  A ColorMatrix instance or an array
 55         *
 56         */
 57         function ColorMatrix (mat:Object = null)
 58         {
 59             if (mat is ColorMatrix)
 60             {
 61                 matrix = mat.matrix.concat();
 62             }
 63             else if (mat is Array)
 64             {
 65                 matrix = mat.concat();
 66             }
 67             else
 68             {
 69                 reset();
 70             }
 71         }
 72 
 73         /**
 74         * Resets the matrix to its IDENTITY
 75         *
 76         */
 77         public function reset():void
 78         {
 79             matrix = IDENTITY.concat();
 80         }
 81 
 82         /**
 83         * Clones the instance of ColorMatrix
 84         *
 85         */
 86         public function clone():ColorMatrix
 87         {
 88             return new ColorMatrix( matrix );
 89         }
 90 
 91         ///////////////////////////////////////////////////////////
 92         // brightness
 93         ///////////////////////////////////////////////////////////
 94 
 95         /**
 96         * Calculate an average of particular indexes of its matrix
 97         *
 98         * @return      Number  Value of a brightness value for using Tweener
 99         *
100         */
101         public function getBrightness (): Number
102         {
103             // average of "brightness"-indexes within matrix
104             var value: Number = (matrix[4] + matrix[9] + matrix[14]) / 3;
105             // convert back to a "valid" tween property between min and max values
106             if (value != 0) value = value * 100 / 255;
107             return Math.round(value);
108         }
109 
110         /**
111         * Changes matrix to alter brightness
112         *
113         * @param       Number  Value of Tweeners brightness property
114         *
115         */
116         public function setBrightness (value: Number):void
117         {
118             var brightness: Number = checkValue(MIN_BRIGHTNESS, MAX_BRIGHTNESS, value);
119             // converts tween property to a valid value for the matrix
120             brightness = 255 * brightness / 100;
121 
122             var mat:Array =  [  1,0,0,0, brightness,
123                                 0,1,0,0, brightness,
124                                 0,0,1,0, brightness,
125                                 0,0,0,1, 0  ];
126 
127             concat(mat);
128         }
129 
130         ///////////////////////////////////////////////////////////
131         // contrast
132         ///////////////////////////////////////////////////////////
133         /**
134         * Calculate an average of particular indexes of its matrix
135         *
136         * @return      Number      Value of a contrast value for using Tweener
137         *
138         */
139         public function getContrast (): Number
140         {
141             // average of "contrast"-indexes within matrix
142             var value: Number = (matrix[0] + matrix[6] + matrix[12]) / 3;
143             // converts back to a "valid" tween property between min and max values
144             value = (value - 1) * 100;
145             return value;
146         }
147 
148         /**
149         * Changes matrix to alter contrast
150         *
151         * @param       Number      Value of Tweeners brightness property
152         *
153         */
154         public function setContrast (value: Number):void
155         {
156             var contrast: Number = checkValue(MIN_CONTRAST, MAX_CONTRAST, value);
157             // convert tween property to a valid value for the matrix
158             contrast /= 100;
159             var scale: Number = contrast + 1;
160             var offset : Number = 128 * (1 - scale);
161 
162             var mat: Array = [  scale,    0,       0,       0,   offset,
163                                 0,       scale,    0,       0,   offset,
164                                 0,       0,       scale,    0,   offset,
165                                 0,       0,       0,       1,   0       ];
166 
167             concat(mat);
168         }
169 
170         ///////////////////////////////////////////////////////////
171         // saturation
172         ///////////////////////////////////////////////////////////
173         /**
174         * Calculate an average of particular indexes of its matrix
175         *
176         * @return      Number      Value of a saturation value for using Tweener
177         *
178         */
179         public function getSaturation (): Number
180         {
181             //
182             // uses 3 "saturation"-indexes within matrix - once per color channel - ignore the others...
183             var s1: Number = 1 - matrix[1] / G_LUM;
184             var s2: Number = 1 - matrix[2] / B_LUM;
185             var s5: Number = 1 - matrix[5] / R_LUM;
186             // average of these "saturation"-indexes
187             var value: Number;
188             value = Math.round((s1 + s2 + s5) / 3);
189             value *= 100;
190 
191             return value;
192         }
193 
194         /**
195         * Changes matrix to alter contrast
196         *
197         * @param       Number      Value of Tweeners saturation property
198         *
199         */
200         public function setSaturation (value: Number): void
201         {
202             var saturation: Number = checkValue(MIN_SATURATION, MAX_SATURATION, value);
203 
204             saturation /=  100;
205 
206             var isValue: Number = 1-saturation;
207 
208             var irlum: Number = isValue * R_LUM;
209             var iglum: Number = isValue * G_LUM;
210             var iblum: Number = isValue * B_LUM;
211 
212             var mat:Array =  [      irlum + saturation, iglum,                iblum,                0, 0,
213                                     irlum,                iglum + saturation, iblum,                0, 0,
214                                     irlum,                iglum,                iblum + saturation, 0, 0,
215                                     0,                   0,                   0,                   1, 0 ];
216 
217             concat(mat);
218         }
219 
220 
221         /**
222         * Concatenates the elements of a matrix specified in the parameter with the elements in an array and creates a new matrix
223         *
224         * @param       Array       Altered Matrix
225         *
226         */
227         public function concat(mat:Array):void
228         {
229             var temp:Array = new Array ();
230             var i:Number = 0;
231 
232             for (var y:Number = 0; y < 4; y++ )
233             {
234 
235                 for (var x:Number = 0; x < 5; x++ )
236                 {
237                     temp[i + x] =  mat[i] * matrix[x] +
238                                     mat[i+1] * matrix[x + 5] +
239                                     mat[i+2] * matrix[x + 10] +
240                                     mat[i+3] * matrix[x + 15] +
241                                     (x == 4 ? mat[i+4] : 0);
242                 }
243                 i+=5;
244             }
245 
246             matrix = temp;
247         }
248 
249         /**
250         * Instanciates a ColorMatrixFilter using ColorMatrix matrix
251         *
252         * @return      ColorMatrixFilter       ColorMatrixFilter using the matrix of a ColorMatrix instance
253         *
254         */
255         public function get filter():ColorMatrixFilter
256         {
257             return new ColorMatrixFilter(matrix);
258         }
259 
260         /**
261         * Helper method to check a value for min. and max. values within a specified range
262         *
263         * @param       Number      min. value of its range
264         * @param       Number      max. value of its range
265         * @param       Number      checked value
266         */
267         private function checkValue(minValue: Number, maxValue: Number, value: Number):Number
268         {
269             return Math.min(maxValue, Math.max(minValue, value));
270         }
271     }
272 }

3) Open SpecialPropertiesDefault.as located in {yourTweenerFolder}/caurina/transitions. Copy and paste the following lines to the method called init().

1 // color brightness
2 Tweener.registerSpecialProperty("_brightness", __brightness_get, __brightness_set);
3 // color contrast
4 Tweener.registerSpecialProperty("_contrast", __contrast_get, __contrast_set);
5 // color saturation
6 Tweener.registerSpecialProperty("_saturation", __saturation_get, __saturation_set);

4) Add the following methods to SpecialPropertiesDefault.as after the method init()mentioned above. Don't forget to import flash.display.DisplayObject and flash.filters.ColorMatrixFilter as well.

  1 // ----------------------------------------------------------------------------------------------------------------------------------
  2 // _brightness_*
  3 
  4 /**
  5  * Gets brightness using ColorMatrix
  6  *
  7  * @param      p_obj               DisplayObject   A Display Object instance
  8  * @return                         Number          Value of the brightness property
  9  */
 10 public static function __brightness_get (p_obj: DisplayObject):Number
 11 {
 12     return getColorMatrix(p_obj).getBrightness();
 13 };
 14 
 15 /**
 16  * Changes brightness of a DisplayObject using ColorMatrix
 17  *
 18  * @param      p_obj               DisplayObject   A Display Object instance
 19  * @param      p_value             Number          Value of the brightness property (min: -100 / max: 100 / standard: 0)
 20  */
 21 public static function __brightness_set (p_obj:DisplayObject, p_value:Number):void
 22 {
 23     var colorMatrix: ColorMatrix = new ColorMatrix();
 24     colorMatrix.setBrightness(p_value);
 25     setColorMatrix(p_obj, colorMatrix);
 26 };
 27 
 28 // ----------------------------------------------------------------------------------------------------------------------------------
 29 // _contrast_*
 30 /**
 31  * Gets contrast using ColorMatrix
 32  *
 33  * @param      p_obj               DisplayObject   A Display Object instance
 34  * @return                         Number          Value of the contrast property
 35  */
 36 public static function __contrast_get (p_obj: DisplayObject):Number
 37 {
 38     return getColorMatrix(p_obj).getContrast();
 39 };
 40 
 41 /**
 42  * Changes contrast of a DisplayObject using ColorMatrix
 43  *
 44  * @param      p_obj               DisplayObject   A Display Object instance
 45  * @param      p_value             Number          Value of the contrast property (min: -200 / max: 500 / standard: 0)
 46  */
 47 public static function __contrast_set (p_obj:DisplayObject, p_value:Number):void
 48 {
 49     var colorMatrix: ColorMatrix = new ColorMatrix();
 50     colorMatrix.setContrast(p_value);
 51     setColorMatrix(p_obj, colorMatrix);
 52 };
 53 
 54 // ----------------------------------------------------------------------------------------------------------------------------------
 55 // _saturation_*
 56 /**
 57  * Gets saturation using ColorMatrix
 58  *
 59  * @param      p_obj               DisplayObject   A Display Object instance
 60  * @return                         Number          Value of the saturation property
 61  */
 62 public static function __saturation_get (p_obj: DisplayObject):Number
 63 {
 64     return getColorMatrix(p_obj).getSaturation();
 65 };
 66 
 67 /**
 68  * Changes saturation of a DisplayObject using ColorMatrix
 69  *
 70  * @param      p_obj               DisplayObject   A Display Object instance
 71  * @param      p_value             Number          Value of the saturation property (min: -300 / max: 300 / standard: 100)
 72  */
 73 public static function __saturation_set (p_obj:DisplayObject, p_value:Number):void
 74 {
 75     var colorMatrix: ColorMatrix = new ColorMatrix();
 76     colorMatrix.setSaturation(p_value);
 77     setColorMatrix(p_obj, colorMatrix);
 78 };
 79 
 80 
 81 // ----------------------------------------------------------------------------------------------------------------------------------
 82 // COLORMATRIX helper functions -----------------------------------------------------------------------------------------------------
 83 
 84 /**
 85  * Helper method for getting the ColorMatrix of a DisplayObject
 86  *
 87  * @param      p_obj               DisplayObject   A Display Object instance
 88  * @return                         ColorMatrix     ColorMatrix of the Display Object
 89  */
 90 private static function getColorMatrix(p_obj: DisplayObject): ColorMatrix
 91 {
 92     var filters: Array = p_obj.filters;
 93     var colorMatrix: ColorMatrix = new ColorMatrix();
 94 
 95     var i:int = filters.length;
 96 
 97     while(--i > -1)
 98     {
 99         if(filters[i] is ColorMatrixFilter)
100         {
101             colorMatrix.matrix = filters[i].matrix.concat();
102             break;
103         }
104     }
105     return colorMatrix;
106 }
107 
108 /**
109  * Helper method for setting the ColorMatrix of a DisplayObject
110  *
111  * @param      p_obj               DisplayObject   A Display Object instance
112  * @param      p_value             ColorMatrix     A ColorMatrix instance
113  */
114 private static function setColorMatrix(p_obj: DisplayObject, value: ColorMatrix): void
115 {
116     var filters: Array = p_obj.filters;
117     var tFilters: Array = new Array();
118     var colorMatrix: ColorMatrix = value;
119 
120     var i:int = filters.length;
121 
122     while(--i > -1)
123     {
124         if(!(filters[i] is ColorMatrixFilter))
125         {
126             tFilters.push(filters[i]);
127         }
128     }
129 
130     tFilters.push(colorMatrix.filter);
131     p_obj.filters = tFilters;
132 
133 }

That's all ;-) .

And here are some examples using the special color properties:

 1 //
 2 // brightness example
 3 Tweener.addTween(myDisplayObject, {    _brightness: 100,
 4                                      time: 2,
 5                                  transition: Quintic.easeOut
 6                              });
 7 
 8 //
 9 // contrast example
10 Tweener.addTween(myDisplayObject, {    _contrast: -100,
11                                  time: 2,
12                                  delay: 2,
13                                  transition: Quintic.easeOut
14                              });
15 
16 //
17 // saturation example
18 Tweener.addTween(myDisplayObject, {    _saturation: 0,
19                                  time: 2,
20                                  delay: 4,
21                                  transition: Quintic.easeOut
22                              });

Download full source

TweenerColorMatrixExample.zip

Have fun ;-)

Update (10/07/07)

Tweeners SpecialPropertiesDefault.as has been deprecated since Tweener version 1.27.62. All listed color properties (brightness, contrast, _saturation) are now included in Tweener version 1.30.66 and higher. For more information check Tweeners changelog on Google Code. Kudos to Zeh Fernando for the latest releases.

Any feedback?

comments powered by Disqus