manualtween.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. Tween = {};
  2. Tween.activeTweens = [];
  3. Tween.idCounter = 0;
  4. Tween.create = (obj, targetProperties, duration, easing, completedCallback) => {
  5. let singleTween = {};
  6. singleTween.id = ++Tween.idCounter;
  7. singleTween.obj = obj;
  8. singleTween.objStart = {};
  9. singleTween.objTarget = targetProperties;
  10. Tween.saveProperties(singleTween.objStart, obj, targetProperties);
  11. singleTween.startTime = new Date().getTime();
  12. singleTween.endTime = singleTween.startTime + duration;
  13. singleTween.easing = easing;
  14. singleTween.completedCallback = completedCallback;
  15. Tween.activeTweens.push(singleTween);
  16. return singleTween.id;
  17. };
  18. Tween.cancel = (tweenId) => {
  19. let tween = Tween.activeTweens.find(tween => tweenId == tween.id);
  20. if(tween) {
  21. let index = Tween.activeTweens.indexOf(tween);
  22. Tween.activeTweens.splice(index, 1);
  23. return tween;
  24. }
  25. };
  26. Tween.stop = (tweenId) => {
  27. let tween = Tween.cancel(tweenId);
  28. tween.completedCallback();
  29. return tween;
  30. };
  31. Tween.saveProperties = (singleTweenStart, obj, targetProperties) => {
  32. for(let property in targetProperties) {
  33. let startValue = obj[property];
  34. if(typeof startValue == "object") {
  35. singleTweenStart[property] = {};
  36. Tween.saveProperties(singleTweenStart[property], obj[property], targetProperties[property]);
  37. continue;
  38. }
  39. singleTweenStart[property] = startValue;
  40. }
  41. }
  42. Tween.update = () => {
  43. let completed = [];
  44. for (let i = 0; i < Tween.activeTweens.length; i++) {
  45. let singleTween = Tween.activeTweens[i];
  46. if(Tween.updateSingleTween(singleTween) == 1) {
  47. completed.push(singleTween);
  48. }
  49. }
  50. for (let i = 0; i < completed.length; i++) {
  51. let singleTween = completed[i];
  52. singleTween.completedCallback();
  53. let foundIndex = Tween.activeTweens.indexOf(singleTween);
  54. if(foundIndex != -1) {
  55. Tween.activeTweens.splice(foundIndex, 1);
  56. }
  57. }
  58. };
  59. Tween.updateSingleTween = (singleTween) => {
  60. let currentTime = new Date().getTime();
  61. let runTime = currentTime - singleTween.startTime;
  62. let duration = singleTween.endTime - singleTween.startTime;
  63. let percentageComplete = Math.min(1, runTime / duration);
  64. let valueToUpdate = singleTween.easing(percentageComplete);
  65. Tween.updateProperties(singleTween.obj, singleTween.objStart, singleTween.objTarget, valueToUpdate);
  66. return percentageComplete;
  67. }
  68. Tween.updateProperties =(obj, objStart, objTarget, valueToUpdate) => {
  69. for(let property in objStart) {
  70. let startValue = objStart[property];
  71. if(typeof startValue == "object") {
  72. Tween.updateProperties(obj[property], objStart[property], objTarget[property], valueToUpdate);
  73. continue;
  74. }
  75. let endValue = objTarget[property];
  76. let delta = endValue - startValue;
  77. obj[property] = startValue + (delta * valueToUpdate);
  78. }
  79. };
  80. Tween.Easing = {};
  81. Tween.Easing.Linear = {};
  82. Tween.Easing.Linear.EaseNone = (percentageComplete) => percentageComplete;
  83. Tween.Easing.Quadratic = {};
  84. Tween.Easing.Quadratic.EaseIn = (percentageComplete) => percentageComplete * percentageComplete;
  85. Tween.Easing.Quadratic.EaseOut = (percentageComplete) => -percentageComplete * ( percentageComplete - 2 );
  86. Tween.Easing.Quadratic.EaseInOut = (percentageComplete) => {
  87. if ( ( percentageComplete *= 2 ) < 1 ) return 0.5 * percentageComplete * percentageComplete;
  88. return - 0.5 * ( --percentageComplete * ( percentageComplete - 2 ) - 1 );
  89. };
  90. Tween.Easing.Cubic = {};
  91. Tween.Easing.Cubic.EaseIn = (percentageComplete) => percentageComplete * percentageComplete * percentageComplete;
  92. Tween.Easing.Cubic.EaseOut = (percentageComplete) => --percentageComplete * percentageComplete * percentageComplete + 1;
  93. Tween.Easing.Cubic.EaseInOut = (percentageComplete) => {
  94. if ( ( percentageComplete *= 2 ) < 1 ) return 0.5 * percentageComplete * percentageComplete * percentageComplete;
  95. return 0.5 * ( ( percentageComplete -= 2 ) * percentageComplete * percentageComplete + 2 );
  96. };
  97. Tween.Easing.Quartic = {};
  98. Tween.Easing.Quartic.EaseIn = (percentageComplete) => percentageComplete * percentageComplete * percentageComplete * percentageComplete;
  99. Tween.Easing.Quartic.EaseOut = (percentageComplete) => -( --percentageComplete * percentageComplete * percentageComplete * percentageComplete - 1 );
  100. Tween.Easing.Quartic.EaseInOut = (percentageComplete) => {
  101. if ( ( percentageComplete *= 2 ) < 1) return 0.5 * percentageComplete * percentageComplete * percentageComplete * percentageComplete;
  102. return - 0.5 * ( ( percentageComplete -= 2 ) * percentageComplete * percentageComplete * percentageComplete - 2 );
  103. };
  104. Tween.Easing.Quintic = {};
  105. Tween.Easing.Quintic.EaseIn = (percentageComplete) => percentageComplete * percentageComplete * percentageComplete * percentageComplete * percentageComplete;
  106. Tween.Easing.Quintic.EaseOut = (percentageComplete) => ( percentageComplete = percentageComplete - 1 ) * percentageComplete * percentageComplete * percentageComplete * percentageComplete + 1;
  107. Tween.Easing.Quintic.EaseInOut = (percentageComplete) => {
  108. if ( ( percentageComplete *= 2 ) < 1 ) return 0.5 * percentageComplete * percentageComplete * percentageComplete * percentageComplete * percentageComplete;
  109. return 0.5 * ( ( percentageComplete -= 2 ) * percentageComplete * percentageComplete * percentageComplete * percentageComplete + 2 );
  110. };
  111. Tween.Easing.Sinusoidal = {};
  112. Tween.Easing.Sinusoidal.EaseIn = (percentageComplete) => -Math.cos( percentageComplete * Math.PI / 2 ) + 1;
  113. Tween.Easing.Sinusoidal.EaseOut = (percentageComplete) => Math.sin( percentageComplete * Math.PI / 2 );
  114. Tween.Easing.Sinusoidal.EaseInOut = (percentageComplete) => -0.5 * ( Math.cos( Math.PI * percentageComplete ) - 1 );
  115. Tween.Easing.Exponential = {};
  116. Tween.Easing.Exponential.EaseIn = (percentageComplete) => {
  117. return percentageComplete == 0 ? 0 : Math.pow( 2, 10 * ( percentageComplete - 1 ) );
  118. };
  119. Tween.Easing.Exponential.EaseOut = (percentageComplete) => {
  120. return percentageComplete == 1 ? 1 : - Math.pow( 2, - 10 * percentageComplete ) + 1;
  121. };
  122. Tween.Easing.Exponential.EaseInOut = (percentageComplete) => {
  123. if ( percentageComplete == 0 ) return 0;
  124. if ( percentageComplete == 1 ) return 1;
  125. if ( ( percentageComplete *= 2 ) < 1 ) return 0.5 * Math.pow( 2, 10 * ( percentageComplete - 1 ) );
  126. return 0.5 * ( - Math.pow( 2, - 10 * ( percentageComplete - 1 ) ) + 2 );
  127. };
  128. Tween.Easing.Circular = {};
  129. Tween.Easing.Circular.EaseIn = (percentageComplete) => -(Math.sqrt( 1 - percentageComplete * percentageComplete ) - 1);
  130. Tween.Easing.Circular.EaseOut = (percentageComplete) => Math.sqrt( 1 - (--percentageComplete * percentageComplete) );
  131. Tween.Easing.Circular.EaseInOut = (percentageComplete) => {
  132. if ( ( percentageComplete /= 0.5 ) < 1) return - 0.5 * ( Math.sqrt( 1 - percentageComplete * percentageComplete) - 1);
  133. return 0.5 * ( Math.sqrt( 1 - ( percentageComplete -= 2) * percentageComplete) + 1);
  134. };
  135. Tween.Easing.Elastic = {};
  136. Tween.Easing.Elastic.EaseIn = (percentageComplete) => {
  137. var s, a = 0.1, p = 0.4;
  138. if ( percentageComplete == 0 ) return 0; if ( percentageComplete == 1 ) return 1; if ( !p ) p = 0.3;
  139. if ( !a || a < 1 ) { a = 1; s = p / 4; }
  140. else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
  141. return - ( a * Math.pow( 2, 10 * ( percentageComplete -= 1 ) ) * Math.sin( ( percentageComplete - s ) * ( 2 * Math.PI ) / p ) );
  142. };
  143. Tween.Easing.Elastic.EaseOut = (percentageComplete) => {
  144. var s, a = 0.1, p = 0.4;
  145. if ( percentageComplete == 0 ) return 0; if ( percentageComplete == 1 ) return 1; if ( !p ) p = 0.3;
  146. if ( !a || a < 1 ) { a = 1; s = p / 4; }
  147. else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
  148. return ( a * Math.pow( 2, - 10 * percentageComplete) * Math.sin( ( percentageComplete - s ) * ( 2 * Math.PI ) / p ) + 1 );
  149. };
  150. Tween.Easing.Elastic.EaseInOut = (percentageComplete) => {
  151. var s, a = 0.1, p = 0.4;
  152. if ( percentageComplete == 0 ) return 0; if ( percentageComplete == 1 ) return 1; if ( !p ) p = 0.3;
  153. if ( !a || a < 1 ) { a = 1; s = p / 4; }
  154. else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
  155. if ( ( percentageComplete *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( percentageComplete -= 1 ) ) * Math.sin( ( percentageComplete - s ) * ( 2 * Math.PI ) / p ) );
  156. return a * Math.pow( 2, -10 * ( percentageComplete -= 1 ) ) * Math.sin( ( percentageComplete - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
  157. };
  158. Tween.Easing.Back = {};
  159. Tween.Easing.Back.EaseIn = (percentageComplete) => {
  160. var s = 1.70158;
  161. return percentageComplete * percentageComplete * ( ( s + 1 ) * percentageComplete - s );
  162. };
  163. Tween.Easing.Back.EaseOut = (percentageComplete) => {
  164. var s = 1.70158;
  165. return ( percentageComplete = percentageComplete - 1 ) * percentageComplete * ( ( s + 1 ) * percentageComplete + s ) + 1;
  166. };
  167. Tween.Easing.Back.EaseInOut = (percentageComplete) => {
  168. var s = 1.70158 * 1.525;
  169. if ( ( percentageComplete *= 2 ) < 1 ) return 0.5 * ( percentageComplete * percentageComplete * ( ( s + 1 ) * percentageComplete - s ) );
  170. return 0.5 * ( ( percentageComplete -= 2 ) * percentageComplete * ( ( s + 1 ) * percentageComplete + s ) + 2 );
  171. };
  172. Tween.Easing.Bounce = {};
  173. Tween.Easing.Bounce.EaseIn = (percentageComplete) => 1 - Tween.Easing.Bounce.EaseOut( 1 - percentageComplete );
  174. Tween.Easing.Bounce.EaseOut = (percentageComplete) => {
  175. if ( ( percentageComplete /= 1 ) < ( 1 / 2.75 ) ) {
  176. return 7.5625 * percentageComplete * percentageComplete;
  177. } else if ( percentageComplete < ( 2 / 2.75 ) ) {
  178. return 7.5625 * ( percentageComplete -= ( 1.5 / 2.75 ) ) * percentageComplete + 0.75;
  179. } else if ( percentageComplete < ( 2.5 / 2.75 ) ) {
  180. return 7.5625 * ( percentageComplete -= ( 2.25 / 2.75 ) ) * percentageComplete + 0.9375;
  181. } else {
  182. return 7.5625 * ( percentageComplete -= ( 2.625 / 2.75 ) ) * percentageComplete + 0.984375;
  183. }
  184. };
  185. Tween.Easing.Bounce.EaseInOut = (percentageComplete) => {
  186. if ( percentageComplete < 0.5 ) return Tween.Easing.Bounce.EaseIn( percentageComplete * 2 ) * 0.5;
  187. return Tween.Easing.Bounce.EaseOut( percentageComplete * 2 - 1 ) * 0.5 + 0.5;
  188. };