Team:SYSU-China/temp/SpryDOMEffects.js
From 2011.igem.org
// SpryDOMEffects.js - version 0.6 - Spry Pre-Release 1.7 // // Copyright (c) 2007. Adobe Systems Incorporated. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Adobe Systems Incorporated nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE.
(function() { // BeginSpryComponent
if (typeof Spry == "undefined" || !Spry.Utils || !Spry.$$) { alert("SpryDOMEffects.js requires SpryDOMUtils.js"); return; }
if (!Spry.Effect) Spry.Effect = {};
Spry.Effect.Animator = function(opts) { Spry.Effect.Animator.Notifier.call(this);
this.animatorID = Spry.Effect.Animator.nextID++; this.dropFrames = true; this.fps = 60; // frames per-second this.duration = 500; // msecs this.timer = 0; this.startTime = 0; // Used only when dropFrames is true. this.currentFrame = 0; this.easeFunc = Spry.Effect.Animator.defaultEaseFunc; this.stopped = false;
Spry.Effect.Animator.copyProps(this, opts);
this.interval = 1000 / this.fps; this.numFrames = (this.duration / 1000) * this.fps;
if (this.onComplete) { var self = this; this.addObserver({ onAnimationComplete: function(){ self.onComplete(); } }); } };
Spry.Effect.Animator.nextID = 1;
Spry.Effect.Animator.copyProps = function(dst, src) { if (src) { for (prop in src) dst[prop] = src[prop]; } return dst; };
Spry.Effect.Animator.getElement = function(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) elements.push(Spry.Effect.Animator.getElement(arguments[i])); return elements; } if (typeof element == 'string') element = document.getElementById(element); return element; };
Spry.Effect.Animator.defaultEaseFunc = function(time, begin, finish, duration) { time /= duration; return begin + ((2 - time) * time * finish); };
Spry.Effect.Animator.Notifier = function() { this.observers = []; this.suppressNotifications = 0; };
Spry.Effect.Animator.Notifier.prototype.addObserver = function(observer) { if (!observer) return;
// Make sure the observer isn't already on the list.
var len = this.observers.length; for (var i = 0; i < len; i++) { if (this.observers[i] == observer) return; } this.observers[len] = observer; };
Spry.Effect.Animator.Notifier.prototype.removeObserver = function(observer) { if (!observer) return;
for (var i = 0; i < this.observers.length; i++) { if (this.observers[i] == observer) { this.observers.splice(i, 1); break; } } };
Spry.Effect.Animator.Notifier.prototype.notifyObservers = function(methodName, data) { if (!methodName) return;
if (!this.suppressNotifications) { var len = this.observers.length; for (var i = 0; i < len; i++) { var obs = this.observers[i]; if (obs) { if (typeof obs == "function") obs(methodName, this, data); else if (obs[methodName]) obs[methodName](this, data); } } } };
Spry.Effect.Animator.Notifier.prototype.enableNotifications = function() { if (--this.suppressNotifications < 0) { this.suppressNotifications = 0; Spry.Debug.reportError("Unbalanced enableNotifications() call!\n"); } };
Spry.Effect.Animator.Notifier.prototype.disableNotifications = function() { ++this.suppressNotifications; };
Spry.Effect.Animator.prototype = new Spry.Effect.Animator.Notifier; Spry.Effect.Animator.prototype.constructor = Spry.Effect.Animator;
Spry.Effect.Animator.prototype.start = function() { this.stopped = false; this.currentFrame = 0; this.startTime = (new Date()).getTime();
this.notifyObservers("onAnimationStart");
var self = this; this.timer = setTimeout(function(){ self.onStepAnimation(); }, this.interval); };
Spry.Effect.Animator.prototype.stop = function() { if (this.timer) clearTimeout(this.timer); this.timer = 0; this.stopped = true;
this.notifyObservers("onAnimationStopped"); };
Spry.Effect.Animator.prototype.onStepAnimation = function() { var obj = {};
if (this.dropFrames) { obj.duration = this.duration; obj.elapsed = ((new Date).getTime()) - this.startTime; if (obj.elapsed > obj.duration) obj.elapsed = obj.duration; } else { obj.duration = this.numFrames; obj.elapsed = ++this.currentFrame; }
obj.easingConst = this.easeFunc(obj.elapsed, 0, 1, obj.duration)
this.notifyObservers("onPreDraw", obj); this.draw(obj.elapsed, obj.duration, obj.easingConst); this.notifyObservers("onPostDraw", obj);
if (!this.stopped) { if (obj.elapsed < obj.duration) { var self = this; this.timer = setTimeout(function(){ self.onStepAnimation(); }, this.interval); } else { this.stop(); this.notifyObservers("onAnimationComplete"); } } };
Spry.Effect.Animator.prototype.draw = function(elapsed, duration, easingConst) { // The default draw method does nothing. It is assumed that // derived classes will provide their own implementation of this // method.
debug.log("elapsed: " + elapsed + " -- duration: " + duration + " -- easingConst: " + easingConst); };
///////////////////////////////////////////////////////////////////////////////
Spry.Effect.CSSAnimator = function(elements, styleStr, opts) { this.animationSets = [];
Spry.Effect.Animator.call(this, opts);
this.add(elements, styleStr); };
Spry.Effect.CSSAnimator.prototype = new Spry.Effect.Animator(); Spry.Effect.CSSAnimator.prototype.constructor = Spry.Effect.CSSAnimator;
Spry.Effect.CSSAnimator.prototype.add = function(elements, styleStr) { // The first argument for the CSSAnimator can be // the id of an element, an element node, or an array of // elements and/or ids.
elements = Spry.$$(elements);
if (elements.length < 1) return;
var animSet = { elements: elements, cssProps: []};
this.animationSets.push(animSet);
// Convert the styleStr into an object.
var toObj = Spry.Utils.styleStringToObject(styleStr); for (var p in toObj) { var obj = new Object; var v = toObj[p]; obj.value = new Number(v.replace(/[^-\d\.]+/g, "")); obj.units = v.replace(/[-\d+\.]/g, ""); toObj[p] = obj; }
for (var i = 0; i < elements.length; i++) { var obj = animSet.cssProps[i] = new Object; for (var p in toObj) { var pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs[p]; if (!pFuncs) pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs["default"];
obj[p] = new Object; obj[p].from = new Number(pFuncs.get(elements[i], p).replace(/[^-\d\.]+/g, "")); obj[p].to = toObj[p].value; obj[p].distance = obj[p].to - obj[p].from; obj[p].units = toObj[p].units; } } };
Spry.Effect.CSSAnimator.prototype.start = function() { for (var s = 0; s < this.animationSets.length; s++) { var animSet = this.animationSets[s]; var elements = animSet.elements; var cssProps = animSet.cssProps;
for (var i = 0; i < elements.length; i++) { var ele = elements[i];
var eleProps = ele.spryCSSAnimatorProps; if (!eleProps) eleProps = ele.spryCSSAnimatorProps = new Object;
var obj = cssProps[i]; for (var p in obj) eleProps[p] = this.animatorID; } }
return Spry.Effect.Animator.prototype.start.call(this); };
Spry.Effect.CSSAnimator.prototype.stop = function() { for (var s = 0; s < this.animationSets.length; s++) { var animSet = this.animationSets[s]; var elements = animSet.elements; var cssProps = animSet.cssProps;
for (var i = 0; i < elements.length; i++) { var ele = elements[i]; var obj = cssProps[i];
var eleProps = ele.spryCSSAnimatorProps; for (var p in obj) { if (eleProps[p] == this.animatorID) delete eleProps[p]; } } }
return Spry.Effect.Animator.prototype.stop.call(this); };
Spry.Effect.CSSAnimator.prototype.draw = function(elapsed, duration, easingConst) { for (var s = 0; s < this.animationSets.length; s++) { var animSet = this.animationSets[s]; var elements = animSet.elements; var cssProps = animSet.cssProps;
for (var i = 0; i < elements.length; i++) { var ele = elements[i]; var eleProps = ele.spryCSSAnimatorProps; var obj = cssProps[i]; for (var p in obj) { if (eleProps[p] == this.animatorID) { var pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs[p]; if (!pFuncs) pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs["default"];
if (elapsed > duration) pFuncs.set(ele, p, obj[p].to + obj[p].units); else pFuncs.set(ele, p, obj[p].from + (obj[p].distance * easingConst) + obj[p].units); } } } } };
Spry.Effect.CSSAnimator.stylePropFuncs = {};
Spry.Effect.CSSAnimator.stylePropFuncs["default"] = { get: function(ele, prop) { return ele.style[prop]; },
set: function(ele, prop, val) { ele.style[prop] = val; } };
Spry.Effect.CSSAnimator.stylePropFuncs["opacity"] = { get: function(ele, prop) { var val = 1;
if (ele.style.opacity) val = ele.style.opacity; else if (ele.style.filter) { var strVal = ele.style.filter.replace(/.*alpha\(opacity=(\d+)\).*/, "$1"); if (strVal) val = parseInt(strVal) / 100; } return val + ""; },
set: function(ele, prop, val) { ele.style.opacity = "" + val; ele.style.filter = "alpha(opacity=" + (val * 100) + ")"; } };
///////////////////////////////////////////////////////////////////////////////
Spry.$$.Results.defaultEaseFunc = function(time, begin, finish, duration) { time /= duration; return begin + ((2 - time) * time * finish); };
Spry.$$.Results.animatePropertyTo = function(propName, to, options) { var opts = { interval: 10, duration: 1000, onComplete: null, transition: Spry.$$.Results.defaultEaseFunc }; Spry.Effect.Animator.copyProps(opts, options);
var objs = []; for (var i = 0; i < this.length; i++) { var obj = objs[i] = new Object; obj.ele = this[i]; obj.from = obj.ele[propName]; obj.distance = to - obj.from; }
var startTime = (new Date).getTime();
var animateFunc = function() { var elapsedTime = ((new Date).getTime()) - startTime;
if (elapsedTime > opts.duration) { for (var i = 0; i < objs.length; i++) objs[i].ele[propName] = to; if (opts.onComplete) opts.onComplete(); } else { for (var i = 0; i < objs.length; i++) { var obj = objs[i]; obj.ele[propName] = opts.transition(elapsedTime, obj.from, obj.distance, opts.duration); } setTimeout(animateFunc, opts.interval); } };
setTimeout(animateFunc, opts.interval); return this; };
Spry.$$.Results.animateStyleTo = function(styleStr, options) { var a = new Spry.Effect.CSSAnimator(this, styleStr, options); a.start(); return this; };
})(); // EndSpryComponent