animation.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import { ObjectExt, Timing, Interp } from '@antv/x6-common';
  2. export class Animation {
  3. constructor(cell) {
  4. this.cell = cell;
  5. this.ids = {};
  6. this.cache = {};
  7. }
  8. get() {
  9. return Object.keys(this.ids);
  10. }
  11. start(path, targetValue, options = {}, delim = '/') {
  12. const startValue = this.cell.getPropByPath(path);
  13. const localOptions = ObjectExt.defaults(options, Animation.defaultOptions);
  14. const timing = this.getTiming(localOptions.timing);
  15. const interpolate = this.getInterp(localOptions.interp, startValue, targetValue);
  16. let startTime = 0;
  17. const key = Array.isArray(path) ? path.join(delim) : path;
  18. const paths = Array.isArray(path) ? path : path.split(delim);
  19. const iterate = () => {
  20. const now = new Date().getTime();
  21. if (startTime === 0) {
  22. startTime = now;
  23. }
  24. const elaspe = now - startTime;
  25. let progress = elaspe / localOptions.duration;
  26. if (progress < 1) {
  27. this.ids[key] = requestAnimationFrame(iterate);
  28. }
  29. else {
  30. progress = 1;
  31. }
  32. const currentValue = interpolate(timing(progress));
  33. this.cell.setPropByPath(paths, currentValue);
  34. if (options.progress) {
  35. options.progress(Object.assign({ progress, currentValue }, this.getArgs(key)));
  36. }
  37. if (progress === 1) {
  38. this.cell.notify('transition:complete', this.getArgs(key));
  39. options.complete && options.complete(this.getArgs(key));
  40. this.cell.notify('transition:finish', this.getArgs(key));
  41. options.finish && options.finish(this.getArgs(key));
  42. this.clean(key);
  43. }
  44. };
  45. setTimeout(() => {
  46. this.stop(path, undefined, delim);
  47. this.cache[key] = { startValue, targetValue, options: localOptions };
  48. this.ids[key] = requestAnimationFrame(iterate);
  49. this.cell.notify('transition:start', this.getArgs(key));
  50. options.start && options.start(this.getArgs(key));
  51. }, options.delay);
  52. return this.stop.bind(this, path, delim, options);
  53. }
  54. stop(path, options = {}, delim = '/') {
  55. const paths = Array.isArray(path) ? path : path.split(delim);
  56. Object.keys(this.ids)
  57. .filter((key) => ObjectExt.isEqual(paths, key.split(delim).slice(0, paths.length)))
  58. .forEach((key) => {
  59. cancelAnimationFrame(this.ids[key]);
  60. const data = this.cache[key];
  61. const commonArgs = this.getArgs(key);
  62. const localOptions = Object.assign(Object.assign({}, data.options), options);
  63. const jumpedToEnd = localOptions.jumpedToEnd;
  64. if (jumpedToEnd && data.targetValue != null) {
  65. this.cell.setPropByPath(key, data.targetValue);
  66. this.cell.notify('transition:end', Object.assign({}, commonArgs));
  67. this.cell.notify('transition:complete', Object.assign({}, commonArgs));
  68. localOptions.complete && localOptions.complete(Object.assign({}, commonArgs));
  69. }
  70. const stopArgs = Object.assign({ jumpedToEnd }, commonArgs);
  71. this.cell.notify('transition:stop', Object.assign({}, stopArgs));
  72. localOptions.stop && localOptions.stop(Object.assign({}, stopArgs));
  73. this.cell.notify('transition:finish', Object.assign({}, commonArgs));
  74. localOptions.finish && localOptions.finish(Object.assign({}, commonArgs));
  75. this.clean(key);
  76. });
  77. return this;
  78. }
  79. clean(key) {
  80. delete this.ids[key];
  81. delete this.cache[key];
  82. }
  83. getTiming(timing) {
  84. return typeof timing === 'string' ? Timing[timing] : timing;
  85. }
  86. getInterp(interp, startValue, targetValue) {
  87. if (interp) {
  88. return interp(startValue, targetValue);
  89. }
  90. if (typeof targetValue === 'number') {
  91. return Interp.number(startValue, targetValue);
  92. }
  93. if (typeof targetValue === 'string') {
  94. if (targetValue[0] === '#') {
  95. return Interp.color(startValue, targetValue);
  96. }
  97. return Interp.unit(startValue, targetValue);
  98. }
  99. return Interp.object(startValue, targetValue);
  100. }
  101. getArgs(key) {
  102. const data = this.cache[key];
  103. return {
  104. path: key,
  105. startValue: data.startValue,
  106. targetValue: data.targetValue,
  107. cell: this.cell,
  108. };
  109. }
  110. }
  111. (function (Animation) {
  112. Animation.defaultOptions = {
  113. delay: 10,
  114. duration: 100,
  115. timing: 'linear',
  116. };
  117. })(Animation || (Animation = {}));
  118. //# sourceMappingURL=animation.js.map