1
9
10 import flash.geom.ColorTransform;
11 import flash.filters.ColorMatrixFilter;
12
13 import caurina.transitions.Tweener;
14 import caurina.transitions.AuxFunctions;
15
16 class caurina.transitions.properties.ColorShortcuts {
17
18
19
20
21
22
23
24 private static var LUMINANCE_R:Number = 0.212671;
25 private static var LUMINANCE_G:Number = 0.715160;
26 private static var LUMINANCE_B:Number = 0.072169;
27
28
31 public function ColorShortcuts () {
32 trace ("This is an static class and should not be instantiated.")
33 }
34
35
38 public static function init():Void {
39
40
41 Tweener.registerSpecialProperty("_color_ra", _oldColor_property_get, _oldColor_property_set, ["ra"]);
42 Tweener.registerSpecialProperty("_color_rb", _oldColor_property_get, _oldColor_property_set, ["rb"]);
43 Tweener.registerSpecialProperty("_color_ga", _oldColor_property_get, _oldColor_property_set, ["ga"]);
44 Tweener.registerSpecialProperty("_color_gb", _oldColor_property_get, _oldColor_property_set, ["gb"]);
45 Tweener.registerSpecialProperty("_color_ba", _oldColor_property_get, _oldColor_property_set, ["ba"]);
46 Tweener.registerSpecialProperty("_color_bb", _oldColor_property_get, _oldColor_property_set, ["bb"]);
47 Tweener.registerSpecialProperty("_color_aa", _oldColor_property_get, _oldColor_property_set, ["aa"]);
48 Tweener.registerSpecialProperty("_color_ab", _oldColor_property_get, _oldColor_property_set, ["ab"]);
49
50 Tweener.registerSpecialProperty("_color_redMultiplier", _color_property_get, _color_property_set, ["redMultiplier"]);
51 Tweener.registerSpecialProperty("_color_redOffset", _color_property_get, _color_property_set, ["redOffset"]);
52 Tweener.registerSpecialProperty("_color_greenMultiplier", _color_property_get, _color_property_set, ["greenMultiplier"]);
53 Tweener.registerSpecialProperty("_color_greenOffset", _color_property_get, _color_property_set, ["greenOffset"]);
54 Tweener.registerSpecialProperty("_color_blueMultiplier", _color_property_get, _color_property_set, ["blueMultiplier"]);
55 Tweener.registerSpecialProperty("_color_blueOffset", _color_property_get, _color_property_set, ["blueOffset"]);
56 Tweener.registerSpecialProperty("_color_alphaMultiplier", _color_property_get, _color_property_set, ["alphaMultiplier"]);
57 Tweener.registerSpecialProperty("_color_alphaOffset", _color_property_get, _color_property_set, ["alphaOffset"]);
58
59
60 Tweener.registerSpecialPropertySplitter("_color", _color_splitter);
61 Tweener.registerSpecialPropertySplitter("_colorTransform", _colorTransform_splitter);
62
63
64 Tweener.registerSpecialProperty("_brightness", _brightness_get, _brightness_set, [false]);
65 Tweener.registerSpecialProperty("_tintBrightness", _brightness_get, _brightness_set, [true]);
66 Tweener.registerSpecialProperty("_contrast", _contrast_get, _contrast_set);
67 Tweener.registerSpecialProperty("_hue", _hue_get, _hue_set);
68 Tweener.registerSpecialProperty("_saturation", _saturation_get, _saturation_set, [false]);
69 Tweener.registerSpecialProperty("_dumbSaturation", _saturation_get, _saturation_set, [true]);
70
71 }
72
73
74
75
76
77
78
79
80
86 public static function _color_splitter (p_value:Number, p_parameters:Array):Array {
87 var nArray:Array = new Array();
88 if (p_value == null) {
89
90 nArray.push({name:"_color_redMultiplier", value:1});
91 nArray.push({name:"_color_redOffset", value:0});
92 nArray.push({name:"_color_greenMultiplier", value:1});
93 nArray.push({name:"_color_greenOffset", value:0});
94 nArray.push({name:"_color_blueMultiplier", value:1});
95 nArray.push({name:"_color_blueOffset", value:0});
96 } else {
97
98 nArray.push({name:"_color_redMultiplier", value:0});
99 nArray.push({name:"_color_redOffset", value:AuxFunctions.numberToR(p_value)});
100 nArray.push({name:"_color_greenMultiplier", value:0});
101 nArray.push({name:"_color_greenOffset", value:AuxFunctions.numberToG(p_value)});
102 nArray.push({name:"_color_blueMultiplier", value:0});
103 nArray.push({name:"_color_blueOffset", value:AuxFunctions.numberToB(p_value)});
104 }
105 return nArray;
106 }
107
108
109
110
111
112
118 public static function _colorTransform_splitter (p_value:Object, p_parameters:Array):Array {
119 var nArray:Array = new Array();
120 if (p_value == null) {
121
122 nArray.push({name:"_color_redMultiplier", value:1});
123 nArray.push({name:"_color_redOffset", value:0});
124 nArray.push({name:"_color_greenMultiplier", value:1});
125 nArray.push({name:"_color_greenOffset", value:0});
126 nArray.push({name:"_color_blueMultiplier", value:1});
127 nArray.push({name:"_color_blueOffset", value:0});
128 } else {
129
130 if (p_value.ra != undefined) nArray.push({name:"_color_ra", value:p_value.ra});
131 if (p_value.rb != undefined) nArray.push({name:"_color_rb", value:p_value.rb});
132 if (p_value.ga != undefined) nArray.push({name:"_color_ba", value:p_value.ba});
133 if (p_value.gb != undefined) nArray.push({name:"_color_bb", value:p_value.bb});
134 if (p_value.ba != undefined) nArray.push({name:"_color_ga", value:p_value.ga});
135 if (p_value.bb != undefined) nArray.push({name:"_color_gb", value:p_value.gb});
136 if (p_value.aa != undefined) nArray.push({name:"_color_aa", value:p_value.aa});
137 if (p_value.ab != undefined) nArray.push({name:"_color_ab", value:p_value.ab});
138 if (p_value.redMultiplier != undefined) nArray.push({name:"_color_redMultiplier", value:p_value.redMultiplier});
139 if (p_value.redOffset != undefined) nArray.push({name:"_color_redOffset", value:p_value.redOffset});
140 if (p_value.blueMultiplier != undefined) nArray.push({name:"_color_blueMultiplier", value:p_value.blueMultiplier});
141 if (p_value.blueOffset != undefined) nArray.push({name:"_color_blueOffset", value:p_value.blueOffset});
142 if (p_value.greenMultiplier != undefined) nArray.push({name:"_color_greenMultiplier", value:p_value.greenMultiplier});
143 if (p_value.greenOffset != undefined) nArray.push({name:"_color_greenOffset", value:p_value.greenOffset});
144 if (p_value.alphaMultiplier != undefined) nArray.push({name:"_color_alphaMultiplier", value:p_value.alphaMultiplier});
145 if (p_value.alphaOffset != undefined) nArray.push({name:"_color_alphaOffset", value:p_value.alphaOffset});
146 }
147 return nArray;
148 }
149
150
151
152
153
154
155
156
157
161 public static function _oldColor_property_get (p_obj:Object, p_parameters:Array):Number {
162 return (new Color(p_obj)).getTransform()[p_parameters[0]];
163 }
164 public static function _oldColor_property_set (p_obj:Object, p_value:Number, p_parameters:Array):Void {
165 var cfObj:Object = new Object();
166 cfObj[p_parameters[0]] = p_value;
167 (new Color(p_obj)).setTransform(cfObj);
168 }
169
170
174 public static function _color_property_get (p_obj:Object, p_parameters:Array):Number {
175 return p_obj.transform.colorTransform[p_parameters[0]];
176 }
177 public static function _color_property_set (p_obj:Object, p_value:Number, p_parameters:Array):Void {
178 var cfm:ColorTransform = p_obj.transform.colorTransform;
179 cfm[p_parameters[0]] = p_value;
180 p_obj.transform.colorTransform = cfm;
181 }
182
183
184
185
186
190 public static function _brightness_get (p_obj:Object, p_parameters:Array):Number {
191
192 var isTint:Boolean = p_parameters[0];
193
194
202
203 var cfm:Object = (new Color(p_obj)).getTransform();
204 var mc:Number = 1 - ((cfm.ra + cfm.ga + cfm.ba) / 300);
205 var co:Number = (cfm.rb + cfm.gb + cfm.bb) / 3;
206
207 if (isTint) {
208
209 return co > 0 ? co / 255 : -mc;
210 } else {
211
212 return co / 100;
213 }
214 }
215 public static function _brightness_set (p_obj:Object, p_value:Number, p_parameters:Array):Void {
216
217
218 var isTint:Boolean = p_parameters[0];
219
220 var mc:Number;
221 var co:Number;
222
223 if (isTint) {
224
225 mc = 1 - Math.abs(p_value);
226 co = p_value > 0 ? Math.round(p_value*255) : 0;
227 } else {
228
229 mc = 1;
230 co = Math.round(p_value*100);
231 }
232
233
243 var cfm:Object = {ra:mc * 100, rb:co, ga:mc * 100, gb:co, ba:mc * 100, bb:co};
244 (new Color(p_obj)).setTransform(cfm);
245 }
246
247
251 public static function _saturation_get (p_obj:Object, p_parameters:Array):Number {
252
253 var mtx:Array = getObjectMatrix(p_obj);
254
255 var isDumb:Boolean = p_parameters[0];
256 var rl:Number = isDumb ? 1/3 : LUMINANCE_R;
257 var gl:Number = isDumb ? 1/3 : LUMINANCE_G;
258 var bl:Number = isDumb ? 1/3 : LUMINANCE_B;
259
260 var mc:Number = ((mtx[0]-rl)/(1-rl) + (mtx[6]-gl)/(1-gl) + (mtx[12]-bl)/(1-bl)) / 3;
261 var cc:Number = 1 - ((mtx[1]/gl + mtx[2]/bl + mtx[5]/rl + mtx[7]/bl + mtx[10]/rl + mtx[11]/gl) / 6);
262 return (mc + cc) / 2;
263 }
264 public static function _saturation_set (p_obj:Object, p_value:Number, p_parameters:Array):Void {
265
266 var isDumb:Boolean = p_parameters[0];
267 var rl:Number = isDumb ? 1/3 : LUMINANCE_R;
268 var gl:Number = isDumb ? 1/3 : LUMINANCE_G;
269 var bl:Number = isDumb ? 1/3 : LUMINANCE_B;
270
271 var sf:Number = p_value;
272 var nf:Number = 1-sf;
273 var nr:Number = rl * nf;
274 var ng:Number = gl * nf;
275 var nb:Number = bl * nf;
276
277 var mtx:Array = [
278 nr+sf, ng, nb, 0, 0,
279 nr, ng+sf, nb, 0, 0,
280 nr, ng, nb+sf, 0, 0,
281 0, 0, 0, 1, 0
282 ];
283 setObjectMatrix(p_obj, mtx);
284 }
285
286
290 public static function _contrast_get (p_obj:Object, p_parameters:Array):Number {
291
292
299 var cfm:Object = (new Color(p_obj)).getTransform();
300 var mc:Number;
301 var co:Number;
302 mc = ((cfm.ra + cfm.ga + cfm.ba) / 300) - 1;
303 co = (cfm.rb + cfm.gb + cfm.bb) / 3 / -128;
304
315
316 return (mc+co)/2;
317 }
318 public static function _contrast_set (p_obj:Object, p_value:Number, p_parameters:Array):Void {
319
320 var mc:Number;
321 var co:Number;
322 mc = p_value + 1;
323 co = Math.round(p_value*-128);
324
325
336
337
338
339
349 var cfm:Object = {ra:mc * 100, rb:co, ga:mc * 100, gb:co, ba:mc * 100, bb:co};
350 (new Color(p_obj)).setTransform(cfm);
351 }
352
353
357 public static function _hue_get (p_obj:Object, p_parameters:Array):Number {
358
359 var mtx:Array = getObjectMatrix(p_obj);
360
361
362
363
364
365
366
367 var hues:Array = [];
368 hues[0] = {angle:-179.9, matrix:getHueMatrix(-179.9)};
369 hues[1] = {angle:180, matrix:getHueMatrix(180)};
370
371 for (var i:Number = 0; i < hues.length; i++) {
372 hues[i].distance = getHueDistance(mtx, hues[i].matrix);
373 }
374
375 var maxTries:Number = 15;
376 var angleToSplit:Number;
377
378 for (var i:Number = 0; i < maxTries; i++) {
379
380 if (hues[0].distance < hues[1].distance) {
381
382 angleToSplit = 1;
383 } else {
384
385 angleToSplit = 0;
386 }
387 hues[angleToSplit].angle = (hues[0].angle + hues[1].angle)/2;
388 hues[angleToSplit].matrix = getHueMatrix(hues[angleToSplit].angle)
389 hues[angleToSplit].distance = getHueDistance(mtx, hues[angleToSplit].matrix);
390 }
391
392 return hues[angleToSplit].angle;
393 }
394
395 public static function _hue_set (p_obj:Object, p_value:Number, p_parameters:Array):Void {
396 setObjectMatrix(p_obj, getHueMatrix(p_value));
397 }
398
399 public static function getHueDistance (mtx1:Array, mtx2:Array): Number {
400 return (Math.abs(mtx1[0] - mtx2[0]) + Math.abs(mtx1[1] - mtx2[1]) + Math.abs(mtx1[2] - mtx2[2]));
401 }
402
403 public static function getHueMatrix (hue:Number): Array {
404 var ha:Number = hue * Math.PI/180;
405
406 var rl:Number = LUMINANCE_R;
407 var gl:Number = LUMINANCE_G;
408 var bl:Number = LUMINANCE_B;
409
410 var c:Number = Math.cos(ha);
411 var s:Number = Math.sin(ha);
412
413 var mtx:Array = [
414 (rl + (c * (1 - rl))) + (s * (-rl)),
415 (gl + (c * (-gl))) + (s * (-gl)),
416 (bl + (c * (-bl))) + (s * (1 - bl)),
417 0, 0,
418
419 (rl + (c * (-rl))) + (s * 0.143),
420 (gl + (c * (1 - gl))) + (s * 0.14),
421 (bl + (c * (-bl))) + (s * -0.283),
422 0, 0,
423
424 (rl + (c * (-rl))) + (s * (-(1 - rl))),
425 (gl + (c * (-gl))) + (s * gl),
426 (bl + (c * (1 - bl))) + (s * bl),
427 0, 0,
428
429 0, 0, 0, 1, 0
430 ];
431
432 return mtx;
433 }
434
435
436
437
438
439 private static function getObjectMatrix(p_obj:Object): Array {
440
441 for (var i:Number = 0; i < p_obj.filters.length; i++) {
442 if (p_obj.filters[i] instanceof ColorMatrixFilter) {
443 return p_obj.filters[i].matrix.concat();
444 }
445 }
446 return [
447 1, 0, 0, 0, 0,
448 0, 1, 0, 0, 0,
449 0, 0, 1, 0, 0,
450 0, 0, 0, 1, 0
451 ];
452 }
453
454 private static function setObjectMatrix(p_obj:Object, p_matrix:Array): Void {
455
456 var objFilters:Array = p_obj.filters.concat();
457 var found:Boolean = false;
458 for (var i:Number = 0; i < objFilters.length; i++) {
459 if (objFilters[i] instanceof ColorMatrixFilter) {
460 objFilters[i].matrix = p_matrix.concat();
461 found = true;
462 }
463 }
464 if (!found) {
465
466 var cmtx:ColorMatrixFilter = new ColorMatrixFilter(p_matrix);
467 objFilters[objFilters.length] = cmtx;
468 }
469 p_obj.filters = objFilters;
470 }
471 }
472