⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tweener.as

📁 ActionScript写的3D图片展示功能
💻 AS
📖 第 1 页 / 共 3 页
字号:
/**
 * Tweener
 * Transition controller for movieclips, sounds, textfields and other objects
 *
 * @author		Zeh Fernando, Nate Chatellier, Arthur Debert
 * @version		1.26.62
 */

/*
Licensed under the MIT License

Copyright (c) 2006-2007 Zeh Fernando and Nate Chatellier

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.

http://code.google.com/p/tweener/
http://code.google.com/p/tweener/wiki/License
*/

package caurina.transitions {
	
	import flash.display.*;
	import flash.events.Event;
	import flash.utils.getTimer;

	public class Tweener {
	
		private static var __tweener_controller__:MovieClip;	// Used to ensure the stage copy is always accessible (garbage collection)
		
		private static var _engineExists:Boolean = false;		// Whether or not the engine is currently running
		private static var _inited:Boolean = false;				// Whether or not the class has been initiated
		private static var _currentTime:Number;					// The current time. This is generic for all tweenings for a "time grid" based update
	
		private static var _tweenList:Array;					// List of active tweens
	
		private static var _timeScale:Number = 1;				// Time scale (default = 1)
	
		private static var _transitionList:Object;				// List of "pre-fetched" transition functions
		private static var _specialPropertyList:Object;			// List of special properties
		private static var _specialPropertyModifierList:Object;	// List of special property modifiers
		private static var _specialPropertySplitterList:Object;	// List of special property splitters

	
		/**
		 * There's no constructor.
		 * @private
		 */
		public function Tweener () {
			trace ("Tweener is a static class and should not be instantiated.")
		}

		// ==================================================================================================================================
		// TWEENING CONTROL functions -------------------------------------------------------------------------------------------------------

		/**
		 * Adds a new tweening.
		 *
		 * @param		(first-n param)		Object				Object that should be tweened: a movieclip, textfield, etc.. OR an array of objects
		 * @param		(last param)		Object				Object containing the specified parameters in any order, as well as the properties that should be tweened and their values
		 * @param		.time				Number				Time in seconds or frames for the tweening to take (defaults 2)
		 * @param		.delay				Number				Delay time (defaults 0)
		 * @param		.useFrames			Boolean				Whether to use frames instead of seconds for time control (defaults false)
		 * @param		.transition			String/Function		Type of transition equation... (defaults to "easeoutexpo")
		 * @param		.onStart			Function			* Direct property, See the TweenListObj class
		 * @param		.onUpdate			Function			* Direct property, See the TweenListObj class
		 * @param		.onComplete			Function			* Direct property, See the TweenListObj class
		 * @param		.onOverwrite		Function			* Direct property, See the TweenListObj class
		 * @param		.onStartParams		Array				* Direct property, See the TweenListObj class
		 * @param		.onUpdateParams		Array				* Direct property, See the TweenListObj class
		 * @param		.onCompleteParams	Array				* Direct property, See the TweenListObj class
		 * @param		.onOverwriteParams	Array				* Direct property, See the TweenListObj class
		 * @param		.rounded			Boolean				* Direct property, See the TweenListObj class
		 * @param		.skipUpdates		Number				* Direct property, See the TweenListObj class
		 * @return							Boolean				TRUE if the tween was successfully added, FALSE if otherwise
		 */
		public static function addTween (p_arg1:Object = null, p_arg2:Object = null):Boolean {
			if (arguments.length < 2 || arguments[0] == undefined) return false;
	
			var rScopes:Array = new Array(); // List of objects to tween
			var i:Number, j:Number, istr:String, jstr:String;
	
			if (arguments[0] is Array) {
				// The first argument is an array
				for (i = 0; i<arguments[0].length; i++) rScopes.push(arguments[0][i]);
			} else {
				// The first argument(s) is(are) object(s)
				for (i = 0; i<arguments.length-1; i++) rScopes.push(arguments[i]);
			}
			// rScopes = arguments.concat().splice(1); // Alternate (should be tested for speed later)
	
			// make properties chain ("inheritance")
    		var p_obj:Object = TweenListObj.makePropertiesChain(arguments[arguments.length-1]);
	
			// Creates the main engine if it isn't active
			if (!_inited) init();
			if (!_engineExists || !Boolean(__tweener_controller__)) startEngine(); // Quick fix for Flash not resetting the vars on double ctrl+enter...
	
			// Creates a "safer", more strict tweening object
			var rTime:Number = (isNaN(p_obj.time) ? 0 : p_obj.time); // Real time
			var rDelay:Number = (isNaN(p_obj.delay) ? 0 : p_obj.delay); // Real delay
	
			// Creates the property list; everything that isn't a hardcoded variable
			var rProperties:Array = new Array(); // array containing object { .name, .valueStart, .valueComplete }
			var restrictedWords:Object = {time:true, delay:true, useFrames:true, skipUpdates:true, transition:true, onStart:true, onUpdate:true, onComplete:true, onOverwrite:true, rounded:true, onStartParams:true, onUpdateParams:true, onCompleteParams:true, onOverwriteParams:true};
			var modifiedProperties:Object = new Object();
			for (istr in p_obj) {
				if (!restrictedWords[istr]) {
					// It's an additional pair, so adds
					if (_specialPropertySplitterList[istr]) {
						// Special property splitter
						var splitProperties:Array = _specialPropertySplitterList[istr].splitValues(p_obj[istr], _specialPropertySplitterList[istr].parameters);
						for (i = 0; i < splitProperties.length; i++) {
							rProperties[splitProperties[i].name] = {valueStart:undefined, valueComplete:splitProperties[i].value};
						}
					} else if (_specialPropertyModifierList[istr] != undefined) {
						// Special property modifier
						var tempModifiedProperties:Array = _specialPropertyModifierList[istr].modifyValues(p_obj[istr]);
						for (i = 0; i < tempModifiedProperties.length; i++) {
							modifiedProperties[tempModifiedProperties[i].name] = {modifierParameters:tempModifiedProperties[i].parameters, modifierFunction:_specialPropertyModifierList[istr].getValue};
						}
					} else {
						// Regular property or special property, just add the property normally
						rProperties[istr] = {valueStart:undefined, valueComplete:p_obj[istr]};
					}
				}
			}
	
			// Adds the modifiers to the list of properties
			for (istr in modifiedProperties) {
				if (rProperties[istr] != undefined) {
					rProperties[istr].modifierParameters = modifiedProperties[istr].modifierParameters;
					rProperties[istr].modifierFunction = modifiedProperties[istr].modifierFunction;
				}
				
			}

			var rTransition:Function; // Real transition
	
			if (typeof p_obj.transition == "string") {
				// String parameter, transition names
				var trans:String = p_obj.transition.toLowerCase();
				rTransition = _transitionList[trans];
			} else {
				// Proper transition function
				rTransition = p_obj.transition;
			}
			if (!Boolean(rTransition)) rTransition = _transitionList["easeoutexpo"];
	
			var nProperties:Object;
			var nTween:TweenListObj;
			var myT:Number;
	
			for (i = 0; i < rScopes.length; i++) {
				// Makes a copy of the properties
				nProperties = new Object();
				for (istr in rProperties) {
					nProperties[istr] = new PropertyInfoObj(rProperties[istr].valueStart, rProperties[istr].valueComplete, rProperties[istr].modifierFunction, rProperties[istr].modifierParameters);
				}
				
				nTween = new TweenListObj(
					/* scope			*/	rScopes[i],
					/* timeStart		*/	_currentTime + ((rDelay * 1000) / _timeScale),
					/* timeComplete		*/	_currentTime + (((rDelay * 1000) + (rTime * 1000)) / _timeScale),
					/* useFrames		*/	(p_obj.useFrames == true),
					/* transition		*/	rTransition
				);
				
				nTween.properties			=	nProperties;
				nTween.onStart				=	p_obj.onStart;
				nTween.onUpdate				=	p_obj.onUpdate;
				nTween.onComplete			=	p_obj.onComplete;
				nTween.onOverwrite			=	p_obj.onOverwrite;
				nTween.onError			    =	p_obj.onError;
				nTween.onStartParams		=	p_obj.onStartParams;
				nTween.onUpdateParams		=	p_obj.onUpdateParams;
				nTween.onCompleteParams		=	p_obj.onCompleteParams;
				nTween.onOverwriteParams	=	p_obj.onOverwriteParams;
				nTween.rounded				=	p_obj.rounded;
				nTween.skipUpdates			=	p_obj.skipUpdates;

				// Remove other tweenings that occur at the same time
				removeTweensByTime(nTween.scope, nTween.properties, nTween.timeStart, nTween.timeComplete);
	
				// And finally adds it to the list
				_tweenList.push(nTween);
	
				// Immediate update and removal if it's an immediate tween -- if not deleted, it executes at the end of this frame execution
				if (rTime == 0 && rDelay == 0) {
					myT = _tweenList.length-1;
					updateTweenByIndex(myT);
					removeTweenByIndex(myT);
				}
			}
	
			return true;
		}
	
		// A "caller" is like this: [          |     |  | ||] got it? :)
		// this function is crap - should be fixed later/extend on addTween()
	
		/**
		 * Adds a new caller tweening.
		 *
		 * @param		(first-n param)		Object that should be tweened: a movieclip, textfield, etc.. OR an array of objects
		 * @param		(last param)		Object containing the specified parameters in any order, as well as the properties that should be tweened and their values
		 * @param		.time				Number				Time in seconds or frames for the tweening to take (defaults 2)
		 * @param		.delay				Number				Delay time (defaults 0)
		 * @param		.count				Number				Number of times this caller should be called
		 * @param		.transition			String/Function		Type of transition equation... (defaults to "easeoutexpo")
		 * @param		.onStart			Function			Event called when tween starts
		 * @param		.onUpdate			Function			Event called when tween updates
		 * @param		.onComplete			Function			Event called when tween ends
		 * @param		.waitFrames			Boolean				Whether to wait (or not) one frame for each call
		 * @return							<code>true</code> if the tween was successfully added, <code>false</code> if otherwise.
		 */
		public static function addCaller (p_arg1:Object = null, p_arg2:Object = null):Boolean {
			if (arguments.length < 2 || arguments[0] == undefined) return false;
	
			var rScopes:Array = new Array(); // List of objects to tween
			var i:Number, j:Number;
	
			if (arguments[0] is Array) {
				// The first argument is an array
				for (i = 0; i<arguments[0].length; i++) rScopes.push(arguments[0][i]);
			} else {
				// The first argument(s) is(are) object(s)
				for (i = 0; i<arguments.length-1; i++) rScopes.push(arguments[i]);
			}
			// rScopes = arguments.concat().splice(1); // Alternate (should be tested for speed later)
	
			var p_obj:Object = arguments[arguments.length-1];
	
			// Creates the main engine if it isn't active
			if (!_inited) init();
			if (!_engineExists || !Boolean(__tweener_controller__)) startEngine(); // Quick fix for Flash not resetting the vars on double ctrl+enter...
	
			// Creates a "safer", more strict tweening object
			var rTime:Number = (isNaN(p_obj.time) ? 0 : p_obj.time); // Real time
			var rDelay:Number = (isNaN(p_obj.delay) ? 0 : p_obj.delay); // Real delay
	
			var rTransition:Function; // Real transition
			if (typeof p_obj.transition == "string") {
				// String parameter, transition names
				var trans:String = p_obj.transition.toLowerCase();
				rTransition = _transitionList[trans];
			} else {
				// Proper transition function
				rTransition = p_obj.transition;
			}
			if (!Boolean(rTransition)) rTransition = _transitionList["easeoutexpo"];
	
			var nTween:TweenListObj;
			var myT:Number;
			for (i = 0; i < rScopes.length; i++) {
				
				nTween = new TweenListObj(
					/* Scope			*/	rScopes[i],
					/* TimeStart		*/	_currentTime + ((rDelay * 1000) / _timeScale),
					/* TimeComplete		*/	_currentTime + (((rDelay * 1000) + (rTime * 1000)) / _timeScale),
					/* UseFrames		*/	(p_obj.useFrames == true),
					/* Transition		*/	rTransition
				);

				nTween.properties			=	null;
				nTween.onStart				=	p_obj.onStart;
				nTween.onUpdate				=	p_obj.onUpdate;
				nTween.onComplete			=	p_obj.onComplete;
				nTween.onOverwrite			=	p_obj.onOverwrite;
				nTween.onStartParams		=	p_obj.onStartParams;
				nTween.onUpdateParams		=	p_obj.onUpdateParams;
				nTween.onCompleteParams		=	p_obj.onCompleteParams;
				nTween.onOverwriteParams	=	p_obj.onOverwriteParams;
				nTween.isCaller				=	true;
				nTween.count				=	p_obj.count;
				nTween.waitFrames			=	p_obj.waitFrames;

				// And finally adds it to the list
				_tweenList.push(nTween);
	
				// Immediate update and removal if it's an immediate tween -- if not deleted, it executes at the end of this frame execution
				if (rTime == 0 && rDelay == 0) {
					myT = _tweenList.length-1;
					updateTweenByIndex(myT);
					removeTweenByIndex(myT);
				}
			}
	
			return true;
		}
	
		/**
		 * Remove an specified tweening of a specified object the tweening list, if it conflicts with the given time.
		 *
		 * @param		p_scope				Object						List of objects affected
		 * @param		p_properties		Object 						List of properties affected (PropertyInfoObj instances)
		 * @param		p_timeStart			Number						Time when the new tween starts
		 * @param		p_timeComplete		Number						Time when the new tween ends
		 * @return							Boolean						Whether or not it actually deleted something
		 */
		public static function removeTweensByTime (p_scope:Object, p_properties:Object, p_timeStart:Number, p_timeComplete:Number):Boolean {
			var removed:Boolean = false;
			var removedLocally:Boolean;
	
			var i:uint;
			var tl:uint = _tweenList.length;
			var pName:String;

			for (i = 0; i < tl; i++) {
				if (Boolean(_tweenList[i]) && p_scope == _tweenList[i].scope) {
					// Same object...
					if (p_timeComplete > _tweenList[i].timeStart && p_timeStart < _tweenList[i].timeComplete) {
						// New time should override the old one...
						removedLocally = false;
						for (pName in _tweenList[i].properties) {
							if (Boolean(p_properties[pName])) {
								// Same object, same property
								// Finally, remove this old tweening and use the new one
								if (Boolean(_tweenList[i].onOverwrite)) {
									try {
										_tweenList[i].onOverwrite.apply(_tweenList[i].scope, _tweenList[i].onOverwriteParams);
									} catch(e:Error) {
										handleError(_tweenList[i], e, "onOverwrite");
									}
								}
								_tweenList[i].properties[pName] = undefined;
								delete _tweenList[i].properties[pName];
								removedLocally = true;
								removed = true;
							}
						}
						if (removedLocally) {
							// Verify if this can be deleted
							if (AuxFunctions.getObjectLength(_tweenList[i].properties) == 0) removeTweenByIndex(i);
						}
					}
				}
			}

			return removed;
		}
	
		/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -