@antv/infographic 0.2.12 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/dist/infographic.min.js +136 -125
  2. package/dist/infographic.min.js.map +1 -1
  3. package/esm/designs/structures/chart-pie.d.ts +25 -0
  4. package/esm/designs/structures/chart-pie.js +182 -23
  5. package/esm/designs/utils/index.d.ts +1 -0
  6. package/esm/designs/utils/index.js +1 -0
  7. package/esm/designs/utils/normalize-percent.d.ts +19 -0
  8. package/esm/designs/utils/normalize-percent.js +32 -0
  9. package/esm/editor/commands/UpdateOptions.d.ts +4 -4
  10. package/esm/editor/commands/UpdateOptions.js +6 -3
  11. package/esm/editor/editor.d.ts +5 -1
  12. package/esm/editor/editor.js +16 -5
  13. package/esm/editor/index.d.ts +1 -0
  14. package/esm/editor/index.js +1 -0
  15. package/esm/editor/interactions/brush-select.d.ts +0 -1
  16. package/esm/editor/interactions/brush-select.js +2 -10
  17. package/esm/editor/interactions/drag-canvas.d.ts +35 -0
  18. package/esm/editor/interactions/drag-canvas.js +161 -0
  19. package/esm/editor/interactions/drag-element.js +4 -3
  20. package/esm/editor/interactions/index.d.ts +1 -0
  21. package/esm/editor/interactions/index.js +1 -0
  22. package/esm/editor/interactions/zoom-wheel.d.ts +12 -0
  23. package/esm/editor/interactions/zoom-wheel.js +67 -27
  24. package/esm/editor/managers/index.d.ts +1 -0
  25. package/esm/editor/managers/index.js +1 -0
  26. package/esm/editor/managers/state.d.ts +4 -2
  27. package/esm/editor/managers/state.js +14 -7
  28. package/esm/editor/managers/sync-registry.d.ts +15 -0
  29. package/esm/editor/managers/sync-registry.js +51 -0
  30. package/esm/editor/plugins/{edit-bar/components → components}/button.js +1 -1
  31. package/esm/editor/plugins/{edit-bar/components → components}/color-picker.js +1 -1
  32. package/esm/editor/plugins/{edit-bar/components → components}/icons.d.ts +1 -0
  33. package/esm/editor/plugins/{edit-bar/components → components}/icons.js +1 -0
  34. package/esm/editor/plugins/{edit-bar/components → components}/popover.js +2 -2
  35. package/esm/editor/plugins/{edit-bar/components → components}/select.js +1 -1
  36. package/esm/editor/plugins/core-sync.d.ts +8 -0
  37. package/esm/editor/plugins/core-sync.js +30 -0
  38. package/esm/editor/plugins/edit-bar/edit-items/align-elements.js +1 -1
  39. package/esm/editor/plugins/edit-bar/edit-items/font-align.js +1 -1
  40. package/esm/editor/plugins/edit-bar/edit-items/font-color.js +1 -1
  41. package/esm/editor/plugins/edit-bar/edit-items/font-family.js +1 -1
  42. package/esm/editor/plugins/edit-bar/edit-items/font-size.js +1 -1
  43. package/esm/editor/plugins/edit-bar/edit-items/icon-color.js +1 -1
  44. package/esm/editor/plugins/edit-bar/index.d.ts +2 -2
  45. package/esm/editor/plugins/edit-bar/index.js +1 -1
  46. package/esm/editor/plugins/index.d.ts +2 -0
  47. package/esm/editor/plugins/index.js +2 -0
  48. package/esm/editor/plugins/reset-viewbox.d.ts +33 -0
  49. package/esm/editor/plugins/reset-viewbox.js +186 -0
  50. package/esm/editor/types/editor.d.ts +13 -0
  51. package/esm/editor/types/index.d.ts +1 -0
  52. package/esm/editor/types/interaction.d.ts +9 -0
  53. package/esm/editor/types/state.d.ts +4 -2
  54. package/esm/editor/types/sync.d.ts +26 -0
  55. package/esm/editor/types/sync.js +1 -0
  56. package/esm/editor/utils/data.js +3 -1
  57. package/esm/editor/utils/event.d.ts +1 -0
  58. package/esm/editor/utils/event.js +8 -0
  59. package/esm/editor/utils/index.d.ts +1 -0
  60. package/esm/editor/utils/index.js +1 -0
  61. package/esm/editor/utils/object.d.ts +15 -0
  62. package/esm/editor/utils/object.js +70 -0
  63. package/esm/index.d.ts +4 -3
  64. package/esm/index.js +3 -2
  65. package/esm/options/types.d.ts +1 -0
  66. package/esm/runtime/options.js +7 -2
  67. package/esm/templates/built-in.js +27 -77
  68. package/esm/templates/chart-pie.d.ts +2 -0
  69. package/esm/templates/chart-pie.js +87 -0
  70. package/esm/utils/measure-text.js +9 -6
  71. package/esm/utils/padding.d.ts +1 -0
  72. package/esm/utils/padding.js +6 -2
  73. package/esm/utils/viewbox.d.ts +20 -0
  74. package/esm/utils/viewbox.js +10 -0
  75. package/esm/version.d.ts +1 -1
  76. package/esm/version.js +1 -1
  77. package/lib/designs/structures/chart-pie.d.ts +25 -0
  78. package/lib/designs/structures/chart-pie.js +182 -22
  79. package/lib/designs/utils/index.d.ts +1 -0
  80. package/lib/designs/utils/index.js +1 -0
  81. package/lib/designs/utils/normalize-percent.d.ts +19 -0
  82. package/lib/designs/utils/normalize-percent.js +35 -0
  83. package/lib/editor/commands/UpdateOptions.d.ts +4 -4
  84. package/lib/editor/commands/UpdateOptions.js +6 -3
  85. package/lib/editor/editor.d.ts +5 -1
  86. package/lib/editor/editor.js +16 -5
  87. package/lib/editor/index.d.ts +1 -0
  88. package/lib/editor/index.js +1 -0
  89. package/lib/editor/interactions/brush-select.d.ts +0 -1
  90. package/lib/editor/interactions/brush-select.js +1 -9
  91. package/lib/editor/interactions/drag-canvas.d.ts +35 -0
  92. package/lib/editor/interactions/drag-canvas.js +165 -0
  93. package/lib/editor/interactions/drag-element.js +4 -3
  94. package/lib/editor/interactions/index.d.ts +1 -0
  95. package/lib/editor/interactions/index.js +3 -1
  96. package/lib/editor/interactions/zoom-wheel.d.ts +12 -0
  97. package/lib/editor/interactions/zoom-wheel.js +66 -26
  98. package/lib/editor/managers/index.d.ts +1 -0
  99. package/lib/editor/managers/index.js +1 -0
  100. package/lib/editor/managers/state.d.ts +4 -2
  101. package/lib/editor/managers/state.js +12 -5
  102. package/lib/editor/managers/sync-registry.d.ts +15 -0
  103. package/lib/editor/managers/sync-registry.js +55 -0
  104. package/lib/editor/plugins/{edit-bar/components → components}/button.js +1 -1
  105. package/lib/editor/plugins/{edit-bar/components → components}/color-picker.js +1 -1
  106. package/lib/editor/plugins/{edit-bar/components → components}/icons.d.ts +1 -0
  107. package/lib/editor/plugins/{edit-bar/components → components}/icons.js +2 -1
  108. package/lib/editor/plugins/{edit-bar/components → components}/popover.js +2 -2
  109. package/lib/editor/plugins/{edit-bar/components → components}/select.js +1 -1
  110. package/lib/editor/plugins/core-sync.d.ts +8 -0
  111. package/lib/editor/plugins/core-sync.js +34 -0
  112. package/lib/editor/plugins/edit-bar/edit-items/align-elements.js +1 -1
  113. package/lib/editor/plugins/edit-bar/edit-items/font-align.js +1 -1
  114. package/lib/editor/plugins/edit-bar/edit-items/font-color.js +1 -1
  115. package/lib/editor/plugins/edit-bar/edit-items/font-family.js +1 -1
  116. package/lib/editor/plugins/edit-bar/edit-items/font-size.js +1 -1
  117. package/lib/editor/plugins/edit-bar/edit-items/icon-color.js +1 -1
  118. package/lib/editor/plugins/edit-bar/index.d.ts +2 -2
  119. package/lib/editor/plugins/edit-bar/index.js +1 -1
  120. package/lib/editor/plugins/index.d.ts +2 -0
  121. package/lib/editor/plugins/index.js +5 -1
  122. package/lib/editor/plugins/reset-viewbox.d.ts +33 -0
  123. package/lib/editor/plugins/reset-viewbox.js +190 -0
  124. package/lib/editor/types/editor.d.ts +13 -0
  125. package/lib/editor/types/index.d.ts +1 -0
  126. package/lib/editor/types/interaction.d.ts +9 -0
  127. package/lib/editor/types/state.d.ts +4 -2
  128. package/lib/editor/types/sync.d.ts +26 -0
  129. package/lib/editor/types/sync.js +2 -0
  130. package/lib/editor/utils/data.js +3 -1
  131. package/lib/editor/utils/event.d.ts +1 -0
  132. package/lib/editor/utils/event.js +9 -0
  133. package/lib/editor/utils/index.d.ts +1 -0
  134. package/lib/editor/utils/index.js +1 -0
  135. package/lib/editor/utils/object.d.ts +15 -0
  136. package/lib/editor/utils/object.js +73 -0
  137. package/lib/index.d.ts +4 -3
  138. package/lib/index.js +9 -2
  139. package/lib/options/types.d.ts +1 -0
  140. package/lib/runtime/options.js +6 -1
  141. package/lib/templates/built-in.js +27 -77
  142. package/lib/templates/chart-pie.d.ts +2 -0
  143. package/lib/templates/chart-pie.js +90 -0
  144. package/lib/utils/measure-text.js +9 -6
  145. package/lib/utils/padding.d.ts +1 -0
  146. package/lib/utils/padding.js +7 -2
  147. package/lib/utils/viewbox.d.ts +20 -0
  148. package/lib/utils/viewbox.js +12 -0
  149. package/lib/version.d.ts +1 -1
  150. package/lib/version.js +1 -1
  151. package/package.json +1 -2
  152. package/src/designs/structures/chart-pie.tsx +259 -26
  153. package/src/designs/utils/index.ts +1 -0
  154. package/src/designs/utils/normalize-percent.ts +33 -0
  155. package/src/editor/commands/UpdateOptions.ts +11 -6
  156. package/src/editor/editor.ts +26 -5
  157. package/src/editor/index.ts +1 -0
  158. package/src/editor/interactions/brush-select.ts +2 -8
  159. package/src/editor/interactions/drag-canvas.ts +203 -0
  160. package/src/editor/interactions/drag-element.ts +5 -4
  161. package/src/editor/interactions/index.ts +1 -0
  162. package/src/editor/interactions/zoom-wheel.ts +102 -24
  163. package/src/editor/managers/index.ts +1 -0
  164. package/src/editor/managers/state.ts +21 -16
  165. package/src/editor/managers/sync-registry.ts +65 -0
  166. package/src/editor/plugins/{edit-bar/components → components}/button.ts +1 -1
  167. package/src/editor/plugins/{edit-bar/components → components}/color-picker.ts +1 -1
  168. package/src/editor/plugins/{edit-bar/components → components}/icons.ts +4 -0
  169. package/src/editor/plugins/{edit-bar/components → components}/popover.ts +2 -2
  170. package/src/editor/plugins/{edit-bar/components → components}/select.ts +1 -1
  171. package/src/editor/plugins/core-sync.ts +44 -0
  172. package/src/editor/plugins/edit-bar/edit-items/align-elements.ts +2 -2
  173. package/src/editor/plugins/edit-bar/edit-items/font-align.ts +1 -1
  174. package/src/editor/plugins/edit-bar/edit-items/font-color.ts +1 -1
  175. package/src/editor/plugins/edit-bar/edit-items/font-family.ts +1 -1
  176. package/src/editor/plugins/edit-bar/edit-items/font-size.ts +3 -3
  177. package/src/editor/plugins/edit-bar/edit-items/icon-color.ts +1 -1
  178. package/src/editor/plugins/edit-bar/index.ts +2 -2
  179. package/src/editor/plugins/index.ts +2 -0
  180. package/src/editor/plugins/reset-viewbox.ts +258 -0
  181. package/src/editor/types/editor.ts +17 -0
  182. package/src/editor/types/index.ts +1 -0
  183. package/src/editor/types/interaction.ts +31 -0
  184. package/src/editor/types/state.ts +14 -2
  185. package/src/editor/types/sync.ts +31 -0
  186. package/src/editor/utils/data.ts +2 -1
  187. package/src/editor/utils/event.ts +7 -0
  188. package/src/editor/utils/index.ts +1 -0
  189. package/src/editor/utils/object.ts +106 -0
  190. package/src/index.ts +26 -2
  191. package/src/options/types.ts +4 -0
  192. package/src/runtime/options.ts +8 -1
  193. package/src/templates/built-in.ts +30 -81
  194. package/src/templates/chart-pie.ts +89 -0
  195. package/src/utils/measure-text.ts +6 -6
  196. package/src/utils/padding.ts +10 -2
  197. package/src/utils/viewbox.ts +23 -0
  198. package/src/version.ts +1 -1
  199. /package/esm/editor/plugins/{edit-bar/components → components}/button.d.ts +0 -0
  200. /package/esm/editor/plugins/{edit-bar/components → components}/color-picker.d.ts +0 -0
  201. /package/esm/editor/plugins/{edit-bar/components → components}/index.d.ts +0 -0
  202. /package/esm/editor/plugins/{edit-bar/components → components}/index.js +0 -0
  203. /package/esm/editor/plugins/{edit-bar/components → components}/popover.d.ts +0 -0
  204. /package/esm/editor/plugins/{edit-bar/components → components}/select.d.ts +0 -0
  205. /package/lib/editor/plugins/{edit-bar/components → components}/button.d.ts +0 -0
  206. /package/lib/editor/plugins/{edit-bar/components → components}/color-picker.d.ts +0 -0
  207. /package/lib/editor/plugins/{edit-bar/components → components}/index.d.ts +0 -0
  208. /package/lib/editor/plugins/{edit-bar/components → components}/index.js +0 -0
  209. /package/lib/editor/plugins/{edit-bar/components → components}/popover.d.ts +0 -0
  210. /package/lib/editor/plugins/{edit-bar/components → components}/select.d.ts +0 -0
  211. /package/src/editor/plugins/{edit-bar/components → components}/index.ts +0 -0
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Editor = void 0;
4
4
  const managers_1 = require("./managers");
