1
8
9
34
35 import caurina.transitions.Equations;
36 import caurina.transitions.AuxFunctions;
37 import caurina.transitions.SpecialProperty;
38 import caurina.transitions.SpecialPropertyModifier;
39 import caurina.transitions.SpecialPropertySplitter;
40 import caurina.transitions.TweenListObj;
41 import caurina.transitions.PropertyInfoObj;
42
43 class caurina.transitions.Tweener {
44
45 private static var _engineExists:Boolean = false;
46 private static var _inited:Boolean = false;
47 private static var _currentTime:Number;
48 private static var _currentTimeFrame:Number;
49
50 private static var _tweenList:Array;
51
52 private static var _timeScale:Number = 1;
53
54 private static var _transitionList:Object;
55 private static var _specialPropertyList:Object;
56 private static var _specialPropertyModifierList:Object;
57 private static var _specialPropertySplitterList:Object;
58
59
60
63 public function Tweener () {
64 trace ("Tweener is an static class and should not be instantiated.");
65 }
66
67
68
69
70
71
93 public static function addTween (p_scopes:Object, p_parameters:Object):Boolean {
94 if (p_scopes == undefined) return false;
95
96 var i:Number, j:Number, istr:String;
97
98 var rScopes:Array;
99 if (p_scopes instanceof Array) {
100
101 rScopes = p_scopes.concat();
102 } else {
103
104 rScopes = [p_scopes];
105 }
106
107
108 var p_obj:Object = TweenListObj.makePropertiesChain(p_parameters);
109
110
111 if (!_inited) init();
112 if (!_engineExists || _root[getControllerName()] == undefined) startEngine();
113
114
115 var rTime:Number = (isNaN(p_obj.time) ? 0 : p_obj.time);
116 var rDelay:Number = (isNaN(p_obj.delay) ? 0 : p_obj.delay);
117
118
119 var rProperties:Object = new Object();
120 var restrictedWords:Object = {time:true, delay:true, useFrames:true, skipUpdates:true, transition:true, transitionParams:true, onStart:true, onUpdate:true, onComplete:true, onOverwrite:true, onError:true, rounded:true, onStartParams:true, onUpdateParams:true, onCompleteParams:true, onOverwriteParams:true, onStartScope:true, onUpdateScope:true, onCompleteScope:true, onOverwriteScope:true, onErrorScope:true, quickAdd:true};
121 var modifiedProperties:Object = new Object();
122 for (istr in p_obj) {
123 if (!restrictedWords[istr]) {
124
125 if (_specialPropertySplitterList[istr] != undefined) {
126
127 var splitProperties:Array = _specialPropertySplitterList[istr].splitValues(p_obj[istr], _specialPropertySplitterList[istr].parameters);
128 for (i = 0; i < splitProperties.length; i++) {
129 if (_specialPropertySplitterList[splitProperties[i].name] != undefined) {
130 var splitProperties2:Array = _specialPropertySplitterList[splitProperties[i].name].splitValues(splitProperties[i].value, _specialPropertySplitterList[splitProperties[i].name].parameters);
131 for (j = 0; j < splitProperties2.length; j++) {
132 rProperties[splitProperties2[j].name] = {valueStart:undefined, valueComplete:splitProperties2[j].value, arrayIndex:splitProperties2[j].arrayIndex, isSpecialProperty:false};
133 }
134 } else {
135 rProperties[splitProperties[i].name] = {valueStart:undefined, valueComplete:splitProperties[i].value, arrayIndex:splitProperties[i].arrayIndex, isSpecialProperty:false};
136 }
137 }
138 } else if (_specialPropertyModifierList[istr] != undefined) {
139
140 var tempModifiedProperties:Array = _specialPropertyModifierList[istr].modifyValues(p_obj[istr]);
141 for (i = 0; i < tempModifiedProperties.length; i++) {
142 modifiedProperties[tempModifiedProperties[i].name] = {modifierParameters:tempModifiedProperties[i].parameters, modifierFunction:_specialPropertyModifierList[istr].getValue};
143 }
144 } else {
145
146 rProperties[istr] = {valueStart:undefined, valueComplete:p_obj[istr]};
147 }
148 }
149 }
150
151
152 for (istr in rProperties) {
153 if (_specialPropertyList[istr] != undefined) {
154 rProperties[istr].isSpecialProperty = true;
155 } else {
156 if (rScopes[0][istr] == undefined) {
157 printError("The property '" + istr + "' doesn't seem to be a normal object property of " + rScopes[0].toString() + " or a registered special property.");
158 }
159 }
160 }
161
162
163 for (istr in modifiedProperties) {
164 if (rProperties[istr] != undefined) {
165 rProperties[istr].modifierParameters = modifiedProperties[istr].modifierParameters;
166 rProperties[istr].modifierFunction = modifiedProperties[istr].modifierFunction;
167 }
168
169 }
170
171 var rTransition:Function;
172
173 if (typeof p_obj.transition == "string") {
174
175 var trans:String = p_obj.transition.toLowerCase();
176 rTransition = _transitionList[trans];
177 } else {
178
179 rTransition = p_obj.transition;
180 }
181 if (rTransition == undefined) rTransition = _transitionList["easeoutexpo"];
182
183 var nProperties:Object;
184 var nTween:TweenListObj;
185 var myT:Number;
186
187 for (i = 0; i < rScopes.length; i++) {
188
189 nProperties = new Object();
190 for (istr in rProperties) {
191 nProperties[istr] = new PropertyInfoObj(rProperties[istr].valueStart, rProperties[istr].valueComplete, rProperties[istr].valueComplete, rProperties[istr].arrayIndex, {}, rProperties[istr].isSpecialProperty, rProperties[istr].modifierFunction, rProperties[istr].modifierParameters);
192 }
193
194 if (p_obj.useFrames == true) {
195 nTween = new TweenListObj(
196 rScopes[i],
197 _currentTimeFrame + (rDelay / _timeScale),
198 _currentTimeFrame + ((rDelay + rTime) / _timeScale),
199 true,
200 rTransition,
201 p_obj.transitionParams
202 );
203 } else {
204 nTween = new TweenListObj(
205 rScopes[i],
206 _currentTime + ((rDelay * 1000) / _timeScale),
207 _currentTime + (((rDelay * 1000) + (rTime * 1000)) / _timeScale),
208 false,
209 rTransition,
210 p_obj.transitionParams
211 );
212 }
213
214 nTween.properties = nProperties;
215 nTween.onStart = p_obj.onStart;
216 nTween.onUpdate = p_obj.onUpdate;
217 nTween.onComplete = p_obj.onComplete;
218 nTween.onOverwrite = p_obj.onOverwrite;
219 nTween.onError = p_obj.onError;
220 nTween.onStartParams = p_obj.onStartParams;
221 nTween.onUpdateParams = p_obj.onUpdateParams;
222 nTween.onCompleteParams = p_obj.onCompleteParams;
223 nTween.onOverwriteParams = p_obj.onOverwriteParams;
224 nTween.onStartScope = p_obj.onStartScope;
225 nTween.onUpdateScope = p_obj.onUpdateScope;
226 nTween.onCompleteScope = p_obj.onCompleteScope;
227 nTween.onOverwriteScope = p_obj.onOverwriteScope;
228 nTween.onErrorScope = p_obj.onErrorScope;
229 nTween.rounded = p_obj.rounded;
230 nTween.skipUpdates = p_obj.skipUpdates;
231
232
233 if (!p_obj.quickAdd) removeTweensByTime(nTween.scope, nTween.properties, nTween.timeStart, nTween.timeComplete);
234
235
236 _tweenList.push(nTween);
237
238
239 if (rTime == 0 && rDelay == 0) {
240 myT = _tweenList.length-1;
241 updateTweenByIndex(myT);
242 removeTweenByIndex(myT);
243 }
244 }
245
246 return true;
247 }
248
249
250
251
252
267 public static function addCaller (p_scopes:Object, p_parameters:Object):Boolean {
268 if (p_scopes == undefined) return false;
269
270 var i:Number;
271
272 var rScopes:Array;
273 if (p_scopes instanceof Array) {
274
275 rScopes = p_scopes.concat();
276 } else {
277
278 rScopes = [p_scopes];
279 }
280
281 var p_obj:Object = p_parameters;
282
283
284 if (!_inited) init();
285 if (!_engineExists || _root[getControllerName()] == undefined) startEngine();
286
287
288 var rTime:Number = (isNaN(p_obj.time) ? 0 : p_obj.time);
289 var rDelay:Number = (isNaN(p_obj.delay) ? 0 : p_obj.delay);
290
291 var rTransition:Function;
292 if (typeof p_obj.transition == "string") {
293
294 var trans:String = p_obj.transition.toLowerCase();
295 rTransition = _transitionList[trans];
296 } else {
297
298 rTransition = p_obj.transition;
299 }
300 if (rTransition == undefined) rTransition = _transitionList["easeoutexpo"];
301
302 var nTween:TweenListObj;
303 var myT:Number;
304 for (i = 0; i < rScopes.length; i++) {
305
306 if (p_obj.useFrames == true) {
307 nTween = new TweenListObj(
308 rScopes[i],
309 _currentTimeFrame + (rDelay / _timeScale),
310 _currentTimeFrame + ((rDelay + rTime) / _timeScale),
311 true,
312 rTransition,
313 p_obj.transitionParams
314 );
315 } else {
316 nTween = new TweenListObj(
317 rScopes[i],
318 _currentTime + ((rDelay * 1000) / _timeScale),
319 _currentTime + (((rDelay * 1000) + (rTime * 1000)) / _timeScale),
320 false,
321 rTransition,
322 p_obj.transitionParams
323 );
324 }
325
326 nTween.properties = undefined;
327 nTween.onStart = p_obj.onStart;
328 nTween.onUpdate = p_obj.onUpdate;
329 nTween.onComplete = p_obj.onComplete;
330 nTween.onOverwrite = p_obj.onOverwrite;
331 nTween.onStartParams = p_obj.onStartParams;
332 nTween.onUpdateParams = p_obj.onUpdateParams;
333 nTween.onCompleteParams = p_obj.onCompleteParams;
334 nTween.onOverwriteParams = p_obj.onOverwriteParams;
335 nTween.onStartScope = p_obj.onStartScope;
336 nTween.onUpdateScope = p_obj.onUpdateScope;
337 nTween.onCompleteScope = p_obj.onCompleteScope;
338 nTween.onOverwriteScope = p_obj.onOverwriteScope;
339 nTween.onErrorScope = p_obj.onErrorScope;
340 nTween.isCaller = true;
341 nTween.count = p_obj.count;
342 nTween.waitFrames = p_obj.waitFrames;
343
344
345 _tweenList.push(nTween);
346
347
348 if (rTime == 0 && rDelay == 0) {
349 myT = _tweenList.length-1;
350 updateTweenByIndex(myT);
351 removeTweenByIndex(myT);
352 }
353 }
354
355 return true;
356 }
357
358
367 public static function removeTweensByTime (p_scope:Object, p_properties:Object, p_timeStart:Number, p_timeComplete:Number):Boolean {
368 var removed:Boolean = false;
369 var removedLocally:Boolean;
370
371 var i:Number;
372 var tl:Number = _tweenList.length;
373 var pName:String;
374
375 for (i = 0; i < tl; i++) {
376 if (p_scope == _tweenList[i].scope) {
377
378 if (p_timeComplete > _tweenList[i].timeStart && p_timeStart < _tweenList[i].timeComplete) {
379
380 removedLocally = false;
381 for (pName in _tweenList[i].properties) {
382 if (p_properties[pName] != undefined) {
383
384
385 if (_tweenList[i].onOverwrite != undefined) {
386 var eventScope:Object = _tweenList[i].onOverwriteScope != undefined ? _tweenList[i].onOverwriteScope : _tweenList[i].scope;
387 try {
388 _tweenList[i].onOverwrite.apply(eventScope, _tweenList[i].onOverwriteParams);
389 } catch(e:Error) {
390 handleError(_tweenList[i], e, "onOverwrite");
391 }
392 }
393 _tweenList[i].properties[pName] = undefined;
394 delete _tweenList[i].properties[pName];
395 removedLocally = true;
396 removed = true;
397 }
398 }
399 if (removedLocally) {
400
401 if (AuxFunctions.getObjectLength(_tweenList[i].properties) == 0) removeTweenByIndex(i);
402 }
403 }
404 }
405 }
406
407 return removed;
408 }
409
410
417 public static function removeTweens (p_scope:Object):Boolean {
418
419 var properties:Array = new Array();
420 var i:Number;
421 for (i = 1; i < arguments.length; i++) {
422 if (typeof(arguments[i]) == "string" && !AuxFunctions.isInArray(arguments[i], properties)) properties.push(arguments[i]);
423 }
424
425 return affectTweens(removeTweenByIndex, p_scope, properties);
426 }
427
428
433 public static function removeAllTweens ():Boolean {
434 var removed:Boolean = false;
435 var i:Number;
436 for (i = 0; i < _tweenList.length; i++) {
437 removeTweenByIndex(i);
438 removed = true;
439 }
440 return removed;
441 }
442
443
450 public static function pauseTweens (p_scope:Object):Boolean {
451
452 var properties:Array = new Array();
453 var i:Number;
454 for (i = 1; i < arguments.length; i++) {
455 if (typeof(arguments[i]) == "string" && !AuxFunctions.isInArray(arguments[i], properties)) properties.push(arguments[i]);
456 }
457
458 return affectTweens(pauseTweenByIndex, p_scope, properties);
459 }
460
461
466 public static function pauseAllTweens ():Boolean {
467 var paused:Boolean = false;
468 var i:Number;
469 for (i = 0; i < _tweenList.length; i++) {
470 pauseTweenByIndex(i);
471 paused = true;
472 }
473 return paused;
474 }
475
476
483 public static function resumeTweens (p_scope:Object):Boolean {
484
485 var properties:Array = new Array();
486 var i:Number;
487 for (i = 1; i < arguments.length; i++) {
488 if (typeof(arguments[i]) == "string" && !AuxFunctions.isInArray(arguments[i], properties)) properties.push(arguments[i]);
489 }
490
491 return affectTweens(resumeTweenByIndex, p_scope, properties);
492 }
493
494
499 public static function resumeAllTweens ():Boolean {
500 var resumed:Boolean = false;
501 var i:Number;
502 for (i = 0; i < _tweenList.length; i++) {
503 resumeTweenByIndex(i);
504 resumed = true;
505 }
506 return resumed;
507 }
508
509
517 private static function affectTweens (p_affectFunction:Function, p_scope:Object, p_properties:Array):Boolean {
518 var affected:Boolean = false;
519 var i:Number;
520
521 if (!_tweenList) return false;
522
523 for (i = 0; i < _tweenList.length; i++) {
524 if (_tweenList[i].scope == p_scope) {
525 if (p_properties.length == 0) {
526
527 p_affectFunction(i);
528 affected = true;
529 } else {
530
531 var affectedProperties:Array = new Array();
532 var j:Number;
533 for (j = 0; j < p_properties.length; j++) {
534 if (_tweenList[i].properties[p_properties[j]] != undefined) {
535 affectedProperties.push(p_properties[j]);
536 }
537 }
538 if (affectedProperties.length > 0) {
539
540 var objectProperties:Number = AuxFunctions.getObjectLength(_tweenList[i].properties);
541 if (objectProperties == affectedProperties.length) {
542
543 p_affectFunction(i);
544 affected = true;
545 } else {
546
547 var slicedTweenIndex:Number = splitTweens(i, affectedProperties);
548 p_affectFunction(slicedTweenIndex);
549 affected = true;
550 }
551 }
552 }
553 }
554 }
555 return affected;
556 }
557
558
565 public static function splitTweens (p_tween:Number, p_properties:Array):Number {
566
567 var originalTween:TweenListObj = _tweenList[p_tween];
568 var newTween:TweenListObj = originalTween.clone(false);
569
570
571 var i:Number;
572 var pName:String;
573
574
575 for (i = 0; i < p_properties.length; i++) {
576 pName = p_properties[i];
577 if (originalTween.properties[pName] != undefined) {
578 originalTween.properties[pName] = undefined;
579 delete originalTween.properties[pName];
580 }
581 }
582
583
584 var found:Boolean;
585 for (pName in newTween.properties) {
586 found = false;
587 for (i = 0; i < p_properties.length; i++) {
588 if (p_properties[i] == pName) {
589 found = true;
590 break;
591 }
592 }
593 if (!found) {
594 newTween.properties[pName] = undefined;
595 delete newTween.properties[pName];
596 }
597 }
598
599
600 _tweenList.push(newTween);
601 return (_tweenList.length - 1);
602
603 }
604
605
606
607
608
609
614 private static function updateTweens ():Boolean {
615 if (_tweenList.length == 0) return false;
616 var i:Number;
617 for (i = 0; i < _tweenList.length; i++) {
618
619 if (!_tweenList[i].isPaused) {
620 if (!updateTweenByIndex(i)) removeTweenByIndex(i);
621 if (_tweenList[i] == null) {
622 removeTweenByIndex(i, true);
623 i--;
624 }
625 }
626 }
627
628 return true;
629 }
630
631
637 public static function removeTweenByIndex (p_tween:Number, p_finalRemoval:Boolean):Boolean {
638 _tweenList[p_tween] = null;
639 if (p_finalRemoval) _tweenList.splice(p_tween, 1);
640 return true;
641 }
642
643
649 public static function pauseTweenByIndex (p_tween:Number):Boolean {
650 var tTweening:Object = _tweenList[p_tween];
651 if (tTweening == null || tTweening.isPaused) return false;
652 tTweening.timePaused = getCurrentTweeningTime(tTweening);
653 tTweening.isPaused = true;
654
655 return true;
656 }
657
658
664 public static function resumeTweenByIndex (p_tween:Number):Boolean {
665 var tTweening:Object = _tweenList[p_tween];
666 if (tTweening == null || !tTweening.isPaused) return false;
667 var cTime:Number = getCurrentTweeningTime(tTweening);
668 tTweening.timeStart += cTime - tTweening.timePaused;
669 tTweening.timeComplete += cTime - tTweening.timePaused;
670 tTweening.timePaused = undefined;
671 tTweening.isPaused = false;
672
673 return true;
674 }
675
676
682 private static function updateTweenByIndex (i:Number):Boolean {
683
684 var tTweening:Object = _tweenList[i];
685
686 if (tTweening == null || !tTweening.scope) return false;
687
688 var isOver:Boolean = false;
689 var mustUpdate:Boolean;
690
691 var nv:Number;
692
693 var t:Number;
694 var b:Number;
695 var c:Number;
696 var d:Number;
697
698 var pName:String;
699 var eventScope:Object;
700
701
702 var tScope:Object;
703 var cTime:Number = getCurrentTweeningTime(tTweening);
704 var tProperty:Object;
705
706 if (cTime >= tTweening.timeStart) {
707
708
709 tScope = tTweening.scope;
710
711 if (tTweening.isCaller) {
712
713 do {
714 t = ((tTweening.timeComplete - tTweening.timeStart)/tTweening.count) * (tTweening.timesCalled+1);
715 b = tTweening.timeStart;
716 c = tTweening.timeComplete - tTweening.timeStart;
717 d = tTweening.timeComplete - tTweening.timeStart;
718 nv = tTweening.transition(t, b, c, d, tTweening.transitionParams);
719
720 if (cTime >= nv) {
721 if (tTweening.onUpdate != undefined) {
722 eventScope = tTweening.onUpdateScope != undefined ? tTweening.onUpdateScope : tScope;
723 try {
724 tTweening.onUpdate.apply(eventScope, tTweening.onUpdateParams);
725 } catch(e:Error) {
726 handleError(tTweening, e, "onUpdate");
727 }
728 }
729
730 tTweening.timesCalled++;
731 if (tTweening.timesCalled >= tTweening.count) {
732 isOver = true;
733 break;
734 }
735 if (tTweening.waitFrames) break;
736 }
737
738 } while (cTime >= nv);
739 } else {
740
741
742 mustUpdate = tTweening.skipUpdates < 1 || tTweening.skipUpdates == undefined || tTweening.updatesSkipped >= tTweening.skipUpdates;
743
744 if (cTime >= tTweening.timeComplete) {
745 isOver = true;
746 mustUpdate = true;
747 }
748
749 if (!tTweening.hasStarted) {
750
751 if (tTweening.onStart != undefined) {
752 eventScope = tTweening.onStartScope != undefined ? tTweening.onStartScope : tScope;
753 try {
754 tTweening.onStart.apply(eventScope, tTweening.onStartParams);
755 } catch(e:Error) {
756 handleError(tTweening, e, "onStart");
757 }
758 }
759 var pv:Number;
760 for (pName in tTweening.properties) {
761 if (tTweening.properties[pName].isSpecialProperty) {
762
763 if (_specialPropertyList[pName].preProcess != undefined) {
764 tTweening.properties[pName].valueComplete = _specialPropertyList[pName].preProcess(tScope, _specialPropertyList[pName].parameters, tTweening.properties[pName].originalValueComplete, tTweening.properties[pName].extra);
765 }
766 pv = _specialPropertyList[pName].getValue(tScope, _specialPropertyList[pName].parameters, tTweening.properties[pName].extra);
767 } else {
768
769 pv = tScope[pName];
770 }
771 tTweening.properties[pName].valueStart = isNaN(pv) ? tTweening.properties[pName].valueComplete : pv;
772 }
773 mustUpdate = true;
774 tTweening.hasStarted = true;
775 }
776
777 if (mustUpdate) {
778 for (pName in tTweening.properties) {
779 tProperty = tTweening.properties[pName];
780
781 if (isOver) {
782
783 nv = tProperty.valueComplete;
784 } else {
785 if (tProperty.hasModifier) {
786
787 t = cTime - tTweening.timeStart;
788 d = tTweening.timeComplete - tTweening.timeStart;
789 nv = tTweening.transition(t, 0, 1, d, tTweening.transitionParams);
790 nv = tProperty.modifierFunction(tProperty.valueStart, tProperty.valueComplete, nv, tProperty.modifierParameters);
791 } else {
792
793 t = cTime - tTweening.timeStart;
794 b = tProperty.valueStart;
795 c = tProperty.valueComplete - tProperty.valueStart;
796 d = tTweening.timeComplete - tTweening.timeStart;
797 nv = tTweening.transition(t, b, c, d, tTweening.transitionParams);
798 }
799 }
800
801 if (tTweening.rounded) nv = Math.round(nv);
802 if (tProperty.isSpecialProperty) {
803
804 _specialPropertyList[pName].setValue(tScope, nv, _specialPropertyList[pName].parameters, tTweening.properties[pName].extra);
805 } else {
806
807 tScope[pName] = nv;
808 }
809 }
810
811 tTweening.updatesSkipped = 0;
812
813 if (tTweening.onUpdate != undefined) {
814 eventScope = tTweening.onUpdateScope != undefined ? tTweening.onUpdateScope : tScope;
815 try {
816 tTweening.onUpdate.apply(eventScope, tTweening.onUpdateParams);
817 } catch(e:Error) {
818 handleError(tTweening, e, "onUpdate");
819 }
820 }
821 } else {
822 tTweening.updatesSkipped++;
823 }
824 }
825
826 if (isOver && tTweening.onComplete != undefined) {
827 eventScope = tTweening.onCompleteScope != undefined ? tTweening.onCompleteScope : tScope;
828 try {
829 tTweening.onComplete.apply(eventScope, tTweening.onCompleteParams);
830 } catch(e:Error) {
831 handleError(tTweening, e, "onComplete");
832 }
833 }
834
835 return (!isOver);
836 }
837
838
839 return (true);
840
841 }
842
843
846 private static function init():Void {
847 _inited = true;
848
849
850 _transitionList = new Object();
851 Equations.init();
852
853
854 _specialPropertyList = new Object();
855 _specialPropertyModifierList = new Object();
856 _specialPropertySplitterList = new Object();
857 }
858
859
865 public static function registerTransition(p_name:String, p_function:Function): Void {
866 if (!_inited) init();
867 _transitionList[p_name] = p_function;
868 }
869
870
877 public static function registerSpecialProperty(p_name:String, p_getFunction:Function, p_setFunction:Function, p_parameters:Array, p_preProcessFunction:Function): Void {
878 if (!_inited) init();
879 var sp:SpecialProperty = new SpecialProperty(p_getFunction, p_setFunction, p_parameters, p_preProcessFunction);
880 _specialPropertyList[p_name] = sp;
881 }
882
883
890 public static function registerSpecialPropertyModifier(p_name:String, p_modifyFunction:Function, p_getFunction:Function): Void {
891 if (!_inited) init();
892 var spm:SpecialPropertyModifier = new SpecialPropertyModifier(p_modifyFunction, p_getFunction);
893 _specialPropertyModifierList[p_name] = spm;
894 }
895
896
902 public static function registerSpecialPropertySplitter(p_name:String, p_splitFunction:Function, p_parameters:Array): Void {
903 if (!_inited) init();
904 var sps:SpecialPropertySplitter = new SpecialPropertySplitter(p_splitFunction, p_parameters);
905 _specialPropertySplitterList[p_name] = sps;
906 }
907
908
911 private static function startEngine():Void {
912 _engineExists = true;
913 _tweenList = new Array();
914
915 var randomDepth:Number = Math.floor(Math.random() * 999999);
916 var fmc:MovieClip = _root.createEmptyMovieClip(getControllerName(), 31338+randomDepth);
917 fmc.onEnterFrame = function(): Void {
918 Tweener.onEnterFrame();
919 };
920
921 _currentTimeFrame = 0;
922 updateTime();
923 }
924
925
928 private static function stopEngine():Void {
929 _engineExists = false;
930 _tweenList = null;
931 _currentTime = 0;
932 _currentTimeFrame = 0;
933 delete _root[getControllerName()].onEnterFrame;
934 _root[getControllerName()].removeMovieClip();
935 }
936
937
940 public static function updateTime():Void {
941 _currentTime = getTimer();
942 }
943
944
947 public static function updateFrame():Void {
948 _currentTimeFrame++;
949 }
950
951
954 public static function onEnterFrame():Void {
955 updateTime();
956 updateFrame();
957 var hasUpdated:Boolean = false;
958 hasUpdated = updateTweens();
959 if (!hasUpdated) stopEngine();
960 }
961
962
967 public static function setTimeScale(p_time:Number):Void {
968 var i:Number;
969 var cTime:Number;
970
971 if (isNaN(p_time)) p_time = 1;
972 if (p_time < 0.00001) p_time = 0.00001;
973 if (p_time != _timeScale) {
974
975 for (i = 0; i<_tweenList.length; i++) {
976 cTime = getCurrentTweeningTime(_tweenList[i]);
977 _tweenList[i].timeStart = cTime - ((cTime - _tweenList[i].timeStart) * _timeScale / p_time);
978 _tweenList[i].timeComplete = cTime - ((cTime - _tweenList[i].timeComplete) * _timeScale / p_time);
979 if (_tweenList[i].timePaused != undefined) _tweenList[i].timePaused = cTime - ((cTime - _tweenList[i].timePaused) * _timeScale / p_time);
980 }
981
982 _timeScale = p_time;
983 }
984 }
985
986
987
988
989
995 public static function isTweening(p_scope:Object):Boolean {
996 var i:Number;
997
998 for (i = 0; i<_tweenList.length; i++) {
999 if (_tweenList[i].scope == p_scope) {
1000 return true;
1001 }
1002 }
1003 return false;
1004 }
1005
1006
1012 public static function getTweens(p_scope:Object):Array {
1013 var i:Number;
1014 var pName:String;
1015 var tList:Array = new Array();
1016
1017 for (i = 0; i<_tweenList.length; i++) {
1018 if (_tweenList[i].scope == p_scope) {
1019 for (pName in _tweenList[i].properties) tList.push(pName);
1020 }
1021 }
1022 return tList;
1023 }
1024
1025
1031 public static function getTweenCount(p_scope:Object):Number {
1032 var i:Number;
1033 var c:Number = 0;
1034
1035 for (i = 0; i<_tweenList.length; i++) {
1036 if (_tweenList[i].scope == p_scope) {
1037 c += AuxFunctions.getObjectLength(_tweenList[i].properties);
1038 }
1039 }
1040 return c;
1041 }
1042
1043
1046 private static function handleError(pTweening : Object, pError : Error, pCallBackName : String) : Void{
1047
1048 if (pTweening.onError != undefined && typeof(pTweening.onError == "function")){
1049
1050 var eventScope:Object = pTweening.onErrorScope != undefined ? pTweening.onErrorScope : pTweening.scope;
1051 try {
1052 pTweening.onError.apply(eventScope, [pTweening.scope, pError]);
1053 } catch (metaError : Error){
1054 printError(pTweening.scope.toString() + " raised an error while executing the 'onError' handler. Original error:\n " + pError + "\nonError error: " + metaError);
1055 }
1056 } else {
1057
1058 if (pTweening.onError == undefined){
1059 printError(pTweening.scope.toString() + " raised an error while executing the '" + pCallBackName.toString() + "'handler. \n" + pError );
1060 }
1061 }
1062 }
1063
1064
1069 public static function getCurrentTweeningTime(p_tweening:Object):Number {
1070 return p_tweening.useFrames ? _currentTimeFrame : _currentTime;
1071 }
1072
1073
1078 public static function getVersion():String {
1079 return "AS2 1.31.69";
1080 }
1081
1082
1087 public static function getControllerName():String {
1088 return "__tweener_controller__"+Tweener.getVersion();
1089 }
1090
1091
1092
1093
1094
1095
1096
1101 public static function printError(p_message:String): Void {
1102
1103 trace("## [Tweener] Error: "+p_message);
1104 }
1105
1106 }
1107