utils.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { __assign, __read } from "tslib";
  2. /* global Keyframe */
  3. import { isNil } from '@antv/util';
  4. import { show, hide } from '../util';
  5. function isStandardAnimationOption(option) {
  6. if (typeof option === 'boolean')
  7. return false;
  8. return 'enter' in option && 'update' in option && 'exit' in option;
  9. }
  10. export function parseAnimationOption(option) {
  11. // option is false => all animation is false
  12. // option is { enter: {}, update: {}, exit: {}, ...baseOption } =>
  13. // { enter: { ...enter, ...baseOption }, update: { ...update, ...baseOption }, exit: { ...exit, ...baseOption } }
  14. // option is { enter: {}, update: {}, exit: {} } => option
  15. if (!option)
  16. return { enter: false, update: false, exit: false };
  17. var keys = ['enter', 'update', 'exit'];
  18. var baseOption = Object.fromEntries(Object.entries(option).filter(function (_a) {
  19. var _b = __read(_a, 1), k = _b[0];
  20. return !keys.includes(k);
  21. }));
  22. return Object.fromEntries(keys.map(function (k) {
  23. if (isStandardAnimationOption(option)) {
  24. if (option[k] === false)
  25. return [k, false];
  26. return [k, __assign(__assign({}, option[k]), baseOption)];
  27. }
  28. return [k, baseOption];
  29. }));
  30. }
  31. export function onAnimateFinished(animation, callback) {
  32. if (!animation)
  33. callback();
  34. else
  35. animation.finished.then(callback);
  36. }
  37. export function onAnimatesFinished(animations, callback) {
  38. if (animations.length === 0)
  39. callback();
  40. else
  41. Promise.all(animations.map(function (a) { return a === null || a === void 0 ? void 0 : a.finished; })).then(callback);
  42. }
  43. function attr(target, value) {
  44. if ('update' in target)
  45. target.update(value);
  46. else
  47. target.attr(value);
  48. }
  49. export function animate(target, keyframes, options) {
  50. if (keyframes.length === 0)
  51. return null;
  52. if (!options) {
  53. var state = keyframes.slice(-1)[0];
  54. attr(target, { style: state });
  55. return null;
  56. }
  57. return target.animate(keyframes, options);
  58. }
  59. /**
  60. * transition source shape to target shape
  61. * @param source
  62. * @param target
  63. * @param options
  64. * @param after destroy or hide source shape after transition
  65. */
  66. export function transitionShape(source, target, options, after) {
  67. if (after === void 0) { after = 'destroy'; }
  68. var afterTransition = function () {
  69. if (after === 'destroy')
  70. source.destroy();
  71. else if (after === 'hide')
  72. hide(source);
  73. if (target.isVisible())
  74. show(target);
  75. };
  76. if (!options) {
  77. afterTransition();
  78. return [null];
  79. }
  80. var _a = options.duration, duration = _a === void 0 ? 0 : _a, _b = options.delay, delay = _b === void 0 ? 0 : _b;
  81. var middle = Math.ceil(+duration / 2);
  82. var offset = +duration / 4;
  83. var getPosition = function (shape) {
  84. if (shape.nodeName === 'circle') {
  85. var _a = __read(shape.getLocalPosition(), 2), cx = _a[0], cy = _a[1];
  86. var r = shape.attr('r');
  87. return [cx - r, cy - r];
  88. }
  89. return shape.getLocalPosition();
  90. };
  91. var _c = __read(getPosition(source), 2), sx = _c[0], sy = _c[1];
  92. var _d = __read(getPosition(target), 2), ex = _d[0], ey = _d[1];
  93. var _e = __read([(sx + ex) / 2 - sx, (sy + ey) / 2 - sy], 2), mx = _e[0], my = _e[1];
  94. var sourceAnimation = source.animate([
  95. { opacity: 1, transform: 'translate(0, 0)' },
  96. { opacity: 0, transform: "translate(".concat(mx, ", ").concat(my, ")") },
  97. ], __assign(__assign({ fill: 'both' }, options), { duration: delay + middle + offset }));
  98. var targetAnimation = target.animate([
  99. { opacity: 0, transform: "translate(".concat(-mx, ", ").concat(-my, ")"), offset: 0.01 },
  100. { opacity: 1, transform: 'translate(0, 0)' },
  101. ], __assign(__assign({ fill: 'both' }, options), { duration: middle + offset, delay: delay + middle - offset }));
  102. onAnimateFinished(targetAnimation, afterTransition);
  103. return [sourceAnimation, targetAnimation];
  104. }
  105. /**
  106. * execute transition animation on element
  107. * @description in the current stage, only support the following properties:
  108. * x, y, width, height, opacity, fill, stroke, lineWidth, radius
  109. * @param target element to be animated
  110. * @param state target properties or element
  111. * @param options transition options
  112. * @param animate whether to animate
  113. * @returns transition instance
  114. */
  115. export function transition(target, state, options) {
  116. var from = {};
  117. var to = {};
  118. Object.entries(state).forEach(function (_a) {
  119. var _b = __read(_a, 2), key = _b[0], tarStyle = _b[1];
  120. if (!isNil(tarStyle)) {
  121. // 关闭 CSS 解析后,attr / getAttribute 只能获取到用户显式传入的属性,此时可以
  122. // 获取解析值,如果仍获取不到(例如 x/y),则使用 0 作为默认值
  123. var currStyle = target.style[key] || target.parsedStyle[key] || 0; // x/y
  124. if (currStyle !== tarStyle) {
  125. from[key] = currStyle;
  126. to[key] = tarStyle;
  127. }
  128. }
  129. });
  130. if (!options) {
  131. attr(target, to);
  132. return null;
  133. }
  134. return animate(target, [from, to], __assign({ fill: 'both' }, options));
  135. }
  136. //# sourceMappingURL=utils.js.map