0
|
1 /*
|
|
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
|
3 Code licensed under the BSD License:
|
|
4 http://developer.yahoo.net/yui/license.txt
|
|
5 version: 2.8.0r4
|
|
6 */
|
|
7 (function() {
|
|
8
|
|
9 var Y = YAHOO.util;
|
|
10
|
|
11 /*
|
|
12 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
|
|
13 Code licensed under the BSD License:
|
|
14 http://developer.yahoo.net/yui/license.txt
|
|
15 */
|
|
16
|
|
17 /**
|
|
18 * The animation module provides allows effects to be added to HTMLElements.
|
|
19 * @module animation
|
|
20 * @requires yahoo, event, dom
|
|
21 */
|
|
22
|
|
23 /**
|
|
24 *
|
|
25 * Base animation class that provides the interface for building animated effects.
|
|
26 * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
|
|
27 * @class Anim
|
|
28 * @namespace YAHOO.util
|
|
29 * @requires YAHOO.util.AnimMgr
|
|
30 * @requires YAHOO.util.Easing
|
|
31 * @requires YAHOO.util.Dom
|
|
32 * @requires YAHOO.util.Event
|
|
33 * @requires YAHOO.util.CustomEvent
|
|
34 * @constructor
|
|
35 * @param {String | HTMLElement} el Reference to the element that will be animated
|
|
36 * @param {Object} attributes The attribute(s) to be animated.
|
|
37 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
38 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
39 * All attribute names use camelCase.
|
|
40 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
41 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
42 */
|
|
43
|
|
44 var Anim = function(el, attributes, duration, method) {
|
|
45 if (!el) {
|
|
46 YAHOO.log('element required to create Anim instance', 'error', 'Anim');
|
|
47 }
|
|
48 this.init(el, attributes, duration, method);
|
|
49 };
|
|
50
|
|
51 Anim.NAME = 'Anim';
|
|
52
|
|
53 Anim.prototype = {
|
|
54 /**
|
|
55 * Provides a readable name for the Anim instance.
|
|
56 * @method toString
|
|
57 * @return {String}
|
|
58 */
|
|
59 toString: function() {
|
|
60 var el = this.getEl() || {};
|
|
61 var id = el.id || el.tagName;
|
|
62 return (this.constructor.NAME + ': ' + id);
|
|
63 },
|
|
64
|
|
65 patterns: { // cached for performance
|
|
66 noNegatives: /width|height|opacity|padding/i, // keep at zero or above
|
|
67 offsetAttribute: /^((width|height)|(top|left))$/, // use offsetValue as default
|
|
68 defaultUnit: /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
|
|
69 offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
|
|
70 },
|
|
71
|
|
72 /**
|
|
73 * Returns the value computed by the animation's "method".
|
|
74 * @method doMethod
|
|
75 * @param {String} attr The name of the attribute.
|
|
76 * @param {Number} start The value this attribute should start from for this animation.
|
|
77 * @param {Number} end The value this attribute should end at for this animation.
|
|
78 * @return {Number} The Value to be applied to the attribute.
|
|
79 */
|
|
80 doMethod: function(attr, start, end) {
|
|
81 return this.method(this.currentFrame, start, end - start, this.totalFrames);
|
|
82 },
|
|
83
|
|
84 /**
|
|
85 * Applies a value to an attribute.
|
|
86 * @method setAttribute
|
|
87 * @param {String} attr The name of the attribute.
|
|
88 * @param {Number} val The value to be applied to the attribute.
|
|
89 * @param {String} unit The unit ('px', '%', etc.) of the value.
|
|
90 */
|
|
91 setAttribute: function(attr, val, unit) {
|
|
92 var el = this.getEl();
|
|
93 if ( this.patterns.noNegatives.test(attr) ) {
|
|
94 val = (val > 0) ? val : 0;
|
|
95 }
|
|
96
|
|
97 if (attr in el && !('style' in el && attr in el.style)) {
|
|
98 el[attr] = val;
|
|
99 } else {
|
|
100 Y.Dom.setStyle(el, attr, val + unit);
|
|
101 }
|
|
102 },
|
|
103
|
|
104 /**
|
|
105 * Returns current value of the attribute.
|
|
106 * @method getAttribute
|
|
107 * @param {String} attr The name of the attribute.
|
|
108 * @return {Number} val The current value of the attribute.
|
|
109 */
|
|
110 getAttribute: function(attr) {
|
|
111 var el = this.getEl();
|
|
112 var val = Y.Dom.getStyle(el, attr);
|
|
113
|
|
114 if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
|
|
115 return parseFloat(val);
|
|
116 }
|
|
117
|
|
118 var a = this.patterns.offsetAttribute.exec(attr) || [];
|
|
119 var pos = !!( a[3] ); // top or left
|
|
120 var box = !!( a[2] ); // width or height
|
|
121
|
|
122 if ('style' in el) {
|
|
123 // use offsets for width/height and abs pos top/left
|
|
124 if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
|
|
125 val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
|
|
126 } else { // default to zero for other 'auto'
|
|
127 val = 0;
|
|
128 }
|
|
129 } else if (attr in el) {
|
|
130 val = el[attr];
|
|
131 }
|
|
132
|
|
133 return val;
|
|
134 },
|
|
135
|
|
136 /**
|
|
137 * Returns the unit to use when none is supplied.
|
|
138 * @method getDefaultUnit
|
|
139 * @param {attr} attr The name of the attribute.
|
|
140 * @return {String} The default unit to be used.
|
|
141 */
|
|
142 getDefaultUnit: function(attr) {
|
|
143 if ( this.patterns.defaultUnit.test(attr) ) {
|
|
144 return 'px';
|
|
145 }
|
|
146
|
|
147 return '';
|
|
148 },
|
|
149
|
|
150 /**
|
|
151 * Sets the actual values to be used during the animation. Should only be needed for subclass use.
|
|
152 * @method setRuntimeAttribute
|
|
153 * @param {Object} attr The attribute object
|
|
154 * @private
|
|
155 */
|
|
156 setRuntimeAttribute: function(attr) {
|
|
157 var start;
|
|
158 var end;
|
|
159 var attributes = this.attributes;
|
|
160
|
|
161 this.runtimeAttributes[attr] = {};
|
|
162
|
|
163 var isset = function(prop) {
|
|
164 return (typeof prop !== 'undefined');
|
|
165 };
|
|
166
|
|
167 if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
|
|
168 return false; // note return; nothing to animate to
|
|
169 }
|
|
170
|
|
171 start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
|
|
172
|
|
173 // To beats by, per SMIL 2.1 spec
|
|
174 if ( isset(attributes[attr]['to']) ) {
|
|
175 end = attributes[attr]['to'];
|
|
176 } else if ( isset(attributes[attr]['by']) ) {
|
|
177 if (start.constructor == Array) {
|
|
178 end = [];
|
|
179 for (var i = 0, len = start.length; i < len; ++i) {
|
|
180 end[i] = start[i] + attributes[attr]['by'][i] * 1; // times 1 to cast "by"
|
|
181 }
|
|
182 } else {
|
|
183 end = start + attributes[attr]['by'] * 1;
|
|
184 }
|
|
185 }
|
|
186
|
|
187 this.runtimeAttributes[attr].start = start;
|
|
188 this.runtimeAttributes[attr].end = end;
|
|
189
|
|
190 // set units if needed
|
|
191 this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
|
|
192 attributes[attr]['unit'] : this.getDefaultUnit(attr);
|
|
193 return true;
|
|
194 },
|
|
195
|
|
196 /**
|
|
197 * Constructor for Anim instance.
|
|
198 * @method init
|
|
199 * @param {String | HTMLElement} el Reference to the element that will be animated
|
|
200 * @param {Object} attributes The attribute(s) to be animated.
|
|
201 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
202 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
203 * All attribute names use camelCase.
|
|
204 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
205 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
206 */
|
|
207 init: function(el, attributes, duration, method) {
|
|
208 /**
|
|
209 * Whether or not the animation is running.
|
|
210 * @property isAnimated
|
|
211 * @private
|
|
212 * @type Boolean
|
|
213 */
|
|
214 var isAnimated = false;
|
|
215
|
|
216 /**
|
|
217 * A Date object that is created when the animation begins.
|
|
218 * @property startTime
|
|
219 * @private
|
|
220 * @type Date
|
|
221 */
|
|
222 var startTime = null;
|
|
223
|
|
224 /**
|
|
225 * The number of frames this animation was able to execute.
|
|
226 * @property actualFrames
|
|
227 * @private
|
|
228 * @type Int
|
|
229 */
|
|
230 var actualFrames = 0;
|
|
231
|
|
232 /**
|
|
233 * The element to be animated.
|
|
234 * @property el
|
|
235 * @private
|
|
236 * @type HTMLElement
|
|
237 */
|
|
238 el = Y.Dom.get(el);
|
|
239
|
|
240 /**
|
|
241 * The collection of attributes to be animated.
|
|
242 * Each attribute must have at least a "to" or "by" defined in order to animate.
|
|
243 * If "to" is supplied, the animation will end with the attribute at that value.
|
|
244 * If "by" is supplied, the animation will end at that value plus its starting value.
|
|
245 * If both are supplied, "to" is used, and "by" is ignored.
|
|
246 * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
|
|
247 * @property attributes
|
|
248 * @type Object
|
|
249 */
|
|
250 this.attributes = attributes || {};
|
|
251
|
|
252 /**
|
|
253 * The length of the animation. Defaults to "1" (second).
|
|
254 * @property duration
|
|
255 * @type Number
|
|
256 */
|
|
257 this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
|
|
258
|
|
259 /**
|
|
260 * The method that will provide values to the attribute(s) during the animation.
|
|
261 * Defaults to "YAHOO.util.Easing.easeNone".
|
|
262 * @property method
|
|
263 * @type Function
|
|
264 */
|
|
265 this.method = method || Y.Easing.easeNone;
|
|
266
|
|
267 /**
|
|
268 * Whether or not the duration should be treated as seconds.
|
|
269 * Defaults to true.
|
|
270 * @property useSeconds
|
|
271 * @type Boolean
|
|
272 */
|
|
273 this.useSeconds = true; // default to seconds
|
|
274
|
|
275 /**
|
|
276 * The location of the current animation on the timeline.
|
|
277 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
|
|
278 * @property currentFrame
|
|
279 * @type Int
|
|
280 */
|
|
281 this.currentFrame = 0;
|
|
282
|
|
283 /**
|
|
284 * The total number of frames to be executed.
|
|
285 * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
|
|
286 * @property totalFrames
|
|
287 * @type Int
|
|
288 */
|
|
289 this.totalFrames = Y.AnimMgr.fps;
|
|
290
|
|
291 /**
|
|
292 * Changes the animated element
|
|
293 * @method setEl
|
|
294 */
|
|
295 this.setEl = function(element) {
|
|
296 el = Y.Dom.get(element);
|
|
297 };
|
|
298
|
|
299 /**
|
|
300 * Returns a reference to the animated element.
|
|
301 * @method getEl
|
|
302 * @return {HTMLElement}
|
|
303 */
|
|
304 this.getEl = function() { return el; };
|
|
305
|
|
306 /**
|
|
307 * Checks whether the element is currently animated.
|
|
308 * @method isAnimated
|
|
309 * @return {Boolean} current value of isAnimated.
|
|
310 */
|
|
311 this.isAnimated = function() {
|
|
312 return isAnimated;
|
|
313 };
|
|
314
|
|
315 /**
|
|
316 * Returns the animation start time.
|
|
317 * @method getStartTime
|
|
318 * @return {Date} current value of startTime.
|
|
319 */
|
|
320 this.getStartTime = function() {
|
|
321 return startTime;
|
|
322 };
|
|
323
|
|
324 this.runtimeAttributes = {};
|
|
325
|
|
326 var logger = {};
|
|
327 logger.log = function() {YAHOO.log.apply(window, arguments)};
|
|
328
|
|
329 logger.log('creating new instance of ' + this);
|
|
330
|
|
331 /**
|
|
332 * Starts the animation by registering it with the animation manager.
|
|
333 * @method animate
|
|
334 */
|
|
335 this.animate = function() {
|
|
336 if ( this.isAnimated() ) {
|
|
337 return false;
|
|
338 }
|
|
339
|
|
340 this.currentFrame = 0;
|
|
341
|
|
342 this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
|
|
343
|
|
344 if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration
|
|
345 this.totalFrames = 1;
|
|
346 }
|
|
347 Y.AnimMgr.registerElement(this);
|
|
348 return true;
|
|
349 };
|
|
350
|
|
351 /**
|
|
352 * Stops the animation. Normally called by AnimMgr when animation completes.
|
|
353 * @method stop
|
|
354 * @param {Boolean} finish (optional) If true, animation will jump to final frame.
|
|
355 */
|
|
356 this.stop = function(finish) {
|
|
357 if (!this.isAnimated()) { // nothing to stop
|
|
358 return false;
|
|
359 }
|
|
360
|
|
361 if (finish) {
|
|
362 this.currentFrame = this.totalFrames;
|
|
363 this._onTween.fire();
|
|
364 }
|
|
365 Y.AnimMgr.stop(this);
|
|
366 };
|
|
367
|
|
368 var onStart = function() {
|
|
369 this.onStart.fire();
|
|
370
|
|
371 this.runtimeAttributes = {};
|
|
372 for (var attr in this.attributes) {
|
|
373 this.setRuntimeAttribute(attr);
|
|
374 }
|
|
375
|
|
376 isAnimated = true;
|
|
377 actualFrames = 0;
|
|
378 startTime = new Date();
|
|
379 };
|
|
380
|
|
381 /**
|
|
382 * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
|
|
383 * @private
|
|
384 */
|
|
385
|
|
386 var onTween = function() {
|
|
387 var data = {
|
|
388 duration: new Date() - this.getStartTime(),
|
|
389 currentFrame: this.currentFrame
|
|
390 };
|
|
391
|
|
392 data.toString = function() {
|
|
393 return (
|
|
394 'duration: ' + data.duration +
|
|
395 ', currentFrame: ' + data.currentFrame
|
|
396 );
|
|
397 };
|
|
398
|
|
399 this.onTween.fire(data);
|
|
400
|
|
401 var runtimeAttributes = this.runtimeAttributes;
|
|
402
|
|
403 for (var attr in runtimeAttributes) {
|
|
404 this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
|
|
405 }
|
|
406
|
|
407 actualFrames += 1;
|
|
408 };
|
|
409
|
|
410 var onComplete = function() {
|
|
411 var actual_duration = (new Date() - startTime) / 1000 ;
|
|
412
|
|
413 var data = {
|
|
414 duration: actual_duration,
|
|
415 frames: actualFrames,
|
|
416 fps: actualFrames / actual_duration
|
|
417 };
|
|
418
|
|
419 data.toString = function() {
|
|
420 return (
|
|
421 'duration: ' + data.duration +
|
|
422 ', frames: ' + data.frames +
|
|
423 ', fps: ' + data.fps
|
|
424 );
|
|
425 };
|
|
426
|
|
427 isAnimated = false;
|
|
428 actualFrames = 0;
|
|
429 this.onComplete.fire(data);
|
|
430 };
|
|
431
|
|
432 /**
|
|
433 * Custom event that fires after onStart, useful in subclassing
|
|
434 * @private
|
|
435 */
|
|
436 this._onStart = new Y.CustomEvent('_start', this, true);
|
|
437
|
|
438 /**
|
|
439 * Custom event that fires when animation begins
|
|
440 * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
|
|
441 * @event onStart
|
|
442 */
|
|
443 this.onStart = new Y.CustomEvent('start', this);
|
|
444
|
|
445 /**
|
|
446 * Custom event that fires between each frame
|
|
447 * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
|
|
448 * @event onTween
|
|
449 */
|
|
450 this.onTween = new Y.CustomEvent('tween', this);
|
|
451
|
|
452 /**
|
|
453 * Custom event that fires after onTween
|
|
454 * @private
|
|
455 */
|
|
456 this._onTween = new Y.CustomEvent('_tween', this, true);
|
|
457
|
|
458 /**
|
|
459 * Custom event that fires when animation ends
|
|
460 * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
|
|
461 * @event onComplete
|
|
462 */
|
|
463 this.onComplete = new Y.CustomEvent('complete', this);
|
|
464 /**
|
|
465 * Custom event that fires after onComplete
|
|
466 * @private
|
|
467 */
|
|
468 this._onComplete = new Y.CustomEvent('_complete', this, true);
|
|
469
|
|
470 this._onStart.subscribe(onStart);
|
|
471 this._onTween.subscribe(onTween);
|
|
472 this._onComplete.subscribe(onComplete);
|
|
473 }
|
|
474 };
|
|
475
|
|
476 Y.Anim = Anim;
|
|
477 })();
|
|
478 /**
|
|
479 * Handles animation queueing and threading.
|
|
480 * Used by Anim and subclasses.
|
|
481 * @class AnimMgr
|
|
482 * @namespace YAHOO.util
|
|
483 */
|
|
484 YAHOO.util.AnimMgr = new function() {
|
|
485 /**
|
|
486 * Reference to the animation Interval.
|
|
487 * @property thread
|
|
488 * @private
|
|
489 * @type Int
|
|
490 */
|
|
491 var thread = null;
|
|
492
|
|
493 /**
|
|
494 * The current queue of registered animation objects.
|
|
495 * @property queue
|
|
496 * @private
|
|
497 * @type Array
|
|
498 */
|
|
499 var queue = [];
|
|
500
|
|
501 /**
|
|
502 * The number of active animations.
|
|
503 * @property tweenCount
|
|
504 * @private
|
|
505 * @type Int
|
|
506 */
|
|
507 var tweenCount = 0;
|
|
508
|
|
509 /**
|
|
510 * Base frame rate (frames per second).
|
|
511 * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
|
|
512 * @property fps
|
|
513 * @type Int
|
|
514 *
|
|
515 */
|
|
516 this.fps = 1000;
|
|
517
|
|
518 /**
|
|
519 * Interval delay in milliseconds, defaults to fastest possible.
|
|
520 * @property delay
|
|
521 * @type Int
|
|
522 *
|
|
523 */
|
|
524 this.delay = 1;
|
|
525
|
|
526 /**
|
|
527 * Adds an animation instance to the animation queue.
|
|
528 * All animation instances must be registered in order to animate.
|
|
529 * @method registerElement
|
|
530 * @param {object} tween The Anim instance to be be registered
|
|
531 */
|
|
532 this.registerElement = function(tween) {
|
|
533 queue[queue.length] = tween;
|
|
534 tweenCount += 1;
|
|
535 tween._onStart.fire();
|
|
536 this.start();
|
|
537 };
|
|
538
|
|
539 /**
|
|
540 * removes an animation instance from the animation queue.
|
|
541 * All animation instances must be registered in order to animate.
|
|
542 * @method unRegister
|
|
543 * @param {object} tween The Anim instance to be be registered
|
|
544 * @param {Int} index The index of the Anim instance
|
|
545 * @private
|
|
546 */
|
|
547 this.unRegister = function(tween, index) {
|
|
548 index = index || getIndex(tween);
|
|
549 if (!tween.isAnimated() || index === -1) {
|
|
550 return false;
|
|
551 }
|
|
552
|
|
553 tween._onComplete.fire();
|
|
554 queue.splice(index, 1);
|
|
555
|
|
556 tweenCount -= 1;
|
|
557 if (tweenCount <= 0) {
|
|
558 this.stop();
|
|
559 }
|
|
560
|
|
561 return true;
|
|
562 };
|
|
563
|
|
564 /**
|
|
565 * Starts the animation thread.
|
|
566 * Only one thread can run at a time.
|
|
567 * @method start
|
|
568 */
|
|
569 this.start = function() {
|
|
570 if (thread === null) {
|
|
571 thread = setInterval(this.run, this.delay);
|
|
572 }
|
|
573 };
|
|
574
|
|
575 /**
|
|
576 * Stops the animation thread or a specific animation instance.
|
|
577 * @method stop
|
|
578 * @param {object} tween A specific Anim instance to stop (optional)
|
|
579 * If no instance given, Manager stops thread and all animations.
|
|
580 */
|
|
581 this.stop = function(tween) {
|
|
582 if (!tween) {
|
|
583 clearInterval(thread);
|
|
584
|
|
585 for (var i = 0, len = queue.length; i < len; ++i) {
|
|
586 this.unRegister(queue[0], 0);
|
|
587 }
|
|
588
|
|
589 queue = [];
|
|
590 thread = null;
|
|
591 tweenCount = 0;
|
|
592 }
|
|
593 else {
|
|
594 this.unRegister(tween);
|
|
595 }
|
|
596 };
|
|
597
|
|
598 /**
|
|
599 * Called per Interval to handle each animation frame.
|
|
600 * @method run
|
|
601 */
|
|
602 this.run = function() {
|
|
603 for (var i = 0, len = queue.length; i < len; ++i) {
|
|
604 var tween = queue[i];
|
|
605 if ( !tween || !tween.isAnimated() ) { continue; }
|
|
606
|
|
607 if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
|
|
608 {
|
|
609 tween.currentFrame += 1;
|
|
610
|
|
611 if (tween.useSeconds) {
|
|
612 correctFrame(tween);
|
|
613 }
|
|
614 tween._onTween.fire();
|
|
615 }
|
|
616 else { YAHOO.util.AnimMgr.stop(tween, i); }
|
|
617 }
|
|
618 };
|
|
619
|
|
620 var getIndex = function(anim) {
|
|
621 for (var i = 0, len = queue.length; i < len; ++i) {
|
|
622 if (queue[i] === anim) {
|
|
623 return i; // note return;
|
|
624 }
|
|
625 }
|
|
626 return -1;
|
|
627 };
|
|
628
|
|
629 /**
|
|
630 * On the fly frame correction to keep animation on time.
|
|
631 * @method correctFrame
|
|
632 * @private
|
|
633 * @param {Object} tween The Anim instance being corrected.
|
|
634 */
|
|
635 var correctFrame = function(tween) {
|
|
636 var frames = tween.totalFrames;
|
|
637 var frame = tween.currentFrame;
|
|
638 var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
|
|
639 var elapsed = (new Date() - tween.getStartTime());
|
|
640 var tweak = 0;
|
|
641
|
|
642 if (elapsed < tween.duration * 1000) { // check if falling behind
|
|
643 tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
|
|
644 } else { // went over duration, so jump to end
|
|
645 tweak = frames - (frame + 1);
|
|
646 }
|
|
647 if (tweak > 0 && isFinite(tweak)) { // adjust if needed
|
|
648 if (tween.currentFrame + tweak >= frames) {// dont go past last frame
|
|
649 tweak = frames - (frame + 1);
|
|
650 }
|
|
651
|
|
652 tween.currentFrame += tweak;
|
|
653 }
|
|
654 };
|
|
655 this._queue = queue;
|
|
656 this._getIndex = getIndex;
|
|
657 };
|
|
658 /**
|
|
659 * Used to calculate Bezier splines for any number of control points.
|
|
660 * @class Bezier
|
|
661 * @namespace YAHOO.util
|
|
662 *
|
|
663 */
|
|
664 YAHOO.util.Bezier = new function() {
|
|
665 /**
|
|
666 * Get the current position of the animated element based on t.
|
|
667 * Each point is an array of "x" and "y" values (0 = x, 1 = y)
|
|
668 * At least 2 points are required (start and end).
|
|
669 * First point is start. Last point is end.
|
|
670 * Additional control points are optional.
|
|
671 * @method getPosition
|
|
672 * @param {Array} points An array containing Bezier points
|
|
673 * @param {Number} t A number between 0 and 1 which is the basis for determining current position
|
|
674 * @return {Array} An array containing int x and y member data
|
|
675 */
|
|
676 this.getPosition = function(points, t) {
|
|
677 var n = points.length;
|
|
678 var tmp = [];
|
|
679
|
|
680 for (var i = 0; i < n; ++i){
|
|
681 tmp[i] = [points[i][0], points[i][1]]; // save input
|
|
682 }
|
|
683
|
|
684 for (var j = 1; j < n; ++j) {
|
|
685 for (i = 0; i < n - j; ++i) {
|
|
686 tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
|
|
687 tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
|
|
688 }
|
|
689 }
|
|
690
|
|
691 return [ tmp[0][0], tmp[0][1] ];
|
|
692
|
|
693 };
|
|
694 };
|
|
695 (function() {
|
|
696 /**
|
|
697 * Anim subclass for color transitions.
|
|
698 * <p>Usage: <code>var myAnim = new Y.ColorAnim(el, { backgroundColor: { from: '#FF0000', to: '#FFFFFF' } }, 1, Y.Easing.easeOut);</code> Color values can be specified with either 112233, #112233,
|
|
699 * [255,255,255], or rgb(255,255,255)</p>
|
|
700 * @class ColorAnim
|
|
701 * @namespace YAHOO.util
|
|
702 * @requires YAHOO.util.Anim
|
|
703 * @requires YAHOO.util.AnimMgr
|
|
704 * @requires YAHOO.util.Easing
|
|
705 * @requires YAHOO.util.Bezier
|
|
706 * @requires YAHOO.util.Dom
|
|
707 * @requires YAHOO.util.Event
|
|
708 * @constructor
|
|
709 * @extends YAHOO.util.Anim
|
|
710 * @param {HTMLElement | String} el Reference to the element that will be animated
|
|
711 * @param {Object} attributes The attribute(s) to be animated.
|
|
712 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
713 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
714 * All attribute names use camelCase.
|
|
715 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
716 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
717 */
|
|
718 var ColorAnim = function(el, attributes, duration, method) {
|
|
719 ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
|
|
720 };
|
|
721
|
|
722 ColorAnim.NAME = 'ColorAnim';
|
|
723
|
|
724 ColorAnim.DEFAULT_BGCOLOR = '#fff';
|
|
725 // shorthand
|
|
726 var Y = YAHOO.util;
|
|
727 YAHOO.extend(ColorAnim, Y.Anim);
|
|
728
|
|
729 var superclass = ColorAnim.superclass;
|
|
730 var proto = ColorAnim.prototype;
|
|
731
|
|
732 proto.patterns.color = /color$/i;
|
|
733 proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
|
|
734 proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
|
|
735 proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
|
|
736 proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
|
|
737
|
|
738 /**
|
|
739 * Attempts to parse the given string and return a 3-tuple.
|
|
740 * @method parseColor
|
|
741 * @param {String} s The string to parse.
|
|
742 * @return {Array} The 3-tuple of rgb values.
|
|
743 */
|
|
744 proto.parseColor = function(s) {
|
|
745 if (s.length == 3) { return s; }
|
|
746
|
|
747 var c = this.patterns.hex.exec(s);
|
|
748 if (c && c.length == 4) {
|
|
749 return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
|
|
750 }
|
|
751
|
|
752 c = this.patterns.rgb.exec(s);
|
|
753 if (c && c.length == 4) {
|
|
754 return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
|
|
755 }
|
|
756
|
|
757 c = this.patterns.hex3.exec(s);
|
|
758 if (c && c.length == 4) {
|
|
759 return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
|
|
760 }
|
|
761
|
|
762 return null;
|
|
763 };
|
|
764
|
|
765 proto.getAttribute = function(attr) {
|
|
766 var el = this.getEl();
|
|
767 if (this.patterns.color.test(attr) ) {
|
|
768 var val = YAHOO.util.Dom.getStyle(el, attr);
|
|
769
|
|
770 var that = this;
|
|
771 if (this.patterns.transparent.test(val)) { // bgcolor default
|
|
772 var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
|
|
773 return !that.patterns.transparent.test(val);
|
|
774 });
|
|
775
|
|
776 if (parent) {
|
|
777 val = Y.Dom.getStyle(parent, attr);
|
|
778 } else {
|
|
779 val = ColorAnim.DEFAULT_BGCOLOR;
|
|
780 }
|
|
781 }
|
|
782 } else {
|
|
783 val = superclass.getAttribute.call(this, attr);
|
|
784 }
|
|
785
|
|
786 return val;
|
|
787 };
|
|
788
|
|
789 proto.doMethod = function(attr, start, end) {
|
|
790 var val;
|
|
791
|
|
792 if ( this.patterns.color.test(attr) ) {
|
|
793 val = [];
|
|
794 for (var i = 0, len = start.length; i < len; ++i) {
|
|
795 val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
|
|
796 }
|
|
797
|
|
798 val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
|
|
799 }
|
|
800 else {
|
|
801 val = superclass.doMethod.call(this, attr, start, end);
|
|
802 }
|
|
803
|
|
804 return val;
|
|
805 };
|
|
806
|
|
807 proto.setRuntimeAttribute = function(attr) {
|
|
808 superclass.setRuntimeAttribute.call(this, attr);
|
|
809
|
|
810 if ( this.patterns.color.test(attr) ) {
|
|
811 var attributes = this.attributes;
|
|
812 var start = this.parseColor(this.runtimeAttributes[attr].start);
|
|
813 var end = this.parseColor(this.runtimeAttributes[attr].end);
|
|
814 // fix colors if going "by"
|
|
815 if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
|
|
816 end = this.parseColor(attributes[attr].by);
|
|
817
|
|
818 for (var i = 0, len = start.length; i < len; ++i) {
|
|
819 end[i] = start[i] + end[i];
|
|
820 }
|
|
821 }
|
|
822
|
|
823 this.runtimeAttributes[attr].start = start;
|
|
824 this.runtimeAttributes[attr].end = end;
|
|
825 }
|
|
826 };
|
|
827
|
|
828 Y.ColorAnim = ColorAnim;
|
|
829 })();
|
|
830 /*!
|
|
831 TERMS OF USE - EASING EQUATIONS
|
|
832 Open source under the BSD License.
|
|
833 Copyright 2001 Robert Penner All rights reserved.
|
|
834
|
|
835 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
836
|
|
837 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
838 * 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.
|
|
839 * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
840
|
|
841 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.
|
|
842 */
|
|
843
|
|
844 /**
|
|
845 * Singleton that determines how an animation proceeds from start to end.
|
|
846 * @class Easing
|
|
847 * @namespace YAHOO.util
|
|
848 */
|
|
849
|
|
850 YAHOO.util.Easing = {
|
|
851
|
|
852 /**
|
|
853 * Uniform speed between points.
|
|
854 * @method easeNone
|
|
855 * @param {Number} t Time value used to compute current value
|
|
856 * @param {Number} b Starting value
|
|
857 * @param {Number} c Delta between start and end values
|
|
858 * @param {Number} d Total length of animation
|
|
859 * @return {Number} The computed value for the current animation frame
|
|
860 */
|
|
861 easeNone: function (t, b, c, d) {
|
|
862 return c*t/d + b;
|
|
863 },
|
|
864
|
|
865 /**
|
|
866 * Begins slowly and accelerates towards end.
|
|
867 * @method easeIn
|
|
868 * @param {Number} t Time value used to compute current value
|
|
869 * @param {Number} b Starting value
|
|
870 * @param {Number} c Delta between start and end values
|
|
871 * @param {Number} d Total length of animation
|
|
872 * @return {Number} The computed value for the current animation frame
|
|
873 */
|
|
874 easeIn: function (t, b, c, d) {
|
|
875 return c*(t/=d)*t + b;
|
|
876 },
|
|
877
|
|
878 /**
|
|
879 * Begins quickly and decelerates towards end.
|
|
880 * @method easeOut
|
|
881 * @param {Number} t Time value used to compute current value
|
|
882 * @param {Number} b Starting value
|
|
883 * @param {Number} c Delta between start and end values
|
|
884 * @param {Number} d Total length of animation
|
|
885 * @return {Number} The computed value for the current animation frame
|
|
886 */
|
|
887 easeOut: function (t, b, c, d) {
|
|
888 return -c *(t/=d)*(t-2) + b;
|
|
889 },
|
|
890
|
|
891 /**
|
|
892 * Begins slowly and decelerates towards end.
|
|
893 * @method easeBoth
|
|
894 * @param {Number} t Time value used to compute current value
|
|
895 * @param {Number} b Starting value
|
|
896 * @param {Number} c Delta between start and end values
|
|
897 * @param {Number} d Total length of animation
|
|
898 * @return {Number} The computed value for the current animation frame
|
|
899 */
|
|
900 easeBoth: function (t, b, c, d) {
|
|
901 if ((t/=d/2) < 1) {
|
|
902 return c/2*t*t + b;
|
|
903 }
|
|
904
|
|
905 return -c/2 * ((--t)*(t-2) - 1) + b;
|
|
906 },
|
|
907
|
|
908 /**
|
|
909 * Begins slowly and accelerates towards end.
|
|
910 * @method easeInStrong
|
|
911 * @param {Number} t Time value used to compute current value
|
|
912 * @param {Number} b Starting value
|
|
913 * @param {Number} c Delta between start and end values
|
|
914 * @param {Number} d Total length of animation
|
|
915 * @return {Number} The computed value for the current animation frame
|
|
916 */
|
|
917 easeInStrong: function (t, b, c, d) {
|
|
918 return c*(t/=d)*t*t*t + b;
|
|
919 },
|
|
920
|
|
921 /**
|
|
922 * Begins quickly and decelerates towards end.
|
|
923 * @method easeOutStrong
|
|
924 * @param {Number} t Time value used to compute current value
|
|
925 * @param {Number} b Starting value
|
|
926 * @param {Number} c Delta between start and end values
|
|
927 * @param {Number} d Total length of animation
|
|
928 * @return {Number} The computed value for the current animation frame
|
|
929 */
|
|
930 easeOutStrong: function (t, b, c, d) {
|
|
931 return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
|
932 },
|
|
933
|
|
934 /**
|
|
935 * Begins slowly and decelerates towards end.
|
|
936 * @method easeBothStrong
|
|
937 * @param {Number} t Time value used to compute current value
|
|
938 * @param {Number} b Starting value
|
|
939 * @param {Number} c Delta between start and end values
|
|
940 * @param {Number} d Total length of animation
|
|
941 * @return {Number} The computed value for the current animation frame
|
|
942 */
|
|
943 easeBothStrong: function (t, b, c, d) {
|
|
944 if ((t/=d/2) < 1) {
|
|
945 return c/2*t*t*t*t + b;
|
|
946 }
|
|
947
|
|
948 return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
|
949 },
|
|
950
|
|
951 /**
|
|
952 * Snap in elastic effect.
|
|
953 * @method elasticIn
|
|
954 * @param {Number} t Time value used to compute current value
|
|
955 * @param {Number} b Starting value
|
|
956 * @param {Number} c Delta between start and end values
|
|
957 * @param {Number} d Total length of animation
|
|
958 * @param {Number} a Amplitude (optional)
|
|
959 * @param {Number} p Period (optional)
|
|
960 * @return {Number} The computed value for the current animation frame
|
|
961 */
|
|
962
|
|
963 elasticIn: function (t, b, c, d, a, p) {
|
|
964 if (t == 0) {
|
|
965 return b;
|
|
966 }
|
|
967 if ( (t /= d) == 1 ) {
|
|
968 return b+c;
|
|
969 }
|
|
970 if (!p) {
|
|
971 p=d*.3;
|
|
972 }
|
|
973
|
|
974 if (!a || a < Math.abs(c)) {
|
|
975 a = c;
|
|
976 var s = p/4;
|
|
977 }
|
|
978 else {
|
|
979 var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
980 }
|
|
981
|
|
982 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
|
983 },
|
|
984
|
|
985 /**
|
|
986 * Snap out elastic effect.
|
|
987 * @method elasticOut
|
|
988 * @param {Number} t Time value used to compute current value
|
|
989 * @param {Number} b Starting value
|
|
990 * @param {Number} c Delta between start and end values
|
|
991 * @param {Number} d Total length of animation
|
|
992 * @param {Number} a Amplitude (optional)
|
|
993 * @param {Number} p Period (optional)
|
|
994 * @return {Number} The computed value for the current animation frame
|
|
995 */
|
|
996 elasticOut: function (t, b, c, d, a, p) {
|
|
997 if (t == 0) {
|
|
998 return b;
|
|
999 }
|
|
1000 if ( (t /= d) == 1 ) {
|
|
1001 return b+c;
|
|
1002 }
|
|
1003 if (!p) {
|
|
1004 p=d*.3;
|
|
1005 }
|
|
1006
|
|
1007 if (!a || a < Math.abs(c)) {
|
|
1008 a = c;
|
|
1009 var s = p / 4;
|
|
1010 }
|
|
1011 else {
|
|
1012 var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
1013 }
|
|
1014
|
|
1015 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
|
1016 },
|
|
1017
|
|
1018 /**
|
|
1019 * Snap both elastic effect.
|
|
1020 * @method elasticBoth
|
|
1021 * @param {Number} t Time value used to compute current value
|
|
1022 * @param {Number} b Starting value
|
|
1023 * @param {Number} c Delta between start and end values
|
|
1024 * @param {Number} d Total length of animation
|
|
1025 * @param {Number} a Amplitude (optional)
|
|
1026 * @param {Number} p Period (optional)
|
|
1027 * @return {Number} The computed value for the current animation frame
|
|
1028 */
|
|
1029 elasticBoth: function (t, b, c, d, a, p) {
|
|
1030 if (t == 0) {
|
|
1031 return b;
|
|
1032 }
|
|
1033
|
|
1034 if ( (t /= d/2) == 2 ) {
|
|
1035 return b+c;
|
|
1036 }
|
|
1037
|
|
1038 if (!p) {
|
|
1039 p = d*(.3*1.5);
|
|
1040 }
|
|
1041
|
|
1042 if ( !a || a < Math.abs(c) ) {
|
|
1043 a = c;
|
|
1044 var s = p/4;
|
|
1045 }
|
|
1046 else {
|
|
1047 var s = p/(2*Math.PI) * Math.asin (c/a);
|
|
1048 }
|
|
1049
|
|
1050 if (t < 1) {
|
|
1051 return -.5*(a*Math.pow(2,10*(t-=1)) *
|
|
1052 Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
|
1053 }
|
|
1054 return a*Math.pow(2,-10*(t-=1)) *
|
|
1055 Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
|
1056 },
|
|
1057
|
|
1058
|
|
1059 /**
|
|
1060 * Backtracks slightly, then reverses direction and moves to end.
|
|
1061 * @method backIn
|
|
1062 * @param {Number} t Time value used to compute current value
|
|
1063 * @param {Number} b Starting value
|
|
1064 * @param {Number} c Delta between start and end values
|
|
1065 * @param {Number} d Total length of animation
|
|
1066 * @param {Number} s Overshoot (optional)
|
|
1067 * @return {Number} The computed value for the current animation frame
|
|
1068 */
|
|
1069 backIn: function (t, b, c, d, s) {
|
|
1070 if (typeof s == 'undefined') {
|
|
1071 s = 1.70158;
|
|
1072 }
|
|
1073 return c*(t/=d)*t*((s+1)*t - s) + b;
|
|
1074 },
|
|
1075
|
|
1076 /**
|
|
1077 * Overshoots end, then reverses and comes back to end.
|
|
1078 * @method backOut
|
|
1079 * @param {Number} t Time value used to compute current value
|
|
1080 * @param {Number} b Starting value
|
|
1081 * @param {Number} c Delta between start and end values
|
|
1082 * @param {Number} d Total length of animation
|
|
1083 * @param {Number} s Overshoot (optional)
|
|
1084 * @return {Number} The computed value for the current animation frame
|
|
1085 */
|
|
1086 backOut: function (t, b, c, d, s) {
|
|
1087 if (typeof s == 'undefined') {
|
|
1088 s = 1.70158;
|
|
1089 }
|
|
1090 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
|
1091 },
|
|
1092
|
|
1093 /**
|
|
1094 * Backtracks slightly, then reverses direction, overshoots end,
|
|
1095 * then reverses and comes back to end.
|
|
1096 * @method backBoth
|
|
1097 * @param {Number} t Time value used to compute current value
|
|
1098 * @param {Number} b Starting value
|
|
1099 * @param {Number} c Delta between start and end values
|
|
1100 * @param {Number} d Total length of animation
|
|
1101 * @param {Number} s Overshoot (optional)
|
|
1102 * @return {Number} The computed value for the current animation frame
|
|
1103 */
|
|
1104 backBoth: function (t, b, c, d, s) {
|
|
1105 if (typeof s == 'undefined') {
|
|
1106 s = 1.70158;
|
|
1107 }
|
|
1108
|
|
1109 if ((t /= d/2 ) < 1) {
|
|
1110 return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
|
1111 }
|
|
1112 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
|
1113 },
|
|
1114
|
|
1115 /**
|
|
1116 * Bounce off of start.
|
|
1117 * @method bounceIn
|
|
1118 * @param {Number} t Time value used to compute current value
|
|
1119 * @param {Number} b Starting value
|
|
1120 * @param {Number} c Delta between start and end values
|
|
1121 * @param {Number} d Total length of animation
|
|
1122 * @return {Number} The computed value for the current animation frame
|
|
1123 */
|
|
1124 bounceIn: function (t, b, c, d) {
|
|
1125 return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
|
|
1126 },
|
|
1127
|
|
1128 /**
|
|
1129 * Bounces off end.
|
|
1130 * @method bounceOut
|
|
1131 * @param {Number} t Time value used to compute current value
|
|
1132 * @param {Number} b Starting value
|
|
1133 * @param {Number} c Delta between start and end values
|
|
1134 * @param {Number} d Total length of animation
|
|
1135 * @return {Number} The computed value for the current animation frame
|
|
1136 */
|
|
1137 bounceOut: function (t, b, c, d) {
|
|
1138 if ((t/=d) < (1/2.75)) {
|
|
1139 return c*(7.5625*t*t) + b;
|
|
1140 } else if (t < (2/2.75)) {
|
|
1141 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
|
1142 } else if (t < (2.5/2.75)) {
|
|
1143 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
|
1144 }
|
|
1145 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
|
1146 },
|
|
1147
|
|
1148 /**
|
|
1149 * Bounces off start and end.
|
|
1150 * @method bounceBoth
|
|
1151 * @param {Number} t Time value used to compute current value
|
|
1152 * @param {Number} b Starting value
|
|
1153 * @param {Number} c Delta between start and end values
|
|
1154 * @param {Number} d Total length of animation
|
|
1155 * @return {Number} The computed value for the current animation frame
|
|
1156 */
|
|
1157 bounceBoth: function (t, b, c, d) {
|
|
1158 if (t < d/2) {
|
|
1159 return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
|
|
1160 }
|
|
1161 return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
|
|
1162 }
|
|
1163 };
|
|
1164
|
|
1165 (function() {
|
|
1166 /**
|
|
1167 * Anim subclass for moving elements along a path defined by the "points"
|
|
1168 * member of "attributes". All "points" are arrays with x, y coordinates.
|
|
1169 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
|
|
1170 * @class Motion
|
|
1171 * @namespace YAHOO.util
|
|
1172 * @requires YAHOO.util.Anim
|
|
1173 * @requires YAHOO.util.AnimMgr
|
|
1174 * @requires YAHOO.util.Easing
|
|
1175 * @requires YAHOO.util.Bezier
|
|
1176 * @requires YAHOO.util.Dom
|
|
1177 * @requires YAHOO.util.Event
|
|
1178 * @requires YAHOO.util.CustomEvent
|
|
1179 * @constructor
|
|
1180 * @extends YAHOO.util.ColorAnim
|
|
1181 * @param {String | HTMLElement} el Reference to the element that will be animated
|
|
1182 * @param {Object} attributes The attribute(s) to be animated.
|
|
1183 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
1184 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
1185 * All attribute names use camelCase.
|
|
1186 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
1187 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
1188 */
|
|
1189 var Motion = function(el, attributes, duration, method) {
|
|
1190 if (el) { // dont break existing subclasses not using YAHOO.extend
|
|
1191 Motion.superclass.constructor.call(this, el, attributes, duration, method);
|
|
1192 }
|
|
1193 };
|
|
1194
|
|
1195
|
|
1196 Motion.NAME = 'Motion';
|
|
1197
|
|
1198 // shorthand
|
|
1199 var Y = YAHOO.util;
|
|
1200 YAHOO.extend(Motion, Y.ColorAnim);
|
|
1201
|
|
1202 var superclass = Motion.superclass;
|
|
1203 var proto = Motion.prototype;
|
|
1204
|
|
1205 proto.patterns.points = /^points$/i;
|
|
1206
|
|
1207 proto.setAttribute = function(attr, val, unit) {
|
|
1208 if ( this.patterns.points.test(attr) ) {
|
|
1209 unit = unit || 'px';
|
|
1210 superclass.setAttribute.call(this, 'left', val[0], unit);
|
|
1211 superclass.setAttribute.call(this, 'top', val[1], unit);
|
|
1212 } else {
|
|
1213 superclass.setAttribute.call(this, attr, val, unit);
|
|
1214 }
|
|
1215 };
|
|
1216
|
|
1217 proto.getAttribute = function(attr) {
|
|
1218 if ( this.patterns.points.test(attr) ) {
|
|
1219 var val = [
|
|
1220 superclass.getAttribute.call(this, 'left'),
|
|
1221 superclass.getAttribute.call(this, 'top')
|
|
1222 ];
|
|
1223 } else {
|
|
1224 val = superclass.getAttribute.call(this, attr);
|
|
1225 }
|
|
1226
|
|
1227 return val;
|
|
1228 };
|
|
1229
|
|
1230 proto.doMethod = function(attr, start, end) {
|
|
1231 var val = null;
|
|
1232
|
|
1233 if ( this.patterns.points.test(attr) ) {
|
|
1234 var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
|
|
1235 val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
|
|
1236 } else {
|
|
1237 val = superclass.doMethod.call(this, attr, start, end);
|
|
1238 }
|
|
1239 return val;
|
|
1240 };
|
|
1241
|
|
1242 proto.setRuntimeAttribute = function(attr) {
|
|
1243 if ( this.patterns.points.test(attr) ) {
|
|
1244 var el = this.getEl();
|
|
1245 var attributes = this.attributes;
|
|
1246 var start;
|
|
1247 var control = attributes['points']['control'] || [];
|
|
1248 var end;
|
|
1249 var i, len;
|
|
1250
|
|
1251 if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
|
|
1252 control = [control];
|
|
1253 } else { // break reference to attributes.points.control
|
|
1254 var tmp = [];
|
|
1255 for (i = 0, len = control.length; i< len; ++i) {
|
|
1256 tmp[i] = control[i];
|
|
1257 }
|
|
1258 control = tmp;
|
|
1259 }
|
|
1260
|
|
1261 if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
|
|
1262 Y.Dom.setStyle(el, 'position', 'relative');
|
|
1263 }
|
|
1264
|
|
1265 if ( isset(attributes['points']['from']) ) {
|
|
1266 Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
|
|
1267 }
|
|
1268 else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
|
|
1269
|
|
1270 start = this.getAttribute('points'); // get actual top & left
|
|
1271
|
|
1272 // TO beats BY, per SMIL 2.1 spec
|
|
1273 if ( isset(attributes['points']['to']) ) {
|
|
1274 end = translateValues.call(this, attributes['points']['to'], start);
|
|
1275
|
|
1276 var pageXY = Y.Dom.getXY(this.getEl());
|
|
1277 for (i = 0, len = control.length; i < len; ++i) {
|
|
1278 control[i] = translateValues.call(this, control[i], start);
|
|
1279 }
|
|
1280
|
|
1281
|
|
1282 } else if ( isset(attributes['points']['by']) ) {
|
|
1283 end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
|
|
1284
|
|
1285 for (i = 0, len = control.length; i < len; ++i) {
|
|
1286 control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
|
|
1287 }
|
|
1288 }
|
|
1289
|
|
1290 this.runtimeAttributes[attr] = [start];
|
|
1291
|
|
1292 if (control.length > 0) {
|
|
1293 this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
|
|
1294 }
|
|
1295
|
|
1296 this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
|
|
1297 }
|
|
1298 else {
|
|
1299 superclass.setRuntimeAttribute.call(this, attr);
|
|
1300 }
|
|
1301 };
|
|
1302
|
|
1303 var translateValues = function(val, start) {
|
|
1304 var pageXY = Y.Dom.getXY(this.getEl());
|
|
1305 val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
|
|
1306
|
|
1307 return val;
|
|
1308 };
|
|
1309
|
|
1310 var isset = function(prop) {
|
|
1311 return (typeof prop !== 'undefined');
|
|
1312 };
|
|
1313
|
|
1314 Y.Motion = Motion;
|
|
1315 })();
|
|
1316 (function() {
|
|
1317 /**
|
|
1318 * Anim subclass for scrolling elements to a position defined by the "scroll"
|
|
1319 * member of "attributes". All "scroll" members are arrays with x, y scroll positions.
|
|
1320 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
|
|
1321 * @class Scroll
|
|
1322 * @namespace YAHOO.util
|
|
1323 * @requires YAHOO.util.Anim
|
|
1324 * @requires YAHOO.util.AnimMgr
|
|
1325 * @requires YAHOO.util.Easing
|
|
1326 * @requires YAHOO.util.Bezier
|
|
1327 * @requires YAHOO.util.Dom
|
|
1328 * @requires YAHOO.util.Event
|
|
1329 * @requires YAHOO.util.CustomEvent
|
|
1330 * @extends YAHOO.util.ColorAnim
|
|
1331 * @constructor
|
|
1332 * @param {String or HTMLElement} el Reference to the element that will be animated
|
|
1333 * @param {Object} attributes The attribute(s) to be animated.
|
|
1334 * Each attribute is an object with at minimum a "to" or "by" member defined.
|
|
1335 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
|
|
1336 * All attribute names use camelCase.
|
|
1337 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
|
|
1338 * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
|
|
1339 */
|
|
1340 var Scroll = function(el, attributes, duration, method) {
|
|
1341 if (el) { // dont break existing subclasses not using YAHOO.extend
|
|
1342 Scroll.superclass.constructor.call(this, el, attributes, duration, method);
|
|
1343 }
|
|
1344 };
|
|
1345
|
|
1346 Scroll.NAME = 'Scroll';
|
|
1347
|
|
1348 // shorthand
|
|
1349 var Y = YAHOO.util;
|
|
1350 YAHOO.extend(Scroll, Y.ColorAnim);
|
|
1351
|
|
1352 var superclass = Scroll.superclass;
|
|
1353 var proto = Scroll.prototype;
|
|
1354
|
|
1355 proto.doMethod = function(attr, start, end) {
|
|
1356 var val = null;
|
|
1357
|
|
1358 if (attr == 'scroll') {
|
|
1359 val = [
|
|
1360 this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
|
|
1361 this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
|
|
1362 ];
|
|
1363
|
|
1364 } else {
|
|
1365 val = superclass.doMethod.call(this, attr, start, end);
|
|
1366 }
|
|
1367 return val;
|
|
1368 };
|
|
1369
|
|
1370 proto.getAttribute = function(attr) {
|
|
1371 var val = null;
|
|
1372 var el = this.getEl();
|
|
1373
|
|
1374 if (attr == 'scroll') {
|
|
1375 val = [ el.scrollLeft, el.scrollTop ];
|
|
1376 } else {
|
|
1377 val = superclass.getAttribute.call(this, attr);
|
|
1378 }
|
|
1379
|
|
1380 return val;
|
|
1381 };
|
|
1382
|
|
1383 proto.setAttribute = function(attr, val, unit) {
|
|
1384 var el = this.getEl();
|
|
1385
|
|
1386 if (attr == 'scroll') {
|
|
1387 el.scrollLeft = val[0];
|
|
1388 el.scrollTop = val[1];
|
|
1389 } else {
|
|
1390 superclass.setAttribute.call(this, attr, val, unit);
|
|
1391 }
|
|
1392 };
|
|
1393
|
|
1394 Y.Scroll = Scroll;
|
|
1395 })();
|
|
1396 YAHOO.register("animation", YAHOO.util.Anim, {version: "2.8.0r4", build: "2449"});
|