5
+ const sync_registry_1 = require("./managers/sync-registry");
6
+ const plugins_1 = require("./plugins");
5
7
  class Editor {
6
8
  constructor(emitter, document, options) {
7
9
  this.emitter = emitter;
@@ -15,6 +17,12 @@ class Editor {
15
17
  const state = new managers_1.StateManager();
16
18
  const plugin = new managers_1.PluginManager();
17
19
  const interaction = new managers_1.InteractionManager();
20
+ const syncRegistry = new sync_registry_1.SyncRegistry(() => state.getOptions());
21
+ this.commander = commander;
22
+ this.state = state;
23
+ this.plugin = plugin;
24
+ this.interaction = interaction;
25
+ this.syncRegistry = syncRegistry;
18
26
  commander.init({ state, emitter });
19
27
  state.init({
20
28
  emitter,
@@ -22,12 +30,15 @@ class Editor {
22
30
  commander,
23
31
  options,
24
32
  });
33
+ // Load core plugin: CoreSyncPlugin (handles viewBox/padding sync)
34
+ const corePlugin = new plugins_1.CoreSyncPlugin();
35
+ const userPlugins = options.plugins || [];
25
36
  plugin.init({
26
37
  emitter,
27
38
  editor: this,
28
39
  commander,
29
40
  state,
30
- }, options.plugins);
41
+ }, [corePlugin, ...userPlugins]);
31
42
  interaction.init({
32
43
  emitter,
33
44
  editor: this,
@@ -35,10 +46,9 @@ class Editor {
35
46
  state,
36
47
  interactions: options.interactions,
37
48
  });
38
- this.commander = commander;
39
- this.state = state;
40
- this.plugin = plugin;
41
- this.interaction = interaction;
49
+ }
50
+ registerSync(path, handler, options) {
51
+ return this.syncRegistry.register(path, handler, options);
42
52
  }
43
53
  getDocument() {
44
54
  return this.document;
@@ -49,6 +59,7 @@ class Editor {
49
59
  this.plugin.destroy();
50
60
  this.commander.destroy();
51
61
  this.state.destroy();
62
+ this.syncRegistry.destroy();
52
63
  }
53
64
  }
54
65
  exports.Editor = Editor;
@@ -1,3 +1,4 @@
1
+ export * from './commands';
1
2
  export { Editor } from './editor';
2
3
  export * from './interactions';
3
4
  export * from './plugins';
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.Editor = void 0;
18
+ __exportStar(require("./commands"), exports);
18
19
  var editor_1 = require("./editor");
19
20
  Object.defineProperty(exports, "Editor", { enumerable: true, get: function () { return editor_1.Editor; } });
20
21
  __exportStar(require("./interactions"), exports);
@@ -19,5 +19,4 @@ export declare class BrushSelect extends Interaction implements IInteraction {
19
19
  private clearBrush;
20
20
  private collectSelection;
21
21
  private hasElementAtStart;
22
- private isTextSelectionTarget;
23
22
  }
@@ -25,7 +25,7 @@ class BrushSelect extends base_1.Interaction {
25
25
  return;
26
26
  if (event.button !== 0)
27
27
  return;
28
- if (this.isTextSelectionTarget(event.target))
28
+ if ((0, utils_2.isTextSelectionTarget)(event.target))
29
29
  return;
30
30
  if (this.hasElementAtStart(event.target))
31
31
  return;
@@ -173,13 +173,5 @@ class BrushSelect extends base_1.Interaction {
173
173
  return true;
174
174
  return Boolean((_a = target.closest) === null || _a === void 0 ? void 0 : _a.call(target, '[data-element-type]'));
175
175
  }
176
- isTextSelectionTarget(target) {
177
- if (!(target instanceof HTMLElement))
178
- return false;
179
- if (target.isContentEditable)
180
- return true;
181
- const tag = target.tagName.toLowerCase();
182
- return tag === 'input' || tag === 'textarea';
183
- }
184
176
  }
185
177
  exports.BrushSelect = BrushSelect;
@@ -0,0 +1,35 @@
1
+ import { IInteraction, InteractionInitOptions, KeyCode } from '../types';
2
+ import { Interaction } from './base';
3
+ export interface DragCanvasOptions {
4
+ trigger?: KeyCode[];
5
+ }
6
+ export declare class DragCanvas extends Interaction implements IInteraction {
7
+ name: string;
8
+ /**
9
+ * 触发交互的按键代码。
10
+ * 参考标准的 KeyboardEvent.code 值:
11
+ * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values
12
+ * @default ['Space']
13
+ */
14
+ trigger: KeyCode[];
15
+ constructor(options?: DragCanvasOptions);
16
+ private isTriggerPressed;
17
+ private pointerId?;
18
+ private startPoint?;
19
+ private document;
20
+ private startViewBoxString?;
21
+ private completeInteraction?;
22
+ private isHovering;
23
+ init(options: InteractionInitOptions): void;
24
+ destroy(): void;
25
+ private handleKeyDown;
26
+ private handlePointerDown;
27
+ private handlePointerMove;
28
+ private handlePointerUp;
29
+ private handleKeyUp;
30
+ private stopDrag;
31
+ private setCursor;
32
+ private handleBlur;
33
+ private onMouseEnter;
34
+ private onMouseLeave;
35
+ }
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DragCanvas = void 0;
13
+ const utils_1 = require("../../utils");
14
+ const commands_1 = require("../commands");
15
+ const utils_2 = require("../utils");
16
+ const base_1 = require("./base");
17
+ class DragCanvas extends base_1.Interaction {
18
+ constructor(options) {
19
+ super();
20
+ this.name = 'drag-canvas';
21
+ /**
22
+ * 触发交互的按键代码。
23
+ * 参考标准的 KeyboardEvent.code 值:
24
+ * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values
25
+ * @default ['Space']
26
+ */
27
+ this.trigger = ['Space'];
28
+ this.isTriggerPressed = false;
29
+ // 防止组件快捷键侵入性过强
30
+ this.isHovering = false;
31
+ this.handleKeyDown = (event) => {
32
+ if (!this.interaction.isActive())
33
+ return;
34
+ if ((0, utils_2.isTextSelectionTarget)(event.target))
35
+ return;
36
+ // 增加焦点的判断,防止对空格的preventDefault侵入性过强
37
+ const target = event.target;
38
+ const isBody = target === document.body || target === document.documentElement;
39
+ const isEditor = target === this.document || this.document.contains(target);
40
+ if (!isBody && !isEditor)
41
+ return;
42
+ if (!this.trigger.includes(event.code))
43
+ return;
44
+ if (!this.isHovering && !this.isTriggerPressed)
45
+ return;
46
+ event.preventDefault();
47
+ event.stopPropagation();
48
+ this.interaction.executeExclusiveInteraction(this, () => __awaiter(this, void 0, void 0, function* () {
49
+ return new Promise((resolve) => {
50
+ this.completeInteraction = resolve;
51
+ this.isTriggerPressed = true;
52
+ const viewBox = (0, utils_1.getViewBox)(this.document);
53
+ this.startViewBoxString = (0, utils_1.viewBoxToString)(viewBox);
54
+ this.setCursor('grab');
55
+ this.document.addEventListener('pointerdown', this.handlePointerDown);
56
+ window.addEventListener('keyup', this.handleKeyUp);
57
+ });
58
+ }));
59
+ };
60
+ this.handlePointerDown = (event) => {
61
+ if (event.button !== 0)
62
+ return;
63
+ event.preventDefault();
64
+ event.stopPropagation();
65
+ const svg = this.document;
66
+ this.startPoint = (0, utils_2.clientToViewport)(svg, event.clientX, event.clientY);
67
+ this.pointerId = event.pointerId;
68
+ this.setCursor('grabbing');
69
+ window.addEventListener('pointermove', this.handlePointerMove);
70
+ window.addEventListener('pointerup', this.handlePointerUp);
71
+ window.addEventListener('pointercancel', this.handlePointerUp);
72
+ };
73
+ this.handlePointerMove = (event) => {
74
+ if (event.pointerId !== this.pointerId || !this.startPoint)
75
+ return;
76
+ event.preventDefault();
77
+ event.stopPropagation();
78
+ const svg = this.document;
79
+ const current = (0, utils_2.clientToViewport)(svg, event.clientX, event.clientY);
80
+ const dx = current.x - this.startPoint.x;
81
+ const dy = current.y - this.startPoint.y;
82
+ const viewBox = (0, utils_1.getViewBox)(svg);
83
+ const { x, y, width, height } = viewBox;
84
+ const newX = x - dx;
85
+ const newY = y - dy;
86
+ this.state.updateOptions({
87
+ viewBox: (0, utils_1.viewBoxToString)({ x: newX, y: newY, width, height }),
88
+ });
89
+ };
90
+ this.handlePointerUp = (event) => {
91
+ if (event.pointerId !== this.pointerId)
92
+ return;
93
+ this.startPoint = undefined;
94
+ this.pointerId = undefined;
95
+ this.setCursor('grab');
96
+ window.removeEventListener('pointermove', this.handlePointerMove);
97
+ window.removeEventListener('pointerup', this.handlePointerUp);
98
+ window.removeEventListener('pointercancel', this.handlePointerUp);
99
+ };
100
+ this.handleKeyUp = (event) => {
101
+ if (!this.trigger.includes(event.code))
102
+ return;
103
+ this.stopDrag();
104
+ };
105
+ this.stopDrag = () => {
106
+ var _a;
107
+ if (this.startViewBoxString) {
108
+ const svg = this.document;
109
+ const viewBox = (0, utils_1.getViewBox)(svg);
110
+ const currentViewBoxString = (0, utils_1.viewBoxToString)(viewBox);
111
+ if (this.startViewBoxString !== currentViewBoxString) {
112
+ const command = new commands_1.UpdateOptionsCommand({ viewBox: currentViewBoxString }, { viewBox: this.startViewBoxString });
113
+ void this.commander.execute(command);
114
+ }
115
+ }
116
+ this.startViewBoxString = undefined;
117
+ this.isTriggerPressed = false;
118
+ this.setCursor('default');
119
+ this.startPoint = undefined;
120
+ this.pointerId = undefined;
121
+ window.removeEventListener('keyup', this.handleKeyUp);
122
+ this.document.removeEventListener('pointerdown', this.handlePointerDown);
123
+ window.removeEventListener('pointermove', this.handlePointerMove);
124
+ window.removeEventListener('pointerup', this.handlePointerUp);
125
+ window.removeEventListener('pointercancel', this.handlePointerUp);
126
+ (_a = this.completeInteraction) === null || _a === void 0 ? void 0 : _a.call(this);
127
+ this.completeInteraction = undefined;
128
+ };
129
+ this.setCursor = (behavior) => {
130
+ document.body.style.cursor = behavior;
131
+ };
132
+ this.handleBlur = () => {
133
+ this.stopDrag();
134
+ };
135
+ this.onMouseEnter = () => {
136
+ this.isHovering = true;
137
+ };
138
+ this.onMouseLeave = () => {
139
+ this.isHovering = false;
140
+ };
141
+ if (options === null || options === void 0 ? void 0 : options.trigger) {
142
+ this.trigger = options.trigger;
143
+ }
144
+ }
145
+ init(options) {
146
+ super.init(options);
147
+ this.document = this.editor.getDocument();
148
+ this.document.addEventListener('mouseenter', this.onMouseEnter);
149
+ this.document.addEventListener('mouseleave', this.onMouseLeave);
150
+ window.addEventListener('keydown', this.handleKeyDown);
151
+ window.addEventListener('blur', this.handleBlur);
152
+ }
153
+ destroy() {
154
+ window.removeEventListener('keydown', this.handleKeyDown);
155
+ window.removeEventListener('keyup', this.handleKeyUp);
156
+ this.document.removeEventListener('pointerdown', this.handlePointerDown);
157
+ window.removeEventListener('pointermove', this.handlePointerMove);
158
+ window.removeEventListener('pointerup', this.handlePointerUp);
159
+ window.removeEventListener('pointercancel', this.handlePointerUp);
160
+ window.removeEventListener('blur', this.handleBlur);
161
+ this.document.removeEventListener('mouseenter', this.onMouseEnter);
162
+ this.document.removeEventListener('mouseleave', this.onMouseLeave);
163
+ }
164
+ }
165
+ exports.DragCanvas = DragCanvas;
@@ -116,9 +116,6 @@ class DragElement extends base_1.Interaction {
116
116
  return true;
117
117
  if (!this.startTarget)
118
118
  return false;
119
- if (this.willReplaceSelection) {
120
- this.interaction.select([this.startTarget], 'replace');
121
- }
122
119
  this.dragItems = this.selectionForDrag
123
120
  .filter((element) => (0, utils_1.isEditableText)(element))
124
121
  .map((element) => this.createDragItem(element))
@@ -128,6 +125,10 @@ class DragElement extends base_1.Interaction {
128
125
  let started = false;
129
126
  this.interaction.executeExclusiveInteraction(this, () => __awaiter(this, void 0, void 0, function* () {
130
127
  return new Promise((resolve) => {
128
+ // 只有拿到锁之后,才真正执行选中逻辑
129
+ if (this.willReplaceSelection && this.startTarget) {
130
+ this.interaction.select([this.startTarget], 'replace');
131
+ }
131
132
  this.completeInteraction = resolve;
132
133
  started = true;
133
134
  });
@@ -2,6 +2,7 @@ export { Interaction } from './base';
2
2
  export { BrushSelect } from './brush-select';
3
3
  export { ClickSelect } from './click-select';
4
4
  export { DblClickEditText } from './dblclick-edit-text';
5
+ export { DragCanvas } from './drag-canvas';
5
6
  export { DragElement } from './drag-element';
6
7
  export { HotkeyHistory } from './hotkey-history';
7
8
  export { SelectHighlight } from './select-highlight';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ZoomWheel = exports.SelectHighlight = exports.HotkeyHistory = exports.DragElement = exports.DblClickEditText = exports.ClickSelect = exports.BrushSelect = exports.Interaction = void 0;
3
+ exports.ZoomWheel = exports.SelectHighlight = exports.HotkeyHistory = exports.DragElement = exports.DragCanvas = exports.DblClickEditText = exports.ClickSelect = exports.BrushSelect = exports.Interaction = void 0;
4
4
  var base_1 = require("./base");
5
5
  Object.defineProperty(exports, "Interaction", { enumerable: true, get: function () { return base_1.Interaction; } });
6
6
  var brush_select_1 = require("./brush-select");
@@ -9,6 +9,8 @@ var click_select_1 = require("./click-select");
9
9
  Object.defineProperty(exports, "ClickSelect", { enumerable: true, get: function () { return click_select_1.ClickSelect; } });
10
10
  var dblclick_edit_text_1 = require("./dblclick-edit-text");
11
11
  Object.defineProperty(exports, "DblClickEditText", { enumerable: true, get: function () { return dblclick_edit_text_1.DblClickEditText; } });
12
+ var drag_canvas_1 = require("./drag-canvas");
13
+ Object.defineProperty(exports, "DragCanvas", { enumerable: true, get: function () { return drag_canvas_1.DragCanvas; } });
12
14
  var drag_element_1 = require("./drag-element");
13
15
  Object.defineProperty(exports, "DragElement", { enumerable: true, get: function () { return drag_element_1.DragElement; } });
14
16
  var hotkey_history_1 = require("./hotkey-history");
@@ -1,8 +1,20 @@
1
1
  import type { IInteraction, InteractionInitOptions } from '../types';
2
2
  import { Interaction } from './base';
3
+ export interface ZoomWheelOptions {
4
+ minViewBoxSize?: number;
5
+ maxViewBoxSize?: number;
6
+ }
3
7
  export declare class ZoomWheel extends Interaction implements IInteraction {
4
8
  name: string;
9
+ private minViewBoxSize;
10
+ private maxViewBoxSize;
11
+ constructor(options?: ZoomWheelOptions);
12
+ private initialViewBox;
13
+ private handleKeyUp;
5
14
  private wheelListener;
15
+ private getMousePoint;
16
+ private getCenterPoint;
17
+ private shouldZoom;
6
18
  init(options: InteractionInitOptions): void;
7
19
  destroy(): void;
8
20
  }
@@ -2,43 +2,82 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ZoomWheel = void 0;
4
4
  const lodash_es_1 = require("lodash-es");
5
- const utils_1 = require("../../utils");
5
+ const viewbox_1 = require("../../utils/viewbox");
6
6
  const commands_1 = require("../commands");
7
+ const utils_1 = require("../utils");
7
8
  const base_1 = require("./base");
8
- const MIN_VIEWBOX_SIZE = 1;
9
- const MIN_PADDING = -5000;
10
- const MAX_PADDING = 5000;
9
+ const ZOOM_FACTOR = 1.1;
11
10
  class ZoomWheel extends base_1.Interaction {
12
- constructor() {
13
- super(...arguments);
11
+ constructor(options) {
12
+ super();
14
13
  this.name = 'zoom-wheel';
14
+ this.minViewBoxSize = 20;
15
+ this.maxViewBoxSize = 20000;
16
+ this.initialViewBox = null;
17
+ this.handleKeyUp = (event) => {
18
+ const isZoomModifierHeld = event.ctrlKey || event.metaKey || event.shiftKey;
19
+ if (!isZoomModifierHeld && this.initialViewBox) {
20
+ const currentViewBox = (0, viewbox_1.viewBoxToString)((0, viewbox_1.getViewBox)(this.editor.getDocument()));
21
+ if (currentViewBox !== this.initialViewBox) {
22
+ const command = new commands_1.UpdateOptionsCommand({ viewBox: currentViewBox }, { viewBox: this.initialViewBox });
23
+ void this.commander.execute(command);
24
+ }
25
+ this.initialViewBox = null;
26
+ document.removeEventListener('keyup', this.handleKeyUp);
27
+ }
28
+ };
15
29
  this.wheelListener = (event) => {
16
- var _a;
17
- if (!this.interaction.isActive())
18
- return;
19
- if (!event.ctrlKey && !event.metaKey)
30
+ if (!this.shouldZoom(event))
20
31
  return;
21
32
  event.preventDefault();
22
- const factor = event.deltaY > 0 ? 1.1 : 0.9;
23
- const current = this.state.getOptions();
24
- const currentPadding = (_a = current.padding) !== null && _a !== void 0 ? _a : 0;
25
- const parsed = (0, utils_1.parsePadding)(currentPadding);
33
+ // Standard Zoom: Scroll Up (deltaY < 0) = Zoom In
34
+ const isZoomIn = event.deltaY < 0;
35
+ const factor = isZoomIn ? 1 / ZOOM_FACTOR : ZOOM_FACTOR;
26
36
  const svg = this.editor.getDocument();
27
- const bbox = svg.getBBox();
28
- const scaled = parsed.map((value) => {
29
- const base = value === 0 ? 1 : value;
30
- return (0, lodash_es_1.clamp)(base * factor, MIN_PADDING, MAX_PADDING);
31
- });
32
- const [top, right, bottom, left] = scaled;
33
- const newWidth = bbox.width + left + right;
34
- const newHeight = bbox.height + top + bottom;
35
- if (newWidth <= MIN_VIEWBOX_SIZE || newHeight <= MIN_VIEWBOX_SIZE)
37
+ const viewBox = (0, viewbox_1.getViewBox)(svg);
38
+ const { width, height } = viewBox;
39
+ const newWidth = width * factor;
40
+ const newHeight = height * factor;
41
+ if (!(0, lodash_es_1.inRange)(newWidth, this.minViewBoxSize, this.maxViewBoxSize) ||
42
+ !(0, lodash_es_1.inRange)(newHeight, this.minViewBoxSize, this.maxViewBoxSize))
36
43
  return;
37
- const command = new commands_1.UpdateOptionsCommand({
38
- padding: scaled,
44
+ if (this.initialViewBox === null) {
45
+ this.initialViewBox = (0, viewbox_1.viewBoxToString)(viewBox);
46
+ document.addEventListener('keyup', this.handleKeyUp);
47
+ }
48
+ const pivot = (event.ctrlKey || event.metaKey) && !event.shiftKey
49
+ ? this.getMousePoint(svg, event)
50
+ : this.getCenterPoint(viewBox);
51
+ const newViewBox = (0, viewbox_1.calculateZoomedViewBox)(viewBox, factor, pivot);
52
+ this.state.updateOptions({
53
+ viewBox: (0, viewbox_1.viewBoxToString)(newViewBox),
39
54
  });
40
- void this.commander.execute(command);
41
55
  };
56
+ this.getMousePoint = (svg, event) => {
57
+ return (0, utils_1.clientToViewport)(svg, event.clientX, event.clientY);
58
+ };
59
+ this.getCenterPoint = (viewBox) => {
60
+ const centerX = viewBox.x + viewBox.width / 2;
61
+ const centerY = viewBox.y + viewBox.height / 2;
62
+ return { x: centerX, y: centerY };
63
+ };
64
+ this.shouldZoom = (event) => {
65
+ if (!this.interaction.isActive())
66
+ return false;
67
+ if (event.deltaY === 0)
68
+ return false;
69
+ const isMouseZoom = event.ctrlKey || event.metaKey;
70
+ const isCenterZoom = event.shiftKey;
71
+ if (isMouseZoom && isCenterZoom)
72
+ return false;
73
+ return isMouseZoom || isCenterZoom;
74
+ };
75
+ if ((options === null || options === void 0 ? void 0 : options.minViewBoxSize) !== undefined) {
76
+ this.minViewBoxSize = options.minViewBoxSize;
77
+ }
78
+ if ((options === null || options === void 0 ? void 0 : options.maxViewBoxSize) !== undefined) {
79
+ this.maxViewBoxSize = options.maxViewBoxSize;
80
+ }
42
81
  }
43
82
  init(options) {
44
83
  super.init(options);
@@ -46,6 +85,7 @@ class ZoomWheel extends base_1.Interaction {
46
85
  }
47
86
  destroy() {
48
87
  document.removeEventListener('wheel', this.wheelListener);
88
+ document.removeEventListener('keyup', this.handleKeyUp);
49
89
  }
50
90
  }
51
91
  exports.ZoomWheel = ZoomWheel;
@@ -2,3 +2,4 @@ export * from './command';
2
2
  export * from './interaction';
3
3
  export * from './plugin';
4
4
  export * from './state';
5
+ export * from './sync-registry';
@@ -18,3 +18,4 @@ __exportStar(require("./command"), exports);
18
18
  __exportStar(require("./interaction"), exports);
19
19
  __exportStar(require("./plugin"), exports);
20
20
  __exportStar(require("./state"), exports);
21
+ __exportStar(require("./sync-registry"), exports);
@@ -1,4 +1,4 @@
1
- import type { ParsedInfographicOptions } from '../../options';
1
+ import type { ParsedInfographicOptions, UpdatableInfographicOptions } from '../../options';
2
2
  import type { Element, IEventEmitter, ItemDatum } from '../../types';
3
3
  import type { ElementProps, ICommandManager, IEditor, IStateManager, StateManagerInitOptions } from '../types';
4
4
  export declare class StateManager implements IStateManager {
@@ -12,7 +12,9 @@ export declare class StateManager implements IStateManager {
12
12
  removeItemDatum(indexes: number[], count?: number): void;
13
13
  updateData(key: string, value: any): void;
14
14
  updateElement(element: Element, props: Partial<ElementProps>): void;
15
- updateOptions(options: ParsedInfographicOptions): void;
15
+ updateOptions(options: UpdatableInfographicOptions, execOptions?: {
16
+ bubbleUp?: boolean;
17
+ }): void;
16
18
  getOptions(): ParsedInfographicOptions;
17
19
  /**
18
20
  * 不包含文本内容、图标类型更新
@@ -28,6 +28,8 @@ class StateManager {
28
28
  }
29
29
  updateItemDatum(indexes, datum) {
30
30
  const item = (0, utils_1.getDatumByIndexes)(this.options.data, indexes);
31
+ if (item == null || indexes.length === 0)
32
+ return;
31
33
  Object.assign(item, datum);
32
34
  this.emitter.emit('options:data:item:update', { indexes, datum });
33
35
  this.emitter.emit('options:change', {
@@ -77,11 +79,14 @@ class StateManager {
77
79
  updateElement(element, props) {
78
80
  this.updateBuiltInElement(element, props);
79
81
  }
80
- updateOptions(options) {
81
- this.options = Object.assign(Object.assign({}, this.options), options);
82
- if (this.options.padding !== undefined) {
83
- (0, utils_1.setSVGPadding)(this.editor.getDocument(), (0, utils_1.parsePadding)(this.options.padding));
84
- }
82
+ updateOptions(options, execOptions) {
83
+ const { bubbleUp = false } = execOptions || {};
84
+ (0, utils_2.applyOptionUpdates)(this.options, options, '', {
85
+ bubbleUp,
86
+ collector: (path, newVal, oldVal) => {
87
+ this.editor.syncRegistry.trigger(path, newVal, oldVal);
88
+ },
89
+ });
85
90
  this.emitter.emit('options:change', {
86
91
  type: 'options:change',
87
92
  changes: [
@@ -112,6 +117,8 @@ class StateManager {
112
117
  const indexes = isItemElement ? (0, utils_2.getIndexesFromElement)(element) : undefined;
113
118
  if (isItemElement) {
114
119
  const datum = (0, utils_1.getDatumByIndexes)(data, indexes);
120
+ if (datum == null)
121
+ return;
115
122
  const key = role.replace('item-', '');
116
123
  datum.attributes || (datum.attributes = {});
117
124
  (_a = datum.attributes)[key] || (_a[key] = {});
@@ -0,0 +1,15 @@
1
+ import { ISyncRegistry, SyncHandler } from '../types';
2
+ type OptionsGetter = () => any;
3
+ export declare class SyncRegistry implements ISyncRegistry {
4
+ private getOptions;
5
+ private handlers;
6
+ private isDispatching;
7
+ private isDestroyed;
8
+ constructor(getOptions: OptionsGetter);
9
+ register(path: string, handler: SyncHandler, options?: {
10
+ immediate?: boolean;
11
+ }): () => void;
12
+ trigger(path: string, newVal: any, oldVal: any): void;
13
+ destroy(): void;
14
+ }
15
+ export {};
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SyncRegistry = void 0;
4
+ const lodash_es_1 = require("lodash-es");
5
+ class SyncRegistry {
6
+ constructor(getOptions) {
7
+ this.getOptions = getOptions;
8
+ this.handlers = new Map();
9
+ // lock to prevent recursive updates
10
+ this.isDispatching = false;
11
+ this.isDestroyed = false;
12
+ }
13
+ register(path, handler, options) {
14
+ if (!this.handlers.has(path)) {
15
+ this.handlers.set(path, new Set());
16
+ }
17
+ this.handlers.get(path).add(handler);
18
+ if (options === null || options === void 0 ? void 0 : options.immediate) {
19
+ const currentVal = (0, lodash_es_1.get)(this.getOptions(), path);
20
+ handler(currentVal, undefined);
21
+ }
22
+ return () => {
23
+ const set = this.handlers.get(path);
24
+ if (set) {
25
+ set.delete(handler);
26
+ if (set.size === 0) {
27
+ this.handlers.delete(path);
28
+ }
29
+ }
30
+ };
31
+ }
32
+ trigger(path, newVal, oldVal) {
33
+ if (this.isDestroyed || this.isDispatching) {
34
+ if (this.isDispatching) {
35
+ console.warn(`[SyncRegistry] Recursive update detected on ${path}. Skipped to prevent loop.`);
36
+ }
37
+ return;
38
+ }
39
+ const handlers = this.handlers.get(path);
40
+ if (handlers) {
41
+ this.isDispatching = true;
42
+ try {
43
+ handlers.forEach((fn) => fn(newVal, oldVal));
44
+ }
45
+ finally {
46
+ this.isDispatching = false;
47
+ }
48
+ }
49
+ }
50
+ destroy() {
51
+ this.isDestroyed = true;
52
+ this.handlers.clear();
53
+ }
54
+ }
55
+ exports.SyncRegistry = SyncRegistry;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IconButton = void 0;
4
- const utils_1 = require("../../../../utils");
4
+ const utils_1 = require("../../../utils");
5
5
  const IconButton = ({ icon, onClick, activate = false, }) => {
6
6
  ensureIconButtonStyle();
7
7
  const button = document.createElement('button');
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ColorPicker = ColorPicker;
4
4
  const culori_1 = require("culori");
5
- const utils_1 = require("../../../../utils");
5
+ const utils_1 = require("../../../utils");
6
6
  const COLOR_PICKER_CLASS = 'infographic-color-picker';
7
7
  const COLOR_PICKER_SWATCHES_CLASS = `${COLOR_PICKER_CLASS}__swatches`;
8
8
  const COLOR_PICKER_SWATCH_CLASS = `${COLOR_PICKER_CLASS}__swatch`;