Graph database Analysis of the Steam Network
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
7.3 KiB

  1. ;(function(undefined) {
  2. 'use strict';
  3. if (typeof sigma === 'undefined')
  4. throw 'sigma is not declared';
  5. // Initialize packages:
  6. sigma.utils.pkg('sigma.misc.animation.running');
  7. /**
  8. * Generates a unique ID for the animation.
  9. *
  10. * @return {string} Returns the new ID.
  11. */
  12. var _getID = (function() {
  13. var id = 0;
  14. return function() {
  15. return '' + (++id);
  16. };
  17. })();
  18. /**
  19. * This function animates a camera. It has to be called with the camera to
  20. * animate, the values of the coordinates to reach and eventually some
  21. * options. It returns a number id, that you can use to kill the animation,
  22. * with the method sigma.misc.animation.kill(id).
  23. *
  24. * The available options are:
  25. *
  26. * {?number} duration The duration of the animation.
  27. * {?function} onNewFrame A callback to execute when the animation
  28. * enter a new frame.
  29. * {?function} onComplete A callback to execute when the animation
  30. * is completed or killed.
  31. * {?(string|function)} easing The name of a function from the package
  32. * sigma.utils.easings, or a custom easing
  33. * function.
  34. *
  35. * @param {camera} camera The camera to animate.
  36. * @param {object} target The coordinates to reach.
  37. * @param {?object} options Eventually an object to specify some options to
  38. * the function. The available options are
  39. * presented in the description of the function.
  40. * @return {number} The animation id, to make it easy to kill
  41. * through the method "sigma.misc.animation.kill".
  42. */
  43. sigma.misc.animation.camera = function(camera, val, options) {
  44. if (
  45. !(camera instanceof sigma.classes.camera) ||
  46. typeof val !== 'object' ||
  47. !val
  48. )
  49. throw 'animation.camera: Wrong arguments.';
  50. if (
  51. typeof val.x !== 'number' &&
  52. typeof val.y !== 'number' &&
  53. typeof val.ratio !== 'number' &&
  54. typeof val.angle !== 'number'
  55. )
  56. throw 'There must be at least one valid coordinate in the given val.';
  57. var fn,
  58. id,
  59. anim,
  60. easing,
  61. duration,
  62. initialVal,
  63. o = options || {},
  64. start = sigma.utils.dateNow();
  65. // Store initial values:
  66. initialVal = {
  67. x: camera.x,
  68. y: camera.y,
  69. ratio: camera.ratio,
  70. angle: camera.angle
  71. };
  72. duration = o.duration;
  73. easing = typeof o.easing !== 'function' ?
  74. sigma.utils.easings[o.easing || 'quadraticInOut'] :
  75. o.easing;
  76. fn = function() {
  77. var coef,
  78. t = o.duration ? (sigma.utils.dateNow() - start) / o.duration : 1;
  79. // If the animation is over:
  80. if (t >= 1) {
  81. camera.isAnimated = false;
  82. camera.goTo({
  83. x: val.x !== undefined ? val.x : initialVal.x,
  84. y: val.y !== undefined ? val.y : initialVal.y,
  85. ratio: val.ratio !== undefined ? val.ratio : initialVal.ratio,
  86. angle: val.angle !== undefined ? val.angle : initialVal.angle
  87. });
  88. cancelAnimationFrame(id);
  89. delete sigma.misc.animation.running[id];
  90. // Check callbacks:
  91. if (typeof o.onComplete === 'function')
  92. o.onComplete();
  93. // Else, let's keep going:
  94. } else {
  95. coef = easing(t);
  96. camera.isAnimated = true;
  97. camera.goTo({
  98. x: val.x !== undefined ?
  99. initialVal.x + (val.x - initialVal.x) * coef :
  100. initialVal.x,
  101. y: val.y !== undefined ?
  102. initialVal.y + (val.y - initialVal.y) * coef :
  103. initialVal.y,
  104. ratio: val.ratio !== undefined ?
  105. initialVal.ratio + (val.ratio - initialVal.ratio) * coef :
  106. initialVal.ratio,
  107. angle: val.angle !== undefined ?
  108. initialVal.angle + (val.angle - initialVal.angle) * coef :
  109. initialVal.angle
  110. });
  111. // Check callbacks:
  112. if (typeof o.onNewFrame === 'function')
  113. o.onNewFrame();
  114. anim.frameId = requestAnimationFrame(fn);
  115. }
  116. };
  117. id = _getID();
  118. anim = {
  119. frameId: requestAnimationFrame(fn),
  120. target: camera,
  121. type: 'camera',
  122. options: o,
  123. fn: fn
  124. };
  125. sigma.misc.animation.running[id] = anim;
  126. return id;
  127. };
  128. /**
  129. * Kills a running animation. It triggers the eventual onComplete callback.
  130. *
  131. * @param {number} id The id of the animation to kill.
  132. * @return {object} Returns the sigma.misc.animation package.
  133. */
  134. sigma.misc.animation.kill = function(id) {
  135. if (arguments.length !== 1 || typeof id !== 'number')
  136. throw 'animation.kill: Wrong arguments.';
  137. var o = sigma.misc.animation.running[id];
  138. if (o) {
  139. cancelAnimationFrame(id);
  140. delete sigma.misc.animation.running[o.frameId];
  141. if (o.type === 'camera')
  142. o.target.isAnimated = false;
  143. // Check callbacks:
  144. if (typeof (o.options || {}).onComplete === 'function')
  145. o.options.onComplete();
  146. }
  147. return this;
  148. };
  149. /**
  150. * Kills every running animations, or only the one with the specified type,
  151. * if a string parameter is given.
  152. *
  153. * @param {?(string|object)} filter A string to filter the animations to kill
  154. * on their type (example: "camera"), or an
  155. * object to filter on their target.
  156. * @return {number} Returns the number of animations killed
  157. * that way.
  158. */
  159. sigma.misc.animation.killAll = function(filter) {
  160. var o,
  161. id,
  162. count = 0,
  163. type = typeof filter === 'string' ? filter : null,
  164. target = typeof filter === 'object' ? filter : null,
  165. running = sigma.misc.animation.running;
  166. for (id in running)
  167. if (
  168. (!type || running[id].type === type) &&
  169. (!target || running[id].target === target)
  170. ) {
  171. o = sigma.misc.animation.running[id];
  172. cancelAnimationFrame(o.frameId);
  173. delete sigma.misc.animation.running[id];
  174. if (o.type === 'camera')
  175. o.target.isAnimated = false;
  176. // Increment counter:
  177. count++;
  178. // Check callbacks:
  179. if (typeof (o.options || {}).onComplete === 'function')
  180. o.options.onComplete();
  181. }
  182. return count;
  183. };
  184. /**
  185. * Returns "true" if any animation that is currently still running matches
  186. * the filter given to the function.
  187. *
  188. * @param {string|object} filter A string to filter the animations to kill
  189. * on their type (example: "camera"), or an
  190. * object to filter on their target.
  191. * @return {boolean} Returns true if any running animation
  192. * matches.
  193. */
  194. sigma.misc.animation.has = function(filter) {
  195. var id,
  196. type = typeof filter === 'string' ? filter : null,
  197. target = typeof filter === 'object' ? filter : null,
  198. running = sigma.misc.animation.running;
  199. for (id in running)
  200. if (
  201. (!type || running[id].type === type) &&
  202. (!target || running[id].target === target)
  203. )
  204. return true;
  205. return false;
  206. };
  207. }).call(this);