/hippo/src/main/webapp/ext/src/adapter/core/ext-base-anim.js

http://hdbc.googlecode.com/ · JavaScript · 477 lines · 382 code · 82 blank · 13 comment · 63 complexity · a2699841f4e31b53af26e675e99ce4d5 MD5 · raw file

  1. /*!
  2. * Ext JS Library 3.0.0
  3. * Copyright(c) 2006-2009 Ext JS, LLC
  4. * licensing@extjs.com
  5. * http://www.extjs.com/license
  6. */
  7. (function(){
  8. var EXTLIB = Ext.lib,
  9. noNegatives = /width|height|opacity|padding/i,
  10. offsetAttribute = /^((width|height)|(top|left))$/,
  11. defaultUnit = /width|height|top$|bottom$|left$|right$/i,
  12. offsetUnit = /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i,
  13. isset = function(v){
  14. return typeof v !== 'undefined';
  15. },
  16. now = function(){
  17. return new Date();
  18. };
  19. EXTLIB.Anim = {
  20. motion : function(el, args, duration, easing, cb, scope) {
  21. return this.run(el, args, duration, easing, cb, scope, Ext.lib.Motion);
  22. },
  23. run : function(el, args, duration, easing, cb, scope, type) {
  24. type = type || Ext.lib.AnimBase;
  25. if (typeof easing == "string") {
  26. easing = Ext.lib.Easing[easing];
  27. }
  28. var anim = new type(el, args, duration, easing);
  29. anim.animateX(function() {
  30. if(Ext.isFunction(cb)){
  31. cb.call(scope);
  32. }
  33. });
  34. return anim;
  35. }
  36. };
  37. EXTLIB.AnimBase = function(el, attributes, duration, method) {
  38. if (el) {
  39. this.init(el, attributes, duration, method);
  40. }
  41. };
  42. EXTLIB.AnimBase.prototype = {
  43. doMethod: function(attr, start, end) {
  44. var me = this;
  45. return me.method(me.curFrame, start, end - start, me.totalFrames);
  46. },
  47. setAttr: function(attr, val, unit) {
  48. if (noNegatives.test(attr) && val < 0) {
  49. val = 0;
  50. }
  51. Ext.fly(this.el, '_anim').setStyle(attr, val + unit);
  52. },
  53. getAttr: function(attr) {
  54. var el = Ext.fly(this.el),
  55. val = el.getStyle(attr),
  56. a = offsetAttribute.exec(attr) || []
  57. if (val !== 'auto' && !offsetUnit.test(val)) {
  58. return parseFloat(val);
  59. }
  60. return (!!(a[2]) || (el.getStyle('position') == 'absolute' && !!(a[3]))) ? el.dom['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)] : 0;
  61. },
  62. getDefaultUnit: function(attr) {
  63. return defaultUnit.test(attr) ? 'px' : '';
  64. },
  65. animateX : function(callback, scope) {
  66. var me = this,
  67. f = function() {
  68. me.onComplete.removeListener(f);
  69. if (Ext.isFunction(callback)) {
  70. callback.call(scope || me, me);
  71. }
  72. };
  73. me.onComplete.addListener(f, me);
  74. me.animate();
  75. },
  76. setRunAttr: function(attr) {
  77. var me = this,
  78. a = this.attributes[attr],
  79. to = a.to,
  80. by = a.by,
  81. from = a.from,
  82. unit = a.unit,
  83. ra = (this.runAttrs[attr] = {}),
  84. end;
  85. if (!isset(to) && !isset(by)){
  86. return false;
  87. }
  88. var start = isset(from) ? from : me.getAttr(attr);
  89. if (isset(to)) {
  90. end = to;
  91. }else if(isset(by)) {
  92. if (Ext.isArray(start)){
  93. end = [];
  94. Ext.each(start, function(v, i){
  95. end[i] = v + by[i];
  96. });
  97. }else{
  98. end = start + by;
  99. }
  100. }
  101. Ext.apply(ra, {
  102. start: start,
  103. end: end,
  104. unit: isset(unit) ? unit : me.getDefaultUnit(attr)
  105. });
  106. },
  107. init: function(el, attributes, duration, method) {
  108. var me = this,
  109. actualFrames = 0,
  110. mgr = EXTLIB.AnimMgr;
  111. Ext.apply(me, {
  112. isAnimated: false,
  113. startTime: null,
  114. el: Ext.getDom(el),
  115. attributes: attributes || {},
  116. duration: duration || 1,
  117. method: method || EXTLIB.Easing.easeNone,
  118. useSec: true,
  119. curFrame: 0,
  120. totalFrames: mgr.fps,
  121. runAttrs: {},
  122. animate: function(){
  123. var me = this,
  124. d = me.duration;
  125. if(me.isAnimated){
  126. return false;
  127. }
  128. me.curFrame = 0;
  129. me.totalFrames = me.useSec ? Math.ceil(mgr.fps * d) : d;
  130. mgr.registerElement(me);
  131. },
  132. stop: function(finish){
  133. var me = this;
  134. if(finish){
  135. me.curFrame = me.totalFrames;
  136. me._onTween.fire();
  137. }
  138. mgr.stop(me);
  139. }
  140. });
  141. var onStart = function(){
  142. var me = this,
  143. attr;
  144. me.onStart.fire();
  145. me.runAttrs = {};
  146. for(attr in this.attributes){
  147. this.setRunAttr(attr);
  148. }
  149. me.isAnimated = true;
  150. me.startTime = now();
  151. actualFrames = 0;
  152. };
  153. var onTween = function(){
  154. var me = this;
  155. me.onTween.fire({
  156. duration: now() - me.startTime,
  157. curFrame: me.curFrame
  158. });
  159. var ra = me.runAttrs;
  160. for (var attr in ra) {
  161. this.setAttr(attr, me.doMethod(attr, ra[attr].start, ra[attr].end), ra[attr].unit);
  162. }
  163. ++actualFrames;
  164. };
  165. var onComplete = function() {
  166. var me = this,
  167. actual = (now() - me.startTime) / 1000,
  168. data = {
  169. duration: actual,
  170. frames: actualFrames,
  171. fps: actualFrames / actual
  172. };
  173. me.isAnimated = false;
  174. actualFrames = 0;
  175. me.onComplete.fire(data);
  176. };
  177. me.onStart = new Ext.util.Event(me);
  178. me.onTween = new Ext.util.Event(me);
  179. me.onComplete = new Ext.util.Event(me);
  180. (me._onStart = new Ext.util.Event(me)).addListener(onStart);
  181. (me._onTween = new Ext.util.Event(me)).addListener(onTween);
  182. (me._onComplete = new Ext.util.Event(me)).addListener(onComplete);
  183. }
  184. };
  185. Ext.lib.AnimMgr = new function() {
  186. var me = this,
  187. thread = null,
  188. queue = [],
  189. tweenCount = 0;
  190. Ext.apply(me, {
  191. fps: 1000,
  192. delay: 1,
  193. registerElement: function(tween){
  194. queue.push(tween);
  195. ++tweenCount;
  196. tween._onStart.fire();
  197. me.start();
  198. },
  199. unRegister: function(tween, index){
  200. tween._onComplete.fire();
  201. index = index || getIndex(tween);
  202. if (index != -1) {
  203. queue.splice(index, 1);
  204. }
  205. if (--tweenCount <= 0) {
  206. me.stop();
  207. }
  208. },
  209. start: function(){
  210. if(thread === null){
  211. thread = setInterval(me.run, me.delay);
  212. }
  213. },
  214. stop: function(tween){
  215. if(!tween){
  216. clearInterval(thread);
  217. for(var i = 0, len = queue.length; i < len; ++i){
  218. if(queue[0].isAnimated){
  219. me.unRegister(queue[0], 0);
  220. }
  221. }
  222. queue = [];
  223. thread = null;
  224. tweenCount = 0;
  225. }else{
  226. me.unRegister(tween);
  227. }
  228. },
  229. run: function(){
  230. var tf;
  231. Ext.each(queue, function(tween){
  232. if(tween && tween.isAnimated){
  233. tf = tween.totalFrames;
  234. if(tween.curFrame < tf || tf === null){
  235. ++tween.curFrame;
  236. if(tween.useSec){
  237. correctFrame(tween);
  238. }
  239. tween._onTween.fire();
  240. }else{
  241. me.stop(tween);
  242. }
  243. }
  244. }, me);
  245. }
  246. });
  247. var getIndex = function(anim) {
  248. var out = -1;
  249. Ext.each(queue, function(item, idx){
  250. if(item == anim){
  251. out = idx;
  252. return false;
  253. }
  254. });
  255. return out;
  256. };
  257. var correctFrame = function(tween) {
  258. var frames = tween.totalFrames,
  259. frame = tween.curFrame,
  260. duration = tween.duration,
  261. expected = (frame * duration * 1000 / frames),
  262. elapsed = (now() - tween.startTime),
  263. tweak = 0;
  264. if(elapsed < duration * 1000){
  265. tweak = Math.round((elapsed / expected - 1) * frame);
  266. }else{
  267. tweak = frames - (frame + 1);
  268. }
  269. if(tweak > 0 && isFinite(tweak)){
  270. if(tween.curFrame + tweak >= frames){
  271. tweak = frames - (frame + 1);
  272. }
  273. tween.curFrame += tweak;
  274. }
  275. };
  276. };
  277. EXTLIB.Bezier = new function() {
  278. this.getPosition = function(points, t) {
  279. var n = points.length,
  280. tmp = [],
  281. c = 1 - t,
  282. i,
  283. j;
  284. for (i = 0; i < n; ++i) {
  285. tmp[i] = [points[i][0], points[i][1]];
  286. }
  287. for (j = 1; j < n; ++j) {
  288. for (i = 0; i < n - j; ++i) {
  289. tmp[i][0] = c * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
  290. tmp[i][1] = c * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
  291. }
  292. }
  293. return [ tmp[0][0], tmp[0][1] ];
  294. };
  295. };
  296. EXTLIB.Easing = {
  297. easeNone: function (t, b, c, d) {
  298. return c * t / d + b;
  299. },
  300. easeIn: function (t, b, c, d) {
  301. return c * (t /= d) * t + b;
  302. },
  303. easeOut: function (t, b, c, d) {
  304. return -c * (t /= d) * (t - 2) + b;
  305. }
  306. };
  307. (function() {
  308. EXTLIB.Motion = function(el, attributes, duration, method) {
  309. if (el) {
  310. EXTLIB.Motion.superclass.constructor.call(this, el, attributes, duration, method);
  311. }
  312. };
  313. Ext.extend(EXTLIB.Motion, Ext.lib.AnimBase);
  314. var superclass = EXTLIB.Motion.superclass,
  315. proto = EXTLIB.Motion.prototype,
  316. pointsRe = /^points$/i;
  317. Ext.apply(EXTLIB.Motion.prototype, {
  318. setAttr: function(attr, val, unit){
  319. var me = this,
  320. setAttr = superclass.setAttr;
  321. if (pointsRe.test(attr)) {
  322. unit = unit || 'px';
  323. setAttr.call(me, 'left', val[0], unit);
  324. setAttr.call(me, 'top', val[1], unit);
  325. } else {
  326. setAttr.call(me, attr, val, unit);
  327. }
  328. },
  329. getAttr: function(attr){
  330. var me = this,
  331. getAttr = superclass.getAttr;
  332. return pointsRe.test(attr) ? [getAttr.call(me, 'left'), getAttr.call(me, 'top')] : getAttr.call(me, attr);
  333. },
  334. doMethod: function(attr, start, end){
  335. var me = this;
  336. return pointsRe.test(attr)
  337. ? EXTLIB.Bezier.getPosition(me.runAttrs[attr], me.method(me.curFrame, 0, 100, me.totalFrames) / 100)
  338. : superclass.doMethod.call(me, attr, start, end);
  339. },
  340. setRunAttr: function(attr){
  341. if(pointsRe.test(attr)){
  342. var me = this,
  343. el = this.el,
  344. points = this.attributes.points,
  345. control = points.control || [],
  346. from = points.from,
  347. to = points.to,
  348. by = points.by,
  349. DOM = EXTLIB.Dom,
  350. start,
  351. i,
  352. end,
  353. len,
  354. ra;
  355. if(control.length > 0 && !Ext.isArray(control[0])){
  356. control = [control];
  357. }else{
  358. /*
  359. var tmp = [];
  360. for (i = 0,len = control.length; i < len; ++i) {
  361. tmp[i] = control[i];
  362. }
  363. control = tmp;
  364. */
  365. }
  366. Ext.fly(el, '_anim').position();
  367. DOM.setXY(el, isset(from) ? from : DOM.getXY(el));
  368. start = me.getAttr('points');
  369. if(isset(to)){
  370. end = translateValues.call(me, to, start);
  371. for (i = 0,len = control.length; i < len; ++i) {
  372. control[i] = translateValues.call(me, control[i], start);
  373. }
  374. } else if (isset(by)) {
  375. end = [start[0] + by[0], start[1] + by[1]];
  376. for (i = 0,len = control.length; i < len; ++i) {
  377. control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
  378. }
  379. }
  380. ra = this.runAttrs[attr] = [start];
  381. if (control.length > 0) {
  382. ra = ra.concat(control);
  383. }
  384. ra[ra.length] = end;
  385. }else{
  386. superclass.setRunAttr.call(this, attr);
  387. }
  388. }
  389. });
  390. var translateValues = function(val, start) {
  391. var pageXY = EXTLIB.Dom.getXY(this.el);
  392. return [val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1]];
  393. };
  394. })();
  395. })();