/**
* Copyright (c) 2008 Donovan Adams, http://blog.hydrotik.com - donovan (at) hydrotik (dot) com
* Copyright (c) 2007 Moses Gunesch, http://www.goasap.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.hydrotik.go {
import org.goasap.utils.SequenceCA;
import org.goasap.utils.SequenceStepCA;
import org.goasap.utils.customadvance.SequenceAdvance;
import org.goasap.utils.customadvance.OnPlayableComplete;
import org.goasap.managers.LinearGoRepeater;
import org.goasap.managers.OverlapMonitor;
import org.goasap.GoEngine;
import org.goasap.events.GoEvent;
import org.goasap.utils.PlayableGroup;
import org.goasap.interfaces.IPlayable;
import flash.utils.Dictionary;
import org.goasap.interfaces.IManageable;
import org.goasap.items.LinearGo;
import flash.display.DisplayObject;
import flash.filters.BevelFilter;
import flash.filters.BitmapFilter;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
public class HydroTween extends LinearGo implements IManageable {
/*
* HydroTween
*
* @author: Donovan Adams, E-Mail: donovan[(at)]hydrotik.com, url: http://blog.hydrotik.com/
* @author: Based on Moses Gunesch Go engine, http://www.goasap.org/ - Thanks Mo!
* @version: 0.4.4
*
* @description HydroTween is a generic tweening syntax parser for the Go tweening engine.
*
*
* @example
*
* HydroTween.go(target, {width:760}, .8, 0, Exponential.easeInOut, onCompleteHandler);
*
*
*
*
BENCHMARK PROGRESSION
Benchmarks:
********
Go 0.3.0
Benchmark results: Go - HydroBenchmark (MacBook Pro Test Dual 2.16) Dec 20, 2007 8:39 PM
------------------
100 Sprites :: Start Lag: 0.01 seconds :: FPS: 50
200 Sprites :: Start Lag: 0.01 seconds :: FPS: 50
400 Sprites :: Start Lag: 0.02 seconds :: FPS: 50
800 Sprites :: Start Lag: 0.03 seconds :: FPS: 50
1600 Sprites :: Start Lag: 0.08 seconds :: FPS: 35
3200 Sprites :: Start Lag: 0.11 seconds :: FPS: 25
6400 Sprites :: Start Lag: 0.26 seconds :: FPS: 8
Benchmark results: Go - HydroBenchmark (PowerPC Quad 2.5) Dec 21, 2007 10:08 AM
------------------
100 Sprites :: Start Lag: 0.02 seconds :: FPS: 50
200 Sprites :: Start Lag: 0.02 seconds :: FPS: 50
400 Sprites :: Start Lag: 0.04 seconds :: FPS: 48
800 Sprites :: Start Lag: 0.04 seconds :: FPS: 44
1600 Sprites :: Start Lag: 0.16 seconds :: FPS: 27
3200 Sprites :: Start Lag: 0.15 seconds :: FPS: 10
********
Go 0.4.0
Benchmark: Go - HydroBenchmark
Benchmark results: Go - HydroBenchmark (PowerPC Quad 2.5) Jan 9, 2008 4:08 AM
------------------
100 Sprites :: Start Lag: 0.01 seconds :: FPS: 96 :: End lag: 0.01
200 Sprites :: Start Lag: 0.04 seconds :: FPS: 93 :: End lag: 0.03
400 Sprites :: Start Lag: 0.06 seconds :: FPS: 91 :: End lag: 0.12
800 Sprites :: Start Lag: 0.06 seconds :: FPS: 81 :: End lag: 0.41
1600 Sprites :: Start Lag: 0.16 seconds :: FPS: 59 :: End lag: 1.74
3200 Sprites :: Start Lag: 0.18 seconds :: FPS: 25 :: End lag: 7.7
6400 Sprites :: Start Lag: 0.4 seconds :: FPS: 2 :: End lag: 15.08
*********
Go 0.4.3
Benchmark results: HydroTween - (PowerPC Quad 2.5) Feb 26, 2008 11:49 AM
------------------
100 Sprites :: Start Lag: 0.03 seconds :: FPS: 96 :: End lag: 0.01
200 Sprites :: Start Lag: 0.03 seconds :: FPS: 95 :: End lag: 0.03
400 Sprites :: Start Lag: 0.06 seconds :: FPS: 90 :: End lag: 0.11
800 Sprites :: Start Lag: 0.05 seconds :: FPS: 72 :: End lag: 0.45
1600 Sprites :: Start Lag: 0.1 seconds :: FPS: 42 :: End lag: 1.89
3200 Sprites :: Start Lag: 0.22 seconds :: FPS: 18 :: End lag: 8.58
Test flatlined! (0-FPS seconds:15)
6400 Sprites :: Start Lag: 0.48 seconds :: FPS: 1 :: End lag: 15.08
*********
Go 0.4.4
Benchmark results: HydroTween - (PowerPC Quad 2.5) Feb 28, 2008 12:49 PM - PRE OPT
------------------
100 Sprites :: Start Lag: 0.02 seconds :: FPS: 96 :: End lag: 0.01
200 Sprites :: Start Lag: 0.02 seconds :: FPS: 93 :: End lag: 0.03
400 Sprites :: Start Lag: 0.05 seconds :: FPS: 90 :: End lag: 0.1
800 Sprites :: Start Lag: 0.06 seconds :: FPS: 71 :: End lag: 0.38
1600 Sprites :: Start Lag: 0.12 seconds :: FPS: 43 :: End lag: 1.76
3200 Sprites :: Start Lag: 0.25 seconds :: FPS: 18 :: End lag: 7.95
Test flatlined! (0-FPS seconds:15)
6400 Sprites :: Start Lag: 0.54 seconds :: FPS: 1 :: End lag: 15.07
Benchmark results: HydroTween - (PowerPC Quad 2.5) Feb 28, 2008 2:34 AM - SWITCH DETECTION OF PROPS
------------------
100 Sprites :: Start Lag: 0.03 seconds :: FPS: 96 :: End lag: 0.01
200 Sprites :: Start Lag: 0.04 seconds :: FPS: 95 :: End lag: 0.03
400 Sprites :: Start Lag: 0.03 seconds :: FPS: 95 :: End lag: 0.11
800 Sprites :: Start Lag: 0.07 seconds :: FPS: 79 :: End lag: 0.43
1600 Sprites :: Start Lag: 0.12 seconds :: FPS: 52 :: End lag: 1.94
3200 Sprites :: Start Lag: 0.19 seconds :: FPS: 22 :: End lag: 8.89
Test flatlined! (0-FPS seconds:15)
6400 Sprites :: Start Lag: 0.43 seconds :: FPS: 2 :: End lag: 15.07
Benchmark results: HydroTween - (PowerPC Quad 2.5) Mar 6, 2008 3:57 PM - Externalized Props/START/READ VALUES BROKEN
------------------
100 Sprites :: Start Lag: 0.01 seconds :: FPS: 95 :: End lag: 0
200 Sprites :: Start Lag: 0.02 seconds :: FPS: 93 :: End lag: 0.01
400 Sprites :: Start Lag: 0.05 seconds :: FPS: 86 :: End lag: 0.01
800 Sprites :: Start Lag: 0.05 seconds :: FPS: 73 :: End lag: 0.02
1600 Sprites :: Start Lag: 0.12 seconds :: FPS: 45 :: End lag: 0.04
3200 Sprites :: Start Lag: 0.23 seconds :: FPS: 19 :: End lag: 0.07
6400 Sprites :: Start Lag: 0.42 seconds :: FPS: 5 :: End lag: 0.15
12800 Sprites :: Start Lag: 0.86 seconds :: FPS: 2 :: End lag: 0.29
Benchmark results: Go - HydroBenchmark - NEW VERSION - MacPro 2 x 3.0GHz dual Core May 6, 2008 12:54
------------------
100 Sprites :: Start Lag: 0.01 seconds :: FPS: 97 :: End lag: 0.02
200 Sprites :: Start Lag: 0.01 seconds :: FPS: 97 :: End lag: 0.01
400 Sprites :: Start Lag: 0.02 seconds :: FPS: 97 :: End lag: 0.04
800 Sprites :: Start Lag: 0.04 seconds :: FPS: 95 :: End lag: 0.16
1600 Sprites :: Start Lag: 0.08 seconds :: FPS: 84 :: End lag: 0.62
3200 Sprites :: Start Lag: 0.14 seconds :: FPS: 61 :: End lag: 2.46
***********************************************************************************************/
public static const VERSION:String = "HydroTween 0.4.8 rev30 / Go 0.4.8jg1";
public static const INFO:String = VERSION + " (c) Donovan Adams/Moses Gunesch, MIT Licensed.";
public static var VERBOSE : Boolean = true;
public static var AUTOSTART : Boolean = true;
private static var _init : Boolean = false;
// DEFAULTS
protected var _target : Object;
protected var _closure : Function;
protected var _update : Function;
protected var _tweenStartProps : Dictionary = new Dictionary(true);
protected var _htweens : Dictionary = new Dictionary(true);
protected static var _propertyList:Dictionary = new Dictionary(true);
protected var _tweenList:Dictionary = new Dictionary(true);
private static var _r_lum:Number = 0.212671;
private static var _g_lum:Number = 0.715160;
private static var _b_lum:Number = 0.072169;
private static const DELTA_INDEX:Array = [
0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11,
0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24,
0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42,
0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68,
0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98,
1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54,
1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25,
2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8,
4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0,
7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8,
10.0
];
private static const IDENTITY:Array = [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
0,0,0,0,1];
protected var _matrix : Array = [];
protected var _changeMatrix : Array = [];
protected var _startMatrix : Array = [];
public static function go(target : Object = null,
propsTo : Object = null,
duration : Number = NaN,
delay : Number = NaN,
easing : Function = null,
closure : Function = null,
update : Function = null,
extraEasingParams : Array = null,
repeater : Object=null,
useRelative : Boolean = false,
useRounding : Boolean = false,
pulseInterval : Number = NaN
) : IPlayable {
if(!_init) {
if(!GoEngine.getManager("OverlapMonitor")) GoEngine.addManager(new OverlapMonitor());
_propertyList["x"] = {prop:"x", read:genericRead, write:genericWrite};
_propertyList["y"] = {prop:"y", read:genericRead, write:genericWrite};
_propertyList["scaleX"] = {prop:"scaleX", read:genericRead, write:genericWrite};
_propertyList["scaleY"] = {prop:"scaleY", read:genericRead, write:genericWrite};
_propertyList["width"] = {prop:"width", read:genericRead, write:genericWrite};
_propertyList["height"] = {prop:"height", read:genericRead, write:genericWrite};
_propertyList["rotation"] = {prop:"rotation", read:genericRead, write:genericWrite};
_propertyList["alpha"] = {prop:"alpha", read:genericRead, write:genericWrite};
// BevelFilter ----------------------------------------------------------------------------
_propertyList["Bevel_angle"] = {prop:"angle", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_blurX"] = {prop:"blurX", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_blurY"] = {prop:"blurY", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_color"] = {prop:"color", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_distance"] = {prop:"distance", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_highlightAlpha"] = {prop:"highlightAlpha", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_highlightColor"] = {prop:"highlightColor", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_quality"] = {prop:"quality", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_shadowAlpha"] = {prop:"shadowAlpha", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_shadowColor"] = {prop:"shadowColor", definition: BevelFilter, read:filterRead, write:filterWrite};
_propertyList["Bevel_strength"] = {prop:"strength", definition: BevelFilter, read:filterRead, write:filterWrite};
// BlurFilter ----------------------------------------------------------------------------
_propertyList["Blur_blurX"] = {prop:"blurX", definition: BlurFilter, read:filterRead, write:filterWrite};
_propertyList["Blur_blurY"] = {prop:"blurY", definition: BlurFilter, read:filterRead, write:filterWrite};
_propertyList["Blur_quality"] = {prop:"quality", definition: BlurFilter, read:filterRead, write:filterWrite};
// DropShadowFilter ----------------------------------------------------------------------------
_propertyList["DropShadow_alpha"] = {prop:"alpha", definition: DropShadowFilter, read:filterRead, write:filterWrite};
_propertyList["DropShadow_angle"] = {prop:"angle", definition: DropShadowFilter, read:filterRead, write:filterWrite};
_propertyList["DropShadow_blurX"] = {prop:"blurX", definition: DropShadowFilter, read:filterRead, write:filterWrite};
_propertyList["DropShadow_blurY"] = {prop:"blurY", definition: DropShadowFilter, read:filterRead, write:filterWrite};
_propertyList["DropShadow_color"] = {prop:"color", definition: DropShadowFilter, read:filterRead, write:filterWrite};
_propertyList["DropShadow_distance"] = {prop:"distance", definition: DropShadowFilter, read:filterRead, write:filterWrite};
_propertyList["DropShadow_quality"] = {prop:"quality", definition: DropShadowFilter, read:filterRead, write:filterWrite};
_propertyList["DropShadow_strength"] = {prop:"strength", definition: DropShadowFilter, read:filterRead, write:filterWrite};
// GlowFilter ----------------------------------------------------------------------------
_propertyList["Glow_alpha"] = {prop:"alpha", definition: GlowFilter, read:filterRead, write:filterWrite};
_propertyList["Glow_blurX"] = {prop:"blurX", definition: GlowFilter, read:filterRead, write:filterWrite};
_propertyList["Glow_blurY"] = {prop:"blurY", definition: GlowFilter, read:filterRead, write:filterWrite};
_propertyList["Glow_color"] = {prop:"color", definition: GlowFilter, read:filterRead, write:filterWrite};
_propertyList["Glow_quality"] = {prop:"quality", definition: GlowFilter, read:filterRead, write:filterWrite};
_propertyList["Glow_strength"] = {prop:"strength", definition: GlowFilter, read:filterRead, write:filterWrite};
// Image ----------------------------------------------------------------------------
_propertyList["matrix"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustMatrix};
_propertyList["brightness"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustBrightness};
_propertyList["contrast"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustContrast};
_propertyList["saturation"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustSaturation};
_propertyList["hue"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustHue};
_propertyList["tint"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustColor};
// Hex ----------------------------------------------------------------------------
_propertyList["color"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustHex};
//_propertyList["color"] = {prop:"color", definition: ColorMatrixFilter, read:hexRead, write:hexWrite};
_init = true;
}
//TODO see if I can attach the curry method for accessing arguments to the read and write functions instead of in the update handler
//trace("Curry: "+partial_apply(HydroTween["multiply"])(2)(10));
/*
private static function multiply(x:uint, y:uint):uint { return x * y; }
private static function partial_apply(f:Function):Function{
return function():Function{
var partial_arguments:Array = arguments.slice();
return function():* {
partial_arguments = partial_arguments.concat(arguments);
return f.apply(null, partial_arguments);
};
};
}
*/
var go:IPlayable;
var group:PlayableGroup;
var targArray:Array;
var isGroup:Boolean = target is Array;
if (isGroup) {
group = new PlayableGroup;
go = group;
targArray = target as Array;
}
else {
targArray = [ target ];
}
for each (var targ:DisplayObject in targArray) {
var tween: HydroTween = new HydroTween(
target,
propsTo,
duration,
delay,
easing,
closure,
update,
extraEasingParams,
repeater,
useRelative,
useRounding,
pulseInterval
);
if (isGroup)
group.addChild(tween);
else
go = tween;
}
//TODO Auto Play? Was deactivated for sequencing compatibility
if(AUTOSTART) go.start();
return go;
}
public static function sequence(...actions): SequenceCA {
if(AUTOSTART) AUTOSTART = false;
var seq:SequenceCA = new SequenceCA();
for (var i:int = 0; i -1) return true;
}
}
return false;
}
// When there's a conflict the manager calls this method so you can stop the tween.
public function releaseHandling(...params) : void {
//trace(this + " releaseHandling()");
super.stop();
}
/* ****************************************************************************************
PROPERTY UPDATERS
******************************************************************************************/
//Generic ---------------------------------------------------------------------------------
protected static function genericRead(targ:DisplayObject, prop:String):Number {
return targ[prop];
}
protected static function genericWrite(targ:DisplayObject, prop:String, val:Number):void {
targ[prop] = val;
}
//Filter ---------------------------------------------------------------------------------
protected static function filterRead(targ:DisplayObject, key:String):* {
var defVals:BitmapFilter;
var filters:Array = targ.filters;
for (var i:int = 0; i < targ.filters.length; i++) {
if (filters[i] is _propertyList[key].definition) {
return (targ.filters[i][_propertyList[key].prop]);
}
}
defVals = getFilterDefaults()[_propertyList[key].definition];
return defVals[_propertyList[key].prop];
}
protected static function filterWrite(targ:DisplayObject, key:String, val:*): void {
var filters:Array = targ.filters;
var filter:BitmapFilter;
for (var i:int = 0; i < filters.length; i++) {
if (filters[i] is _propertyList[key].definition) {
filters[i][_propertyList[key].prop] = val;
targ.filters = filters;
return;
}
}
if (filters == null) filters = new Array();
filter = getFilterDefaults()[_propertyList[key].definition];
filter[_propertyList[key].prop] = val;
filters.push(filter);
targ.filters = filters;
}
//Matrix/Color ---------------------------------------------------------------------------------
private function scalarWrite(element:*, index:int, arr:Array):Number {
return (_startMatrix[index] + _changeMatrix[index] * _position);
}
private function scalarSubtraction(element:*, index:int, arr:Array):Number {
return element - _startMatrix[index];
}
// Borrowed and tweaked w/permission from Grant Skinner's
// ColorMatrix AS3 Class - thanks Grant!
// http://www.gskinner.com/blog/archives/2007/12/colormatrix_upd.html
public static function adjustMatrix(array:Array, val:Array):Array {
return multiplyMatrix(array, val);
}
public static function adjustColor(array:Array, rgb:Number, amount:Number = 1):Array {
if (rgb == -1) return multiplyMatrix(IDENTITY, array);
var r:Number = ((rgb >> 16) & 0xff) / 255;
var g:Number = ((rgb >> 8) & 0xff) / 255;
var b:Number = (rgb & 0xff) / 255;
var inv:Number = 1 - amount;
return multiplyMatrix([inv + amount * r * _r_lum, amount * r * _g_lum, amount * r * _b_lum, 0, 0,
amount * g * _r_lum, inv + amount * g * _g_lum, amount * g * _b_lum, 0, 0,
amount * b * _r_lum, amount * b * _g_lum, inv + amount * b * _b_lum, 0, 0,
0, 0, 0, 1, 0], array);
}
public static function adjustHex(array:Array, rgb:Number, amount:Number = 1):Array {
if (rgb == -1) return multiplyMatrix(IDENTITY, array);
var r:Number = ((rgb >> 16) & 0xff) / 255;
var g:Number = ((rgb >> 8) & 0xff) / 255;
var b:Number = (rgb & 0xff) / 255;
var inv:Number = 1 - amount;
return multiplyMatrix([inv + amount * r, amount * r, amount * r, 0, 0,
amount * g, inv + amount * g, amount * g, 0, 0,
amount * b, amount * b, inv + amount * b, 0, 0,
0, 0, 0, 1, 0], array);
}
public static function adjustBrightness(array:Array, val:Number):Array {
val = cleanValue(val,10) * 100;
if (val == 0 || isNaN(val)) { return array; }
return multiplyMatrix(array, [
1,0,0,0,val,
0,1,0,0,val,
0,0,1,0,val,
0,0,0,1,0,
0,0,0,0,1
]);
}
public static function adjustContrast(array:Array, val:Number):Array {
val = cleanValue(val,1) * 100;
if (val == 0 || isNaN(val)) { return array; }
var x:Number;
if (val<0) {
x = 127+val/100*127;
} else {
x = val%1;
if (x == 0) {
x = DELTA_INDEX[val];
} else {
x = DELTA_INDEX[(val<<0)]*(1-x)+DELTA_INDEX[(val<<0)+1]*x;
}
x = x*127+127;
}
return multiplyMatrix(array, [
x/127,0,0,0,0.5*(127-x),
0,x/127,0,0,0.5*(127-x),
0,0,x/127,0,0.5*(127-x),
0,0,0,1,0,
0,0,0,0,1
]);
}
public static function adjustSaturation(array:Array, val:Number):Array {
val = cleanValue(val,10) * 100;
if (val == 0 || isNaN(val)) { return array; }
var x:Number = 1+((val > 0) ? 3*val/100 : val/100);
var _r_lum:Number = 0.3086;
var _g_lum:Number = 0.6094;
var _b_lum:Number = 0.0820;
return multiplyMatrix(array, [
_r_lum*(1-x)+x,_g_lum*(1-x),_b_lum*(1-x),0,0,
_r_lum*(1-x),_g_lum*(1-x)+x,_b_lum*(1-x),0,0,
_r_lum*(1-x),_g_lum*(1-x),_b_lum*(1-x)+x,0,0,
0,0,0,1,0,
0,0,0,0,1
]);
}
public static function adjustHue(array:Array, val:Number):Array {
val = cleanValue(val,180)/180*Math.PI;
if (val == 0 || isNaN(val)) { return array; }
var cosVal:Number = Math.cos(val);
var sinVal:Number = Math.sin(val);
return multiplyMatrix(array, [
_r_lum+cosVal*(1-_r_lum)+sinVal*(-_r_lum),_g_lum+cosVal*(-_g_lum)+sinVal*(-_g_lum),_b_lum+cosVal*(-_b_lum)+sinVal*(1-_b_lum),0,0,
_r_lum+cosVal*(-_r_lum)+sinVal*(0.143),_g_lum+cosVal*(1-_g_lum)+sinVal*(0.140),_b_lum+cosVal*(-_b_lum)+sinVal*(-0.283),0,0,
_r_lum+cosVal*(-_r_lum)+sinVal*(-(1-_r_lum)),_g_lum+cosVal*(-_g_lum)+sinVal*(_g_lum),_b_lum+cosVal*(1-_b_lum)+sinVal*(_b_lum),0,0,
0,0,0,1,0,
0,0,0,0,1
]);
}
// multiplies one matrix against another:
protected static function multiplyMatrix(array:Array, matrix:Array):Array {
var col:Array = [];
var output:Array = [];
for (var i:int=0;i<5;i++) {
for (var j:int=0;j<5;j++) {
col[j] = array[j+i*5];
}
for (j=0;j<5;j++) {
var val:Number=0;
for (var k:Number=0;k<5;k++) {
val += matrix[j+k*5]*col[k];
}
output[j+i*5] = val;
}
}
return output;
}
// make sure values are within the specified range, hue has a limit of 180, others are 100:
protected static function cleanValue(val:Number,range:Number):Number {
return Math.min(range,Math.max(-range,val));
}
// makes sure matrixes are 5x5 (25 long):
protected static function fixMatrix(matrix:Array = null):Array {
if (matrix == null) { return IDENTITY; }
if (matrix is Array) { matrix = matrix.slice(0); }
if (matrix.length < IDENTITY.length) {
matrix = matrix.slice(0,matrix.length).concat(IDENTITY.slice(matrix.length,IDENTITY.length));
} else if (matrix.length > IDENTITY.length) {
matrix = matrix.slice(0,IDENTITY.length);
}
return matrix;
}
}
}
class HydroError extends Error
{
public function HydroError(message:String)
{
super(message);
}
}