1// SpryDOMEffects.js - version 0.6 - Spry Pre-Release 1.7 2// 3// Copyright (c) 2007. Adobe Systems Incorporated. 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are met: 8// 9// * Redistributions of source code must retain the above copyright notice, 10// this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above copyright notice, 12// this list of conditions and the following disclaimer in the documentation 13// and/or other materials provided with the distribution. 14// * Neither the name of Adobe Systems Incorporated nor the names of its 15// contributors may be used to endorse or promote products derived from this 16// software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28// POSSIBILITY OF SUCH DAMAGE. 29 30(function() { // BeginSpryComponent 31 32if (typeof Spry == "undefined" || !Spry.Utils || !Spry.$$) 33{ 34 alert("SpryDOMEffects.js requires SpryDOMUtils.js"); 35 return; 36} 37 38if (!Spry.Effect) Spry.Effect = {}; 39 40Spry.Effect.Animator = function(opts) 41{ 42 Spry.Effect.Animator.Notifier.call(this); 43 44 this.animatorID = Spry.Effect.Animator.nextID++; 45 this.dropFrames = true; 46 this.fps = 60; // frames per-second 47 this.duration = 500; // msecs 48 this.timer = 0; 49 this.startTime = 0; // Used only when dropFrames is true. 50 this.currentFrame = 0; 51 this.easeFunc = Spry.Effect.Animator.defaultEaseFunc; 52 this.stopped = false; 53 54 Spry.Effect.Animator.copyProps(this, opts); 55 56 this.interval = 1000 / this.fps; 57 this.numFrames = (this.duration / 1000) * this.fps; 58 59 if (this.onComplete) 60 { 61 var self = this; 62 this.addObserver({ onAnimationComplete: function(){ self.onComplete(); } }); 63 } 64}; 65 66Spry.Effect.Animator.nextID = 1; 67 68Spry.Effect.Animator.copyProps = function(dst, src) 69{ 70 if (src) 71 { 72 for (prop in src) 73 dst[prop] = src[prop]; 74 } 75 return dst; 76}; 77 78Spry.Effect.Animator.getElement = function(element) 79{ 80 if (arguments.length > 1) 81 { 82 for (var i = 0, elements = [], length = arguments.length; i < length; i++) 83 elements.push(Spry.Effect.Animator.getElement(arguments[i])); 84 return elements; 85 } 86 if (typeof element == 'string') 87 element = document.getElementById(element); 88 return element; 89}; 90 91Spry.Effect.Animator.defaultEaseFunc = function(time, begin, finish, duration) { time /= duration; return begin + ((2 - time) * time * finish); }; 92 93Spry.Effect.Animator.Notifier = function() 94{ 95 this.observers = []; 96 this.suppressNotifications = 0; 97}; 98 99Spry.Effect.Animator.Notifier.prototype.addObserver = function(observer) 100{ 101 if (!observer) 102 return; 103 104 // Make sure the observer isn't already on the list. 105 106 var len = this.observers.length; 107 for (var i = 0; i < len; i++) 108 { 109 if (this.observers[i] == observer) 110 return; 111 } 112 this.observers[len] = observer; 113}; 114 115Spry.Effect.Animator.Notifier.prototype.removeObserver = function(observer) 116{ 117 if (!observer) 118 return; 119 120 for (var i = 0; i < this.observers.length; i++) 121 { 122 if (this.observers[i] == observer) 123 { 124 this.observers.splice(i, 1); 125 break; 126 } 127 } 128}; 129 130Spry.Effect.Animator.Notifier.prototype.notifyObservers = function(methodName, data) 131{ 132 if (!methodName) 133 return; 134 135 if (!this.suppressNotifications) 136 { 137 var len = this.observers.length; 138 for (var i = 0; i < len; i++) 139 { 140 var obs = this.observers[i]; 141 if (obs) 142 { 143 if (typeof obs == "function") 144 obs(methodName, this, data); 145 else if (obs[methodName]) 146 obs[methodName](this, data); 147 } 148 } 149 } 150}; 151 152Spry.Effect.Animator.Notifier.prototype.enableNotifications = function() 153{ 154 if (--this.suppressNotifications < 0) 155 { 156 this.suppressNotifications = 0; 157 Spry.Debug.reportError("Unbalanced enableNotifications() call!\n"); 158 } 159}; 160 161Spry.Effect.Animator.Notifier.prototype.disableNotifications = function() 162{ 163 ++this.suppressNotifications; 164};
165 166Spry.Effect.Animator.prototype = new Spry.Effect.Animator.Notifier; 167Spry.Effect.Animator.prototype.constructor = Spry.Effect.Animator; 168 169Spry.Effect.Animator.prototype.start = function() 170{ 171 this.stopped = false; 172 this.currentFrame = 0; 173 this.startTime = (new Date()).getTime(); 174 175 this.notifyObservers("onAnimationStart"); 176 177 var self = this; 178 this.timer = setTimeout(function(){ self.onStepAnimation(); }, this.interval); 179}; 180 181Spry.Effect.Animator.prototype.stop = function() 182{ 183 if (this.timer) 184 clearTimeout(this.timer); 185 this.timer = 0; 186 this.stopped = true; 187 188 this.notifyObservers("onAnimationStopped"); 189}; 190 191Spry.Effect.Animator.prototype.onStepAnimation = function() 192{ 193 var obj = {}; 194 195 if (this.dropFrames) 196 { 197 obj.duration = this.duration; 198 obj.elapsed = ((new Date).getTime()) - this.startTime; 199 if (obj.elapsed > obj.duration) 200 obj.elapsed = obj.duration; 201 } 202 else 203 { 204 obj.duration = this.numFrames; 205 obj.elapsed = ++this.currentFrame; 206 } 207 208 obj.easingConst = this.easeFunc(obj.elapsed, 0, 1, obj.duration) 209 210 this.notifyObservers("onPreDraw", obj); 211 this.draw(obj.elapsed, obj.duration, obj.easingConst); 212 this.notifyObservers("onPostDraw", obj); 213 214 if (!this.stopped) 215 { 216 if (obj.elapsed < obj.duration) 217 { 218 var self = this; 219 this.timer = setTimeout(function(){ self.onStepAnimation(); }, this.interval); 220 } 221 else 222 { 223 this.stop(); 224 this.notifyObservers("onAnimationComplete"); 225 } 226 } 227}; 228 229Spry.Effect.Animator.prototype.draw = function(elapsed, duration, easingConst) 230{ 231 // The default draw method does nothing. It is assumed that 232 // derived classes will provide their own implementation of this 233 // method. 234 235 debug.log("elapsed: " + elapsed + " -- duration: " + duration + " -- easingConst: " + easingConst); 236}; 237 238 239/////////////////////////////////////////////////////////////////////////////// 240 241Spry.Effect.CSSAnimator = function(elements, styleStr, opts) 242{ 243 this.animationSets = []; 244 245 Spry.Effect.Animator.call(this, opts); 246 247 this.add(elements, styleStr); 248}; 249 250Spry.Effect.CSSAnimator.prototype = new Spry.Effect.Animator(); 251Spry.Effect.CSSAnimator.prototype.constructor = Spry.Effect.CSSAnimator; 252 253Spry.Effect.CSSAnimator.prototype.add = function(elements, styleStr) 254{ 255 // The first argument for the CSSAnimator can be 256 // the id of an element, an element node, or an array of 257 // elements and/or ids. 258 259 elements = Spry.$$(elements); 260 261 if (elements.length < 1) 262 return; 263 264 var animSet = { elements: elements, cssProps: []}; 265 266 this.animationSets.push(animSet); 267 268 // Convert the styleStr into an object. 269 270 var toObj = Spry.Utils.styleStringToObject(styleStr); 271 for (var p in toObj) 272 { 273 var obj = new Object; 274 var v = toObj[p]; 275 obj.value = new Number(v.replace(/[^-\d\.]+/g, "")); 276 obj.units = v.replace(/[-\d+\.]/g, ""); 277 toObj[p] = obj;
278 } 279 280 for (var i = 0; i < elements.length; i++) 281 { 282 var obj = animSet.cssProps[i] = new Object; 283 for (var p in toObj) 284 { 285 var pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs[p]; 286 if (!pFuncs) 287 pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs["default"]; 288 289 obj[p] = new Object; 290 obj[p].from = new Number(pFuncs.get(elements[i], p).replace(/[^-\d\.]+/g, "")); 291 obj[p].to = toObj[p].value; 292 obj[p].distance = obj[p].to - obj[p].from; 293 obj[p].units = toObj[p].units; 294 } 295 } 296}; 297 298Spry.Effect.CSSAnimator.prototype.start = function() 299{ 300 for (var s = 0; s < this.animationSets.length; s++) 301 { 302 var animSet = this.animationSets[s]; 303 var elements = animSet.elements; 304 var cssProps = animSet.cssProps; 305 306 for (var i = 0; i < elements.length; i++) 307 { 308 var ele = elements[i]; 309 310 var eleProps = ele.spryCSSAnimatorProps; 311 if (!eleProps) 312 eleProps = ele.spryCSSAnimatorProps = new Object; 313 314 var obj = cssProps[i]; 315 for (var p in obj) 316 eleProps[p] = this.animatorID; 317 } 318 } 319 320 return Spry.Effect.Animator.prototype.start.call(this); 321}; 322 323Spry.Effect.CSSAnimator.prototype.stop = function() 324{ 325 for (var s = 0; s < this.animationSets.length; s++) 326 { 327 var animSet = this.animationSets[s]; 328 var elements = animSet.elements; 329 var cssProps = animSet.cssProps; 330 331 for (var i = 0; i < elements.length; i++) 332 { 333 var ele = elements[i]; 334 var obj = cssProps[i]; 335 336 var eleProps = ele.spryCSSAnimatorProps; 337 for (var p in obj) 338 { 339 if (eleProps[p] == this.animatorID) 340 delete eleProps[p]; 341 } 342 } 343 } 344 345 return Spry.Effect.Animator.prototype.stop.call(this); 346}; 347 348Spry.Effect.CSSAnimator.prototype.draw = function(elapsed, duration, easingConst) 349{ 350 for (var s = 0; s < this.animationSets.length; s++) 351 { 352 var animSet = this.animationSets[s]; 353 var elements = animSet.elements; 354 var cssProps = animSet.cssProps; 355 356 for (var i = 0; i < elements.length; i++) 357 { 358 var ele = elements[i]; 359 var eleProps = ele.spryCSSAnimatorProps; 360 var obj = cssProps[i]; 361 for (var p in obj) 362 { 363 if (eleProps[p] == this.animatorID) 364 { 365 var pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs[p]; 366 if (!pFuncs) 367 pFuncs = Spry.Effect.CSSAnimator.stylePropFuncs["default"]; 368 369 if (elapsed > duration) 370 pFuncs.set(ele, p, obj[p].to + obj[p].units); 371 else 372 pFuncs.set(ele, p, obj[p].from + (obj[p].distance * easingConst) + obj[p].units); 373 } 374 } 375 } 376 } 377}; 378 379Spry.Effect.CSSAnimator.stylePropFuncs = {}; 380 381Spry.Effect.CSSAnimator.stylePropFuncs["default"] = { 382 get: function(ele, prop) 383 { 384 return ele.style[prop]; 385 }, 386 387 set: function(ele, prop, val) 388 { 389 ele.style[prop] = val; 390 } 391}; 392 393Spry.Effect.CSSAnimator.stylePropFuncs["opacity"] = { 394 get: function(ele, prop) 395 { 396 var val = 1; 397 398 if (ele.style.opacity) 399 val = ele.style.opacity; 400 else if (ele.style.filter) 401 { 402 var strVal = ele.style.filter.replace(/.*alpha\(opacity=(\d+)\).*/, "$1"); 403 if (strVal) 404 val = parseInt(strVal) / 100; 405 } 406 return val + ""; 407 }, 408 409 set: function(ele, prop, val) 410 { 411 ele.style.opacity = "" + val; 412 ele.style.filter = "alpha(opacity=" + (val * 100) + ")"; 413 } 414}; 415 416/////////////////////////////////////////////////////////////////////////////// 417 418Spry.$$.Results.defaultEaseFunc = function(time, begin, finish, duration) { time /= duration; return begin + ((2 - time) * time * finish); }; 419 420Spry.$$.Results.animatePropertyTo = function(propName, to, options) 421{ 422 var opts = { interval: 10, duration: 1000, onComplete: null, transition: Spry.$$.Results.defaultEaseFunc }; 423 Spry.Effect.Animator.copyProps(opts, options); 424 425 var objs = []; 426 for (var i = 0; i < this.length; i++) 427 { 428 var obj = objs[i] = new Object; 429 obj.ele = this[i]; 430 obj.from = obj.ele[propName]; 431 obj.distance = to - obj.from; 432 } 433 434 var startTime = (new Date).getTime(); 435 436 var animateFunc = function() 437 { 438 var elapsedTime = ((new Date).getTime()) - startTime; 439 440 if (elapsedTime > opts.duration) 441 { 442 for (var i = 0; i < objs.length; i++) 443 objs[i].ele[propName] = to; 444 if (opts.onComplete) 445 opts.onComplete(); 446 } 447 else 448 { 449 for (var i = 0; i < objs.length; i++) 450 { 451 var obj = objs[i]; 452 obj.ele[propName] = opts.transition(elapsedTime, obj.from, obj.distance, opts.duration); 453 } 454 setTimeout(animateFunc, opts.interval); 455 } 456 }; 457 458 setTimeout(animateFunc, opts.interval); 459 return this; 460};
461 462Spry.$$.Results.animateStyleTo = function(styleStr, options) 463{ 464 var a = new Spry.Effect.CSSAnimator(this, styleStr, options); 465 a.start(); 466 return this; 467}; 468 469})(); // EndSpryComponent
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.