25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

178 satır
2.9 KiB

  1. /**
  2. * Module dependencies.
  3. */
  4. var Emitter = require('emitter');
  5. var clone = require('clone');
  6. var type = require('type');
  7. var ease = require('ease');
  8. /**
  9. * Expose `Tween`.
  10. */
  11. module.exports = Tween;
  12. /**
  13. * Initialize a new `Tween` with `obj`.
  14. *
  15. * @param {Object|Array} obj
  16. * @api public
  17. */
  18. function Tween(obj) {
  19. if (!(this instanceof Tween)) return new Tween(obj);
  20. this._from = obj;
  21. this.ease('linear');
  22. this.duration(500);
  23. }
  24. /**
  25. * Mixin emitter.
  26. */
  27. Emitter(Tween.prototype);
  28. /**
  29. * Reset the tween.
  30. *
  31. * @api public
  32. */
  33. Tween.prototype.reset = function(){
  34. this.isArray = 'array' === type(this._from);
  35. this._curr = clone(this._from);
  36. this._done = false;
  37. this._start = Date.now();
  38. return this;
  39. };
  40. /**
  41. * Tween to `obj` and reset internal state.
  42. *
  43. * tween.to({ x: 50, y: 100 })
  44. *
  45. * @param {Object|Array} obj
  46. * @return {Tween} self
  47. * @api public
  48. */
  49. Tween.prototype.to = function(obj){
  50. this.reset();
  51. this._to = obj;
  52. return this;
  53. };
  54. /**
  55. * Set duration to `ms` [500].
  56. *
  57. * @param {Number} ms
  58. * @return {Tween} self
  59. * @api public
  60. */
  61. Tween.prototype.duration = function(ms){
  62. this._duration = ms;
  63. return this;
  64. };
  65. /**
  66. * Set easing function to `fn`.
  67. *
  68. * tween.ease('in-out-sine')
  69. *
  70. * @param {String|Function} fn
  71. * @return {Tween}
  72. * @api public
  73. */
  74. Tween.prototype.ease = function(fn){
  75. fn = 'function' == typeof fn ? fn : ease[fn];
  76. if (!fn) throw new TypeError('invalid easing function');
  77. this._ease = fn;
  78. return this;
  79. };
  80. /**
  81. * Stop the tween and immediately emit "stop" and "end".
  82. *
  83. * @return {Tween}
  84. * @api public
  85. */
  86. Tween.prototype.stop = function(){
  87. this.stopped = true;
  88. this._done = true;
  89. this.emit('stop');
  90. this.emit('end');
  91. return this;
  92. };
  93. /**
  94. * Perform a step.
  95. *
  96. * @return {Tween} self
  97. * @api private
  98. */
  99. Tween.prototype.step = function(){
  100. if (this._done) return;
  101. // duration
  102. var duration = this._duration;
  103. var now = Date.now();
  104. var delta = now - this._start;
  105. var done = delta >= duration;
  106. // complete
  107. if (done) {
  108. this._from = this._to;
  109. this._update(this._to);
  110. this._done = true;
  111. this.emit('end');
  112. return this;
  113. }
  114. // tween
  115. var from = this._from;
  116. var to = this._to;
  117. var curr = this._curr;
  118. var fn = this._ease;
  119. var p = (now - this._start) / duration;
  120. var n = fn(p);
  121. // array
  122. if (this.isArray) {
  123. for (var i = 0; i < from.length; ++i) {
  124. curr[i] = from[i] + (to[i] - from[i]) * n;
  125. }
  126. this._update(curr);
  127. return this;
  128. }
  129. // objech
  130. for (var k in from) {
  131. curr[k] = from[k] + (to[k] - from[k]) * n;
  132. }
  133. this._update(curr);
  134. return this;
  135. };
  136. /**
  137. * Set update function to `fn` or
  138. * when no argument is given this performs
  139. * a "step".
  140. *
  141. * @param {Function} fn
  142. * @return {Tween} self
  143. * @api public
  144. */
  145. Tween.prototype.update = function(fn){
  146. if (0 == arguments.length) return this.step();
  147. this._update = fn;
  148. return this;
  149. };