1 /** 2 * properties.CurveModifiers 3 * List of default special properties modifiers for the Tweener class 4 * The function names are strange/inverted because it makes for easier debugging (alphabetic order). They're only for internal use (on this class) anyways. 5 * 6 * @author Zeh Fernando, Nate Chatellier, Arthur Debert 7 * @version 1.0.0 8 */ 9 10 import caurina.transitions.Tweener; 11 12 class caurina.transitions.properties.CurveModifiers { 13 14 /** 15 * There's no constructor. 16 */ 17 public function CurveModifiers () { 18 trace ("This is an static class and should not be instantiated.") 19 } 20 21 /** 22 * Registers all the special properties to the Tweener class, so the Tweener knows what to do with them. 23 */ 24 public static function init():Void { 25 26 // Bezier modifiers 27 Tweener.registerSpecialPropertyModifier("_bezier", _bezier_modifier, _bezier_get); 28 } 29 30 31 // ================================================================================================================================== 32 // SPECIAL PROPERTY MODIFIER functions ---------------------------------------------------------------------------------------------- 33 34 // ---------------------------------------------------------------------------------------------------------------------------------- 35 // _bezier 36 37 /** 38 * Given the parameter object passed to this special property, return an array listing the properties that should be modified, and their parameters 39 * 40 * @param p_obj Object Parameter passed to this property 41 * @return Array Array listing name and parameter of each property 42 */ 43 public static function _bezier_modifier (p_obj:Object):Array { 44 var mList:Array = []; // List of properties to be modified 45 var pList:Array; // List of parameters passed, normalized as an array 46 if (p_obj instanceof Array) { 47 // Complex 48 pList = p_obj.concat(); 49 } else { 50 pList = [p_obj]; 51 } 52 53 var i:Number; 54 var istr:String; 55 var mListObj:Object = {}; // Object describing each property name and parameter 56 57 for (i = 0; i < pList.length; i++) { 58 for (istr in pList[i]) { 59 if (mListObj[istr] == undefined) mListObj[istr] = []; 60 mListObj[istr].push(pList[i][istr]); 61 } 62 } 63 for (istr in mListObj) { 64 mList.push({name:istr, parameters:mListObj[istr]}); 65 } 66 return mList; 67 } 68 69 /** 70 * Given tweening specifications (beging, end, t), applies the property parameter to it, returning new t 71 * 72 * @param b Number Beginning value of the property 73 * @param e Number Ending (desired) value of the property 74 * @param t Number Current t of this tweening (0-1), after applying the easing equation 75 * @param p Array Array of parameters passed to this specific property 76 * @return Number New t, with the p parameters applied to it 77 */ 78 public static function _bezier_get (b:Number, e:Number, t:Number, p:Array):Number { 79 // This is based on Robert Penner's code 80 if (p.length == 1) { 81 // Simple curve with just one bezier control point 82 return b + t*(2*(1-t)*(p[0]-b) + t*(e - b)); 83 } else { 84 // Array of bezier control points, must find the point between each pair of bezier points 85 var ip:Number = Math.floor(t * p.length); // Position on the bezier list 86 var it:Number = (t - (ip * (1 / p.length))) * p.length; // t inside this ip 87 var p1:Number, p2:Number; 88 if (ip == 0) { 89 // First part: belongs to the first control point, find second midpoint 90 p1 = b; 91 p2 = (p[0]+p[1])/2; 92 } else if (ip == p.length - 1) { 93 // Last part: belongs to the last control point, find first midpoint 94 p1 = (p[ip-1]+p[ip])/2; 95 p2 = e; 96 } else { 97 // Any middle part: find both midpoints 98 p1 = (p[ip-1]+p[ip])/2; 99 p2 = (p[ip]+p[ip+1])/2; 100 } 101 return p1+it*(2*(1-it)*(p[ip]-p1) + it*(p2 - p1)); 102 } 103 } 104 } 105