animation-debug.js 47 KB

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