ice-render 1.0.4 → 1.0.6

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 (145) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +229 -141
  3. package/dist/THIRD-PARTY-NOTICES.txt +32 -0
  4. package/dist/index.cjs +30 -0
  5. package/dist/index.mjs +30 -0
  6. package/dist/index.umd.js +6 -1
  7. package/dist/types/FrameManager.d.mts +26 -0
  8. package/dist/types/FrameManager.d.ts +26 -26
  9. package/dist/types/ICE.d.mts +369 -0
  10. package/dist/types/ICE.d.ts +369 -107
  11. package/dist/types/a11y/accessibility.d.mts +46 -0
  12. package/dist/types/a11y/accessibility.d.ts +46 -0
  13. package/dist/types/animation/AnimationManager.d.mts +96 -0
  14. package/dist/types/animation/AnimationManager.d.ts +96 -25
  15. package/dist/types/animation/Easing.d.mts +33 -0
  16. package/dist/types/animation/Easing.d.ts +33 -32
  17. package/dist/types/consts/BIG_ZINDEX_NUMBER.d.mts +14 -0
  18. package/dist/types/consts/BIG_ZINDEX_NUMBER.d.ts +14 -14
  19. package/dist/types/consts/COMPONENT_TYPE_MAPPING.d.mts +45 -0
  20. package/dist/types/consts/COMPONENT_TYPE_MAPPING.d.ts +45 -36
  21. package/dist/types/consts/DOM_EVENT_MAPPING_CONSTS.d.mts +37 -0
  22. package/dist/types/consts/DOM_EVENT_MAPPING_CONSTS.d.ts +37 -19
  23. package/dist/types/consts/ICE_EVENT_NAME_CONSTS.d.mts +27 -0
  24. package/dist/types/consts/ICE_EVENT_NAME_CONSTS.d.ts +27 -20
  25. package/dist/types/control-panel/AlignmentGuideManager.d.mts +92 -0
  26. package/dist/types/control-panel/AlignmentGuideManager.d.ts +92 -0
  27. package/dist/types/control-panel/ICEControlPanel.d.mts +37 -0
  28. package/dist/types/control-panel/ICEControlPanel.d.ts +37 -37
  29. package/dist/types/control-panel/ICEControlPanelManager.d.mts +25 -0
  30. package/dist/types/control-panel/ICEControlPanelManager.d.ts +25 -23
  31. package/dist/types/control-panel/link-controls/LineControlPanel.d.mts +39 -0
  32. package/dist/types/control-panel/link-controls/LineControlPanel.d.ts +39 -39
  33. package/dist/types/control-panel/transform-controls/ResizeControl.d.mts +38 -0
  34. package/dist/types/control-panel/transform-controls/ResizeControl.d.ts +38 -38
  35. package/dist/types/control-panel/transform-controls/RotateControl.d.mts +12 -0
  36. package/dist/types/control-panel/transform-controls/RotateControl.d.ts +12 -12
  37. package/dist/types/control-panel/transform-controls/TransformControlPanel.d.mts +83 -0
  38. package/dist/types/control-panel/transform-controls/TransformControlPanel.d.ts +83 -74
  39. package/dist/types/control-panel/transform-controls/constraints.d.mts +24 -0
  40. package/dist/types/control-panel/transform-controls/constraints.d.ts +24 -0
  41. package/dist/types/cross-platform/PolyfillPath2D.d.mts +31 -0
  42. package/dist/types/cross-platform/PolyfillPath2D.d.ts +31 -0
  43. package/dist/types/cross-platform/root.d.mts +7 -0
  44. package/dist/types/cross-platform/root.d.ts +7 -2
  45. package/dist/types/event/DOMEventDispatcher.d.mts +68 -0
  46. package/dist/types/event/DOMEventDispatcher.d.ts +68 -29
  47. package/dist/types/event/DOMEventInterceptor.d.mts +36 -0
  48. package/dist/types/event/DOMEventInterceptor.d.ts +36 -7
  49. package/dist/types/event/EventBus.d.mts +27 -0
  50. package/dist/types/event/EventBus.d.ts +27 -27
  51. package/dist/types/event/ICEEvent.d.mts +46 -0
  52. package/dist/types/event/ICEEvent.d.ts +46 -46
  53. package/dist/types/event/ICEEventTarget.d.mts +106 -0
  54. package/dist/types/event/ICEEventTarget.d.ts +106 -106
  55. package/dist/types/event/input-normalize.d.mts +75 -0
  56. package/dist/types/event/input-normalize.d.ts +75 -0
  57. package/dist/types/geometry/GeoLine.d.mts +24 -0
  58. package/dist/types/geometry/GeoLine.d.ts +24 -23
  59. package/dist/types/geometry/GeoPoint.d.mts +53 -0
  60. package/dist/types/geometry/GeoPoint.d.ts +53 -66
  61. package/dist/types/geometry/GeoUtil.d.mts +73 -0
  62. package/dist/types/geometry/GeoUtil.d.ts +73 -37
  63. package/dist/types/geometry/ICEBoundingBox.d.mts +81 -0
  64. package/dist/types/geometry/ICEBoundingBox.d.ts +81 -81
  65. package/dist/types/graphic/ICEComponent.d.mts +436 -0
  66. package/dist/types/graphic/ICEComponent.d.ts +436 -264
  67. package/dist/types/graphic/ICEDotPath.d.mts +99 -0
  68. package/dist/types/graphic/ICEDotPath.d.ts +99 -63
  69. package/dist/types/graphic/ICEImage.d.mts +17 -0
  70. package/dist/types/graphic/ICEImage.d.ts +17 -17
  71. package/dist/types/graphic/ICEPath.d.mts +39 -0
  72. package/dist/types/graphic/ICEPath.d.ts +39 -36
  73. package/dist/types/graphic/container/ICEGroup.d.mts +101 -0
  74. package/dist/types/graphic/container/ICEGroup.d.ts +101 -53
  75. package/dist/types/graphic/link/ICEBezier.d.mts +23 -0
  76. package/dist/types/graphic/link/ICEBezier.d.ts +23 -15
  77. package/dist/types/graphic/link/ICELinkHook.d.mts +52 -0
  78. package/dist/types/graphic/link/ICELinkHook.d.ts +52 -52
  79. package/dist/types/graphic/link/ICELinkSlot.d.mts +54 -0
  80. package/dist/types/graphic/link/ICELinkSlot.d.ts +54 -46
  81. package/dist/types/graphic/link/ICELinkSlotManager.d.mts +28 -0
  82. package/dist/types/graphic/link/ICELinkSlotManager.d.ts +28 -28
  83. package/dist/types/graphic/link/ICEPolyLine.d.mts +292 -0
  84. package/dist/types/graphic/link/ICEPolyLine.d.ts +292 -219
  85. package/dist/types/graphic/link/ICEVisioLink.d.mts +163 -0
  86. package/dist/types/graphic/link/ICEVisioLink.d.ts +163 -129
  87. package/dist/types/graphic/shape/ICECircle.d.mts +19 -0
  88. package/dist/types/graphic/shape/ICECircle.d.ts +19 -19
  89. package/dist/types/graphic/shape/ICEEllipse.d.mts +29 -0
  90. package/dist/types/graphic/shape/ICEEllipse.d.ts +29 -23
  91. package/dist/types/graphic/shape/ICEIsogon.d.mts +52 -0
  92. package/dist/types/graphic/shape/ICEIsogon.d.ts +52 -52
  93. package/dist/types/graphic/shape/ICERect.d.mts +10 -0
  94. package/dist/types/graphic/shape/ICERect.d.ts +10 -17
  95. package/dist/types/graphic/shape/ICERose.d.mts +41 -0
  96. package/dist/types/graphic/shape/ICERose.d.ts +41 -41
  97. package/dist/types/graphic/shape/ICEStar.d.mts +45 -0
  98. package/dist/types/graphic/shape/ICEStar.d.ts +45 -45
  99. package/dist/types/graphic/text/ICEText.d.mts +137 -0
  100. package/dist/types/graphic/text/ICEText.d.ts +137 -65
  101. package/dist/types/index.d.mts +55 -0
  102. package/dist/types/index.d.ts +55 -41
  103. package/dist/types/layout/ICEBorderLayout.d.mts +34 -0
  104. package/dist/types/layout/ICEBorderLayout.d.ts +34 -0
  105. package/dist/types/layout/ICEBoxLayout.d.mts +30 -0
  106. package/dist/types/layout/ICEBoxLayout.d.ts +30 -0
  107. package/dist/types/layout/ICECardLayout.d.mts +36 -0
  108. package/dist/types/layout/ICECardLayout.d.ts +36 -0
  109. package/dist/types/layout/ICEFlowLayout.d.mts +31 -0
  110. package/dist/types/layout/ICEFlowLayout.d.ts +31 -0
  111. package/dist/types/layout/ICEGridLayout.d.mts +33 -0
  112. package/dist/types/layout/ICEGridLayout.d.ts +33 -0
  113. package/dist/types/layout/ICELayeredLayout.d.mts +49 -0
  114. package/dist/types/layout/ICELayeredLayout.d.ts +49 -0
  115. package/dist/types/layout/ICELayoutManager.d.mts +33 -0
  116. package/dist/types/layout/ICELayoutManager.d.ts +33 -0
  117. package/dist/types/layout/ICEOverlayLayout.d.mts +25 -0
  118. package/dist/types/layout/ICEOverlayLayout.d.ts +25 -0
  119. package/dist/types/persistence/Deserializer.d.mts +43 -0
  120. package/dist/types/persistence/Deserializer.d.ts +43 -14
  121. package/dist/types/persistence/Serializer.d.mts +35 -0
  122. package/dist/types/persistence/Serializer.d.ts +35 -26
  123. package/dist/types/plugin/PluginHost.d.mts +86 -0
  124. package/dist/types/plugin/PluginHost.d.ts +86 -0
  125. package/dist/types/renderer/CanvasRenderer.d.mts +150 -0
  126. package/dist/types/renderer/CanvasRenderer.d.ts +150 -22
  127. package/dist/types/renderer/ObjectCache.d.mts +79 -0
  128. package/dist/types/renderer/ObjectCache.d.ts +79 -0
  129. package/dist/types/renderer/dirty-rect-util.d.mts +86 -0
  130. package/dist/types/renderer/dirty-rect-util.d.ts +86 -0
  131. package/dist/types/theme/ICETheme.d.mts +382 -0
  132. package/dist/types/theme/ICETheme.d.ts +382 -0
  133. package/dist/types/util/ImageCache.d.mts +19 -0
  134. package/dist/types/util/ImageCache.d.ts +19 -19
  135. package/dist/types/util/data-util.d.mts +43 -0
  136. package/dist/types/util/data-util.d.ts +43 -19
  137. package/dist/types/util/gl-matrix-skew.d.mts +14 -0
  138. package/dist/types/util/gl-matrix-skew.d.ts +14 -14
  139. package/dist/types/util/lang.d.mts +28 -0
  140. package/dist/types/util/lang.d.ts +28 -0
  141. package/dist/types/util/uuid.d.mts +1 -0
  142. package/dist/types/util/uuid.d.ts +1 -1
  143. package/package.json +118 -81
  144. package/dist/index.cjs.js +0 -25
  145. package/dist/index.js +0 -25
@@ -1,107 +1,369 @@
1
- import AnimationManager from './animation/AnimationManager';
2
- import ICEControlPanelManager from './control-panel/ICEControlPanelManager';
3
- import DOMEventDispatcher from './event/DOMEventDispatcher';
4
- import EventBus from './event/EventBus';
5
- import ICEComponent from './graphic/ICEComponent';
6
- import ICELinkSlotManager from './graphic/link/ICELinkSlotManager';
7
- import Deserializer from './persistence/Deserializer';
8
- import Serializer from './persistence/Serializer';
9
- import ImageCache from './util/ImageCache';
10
- /**
11
- * @class ICE
12
- *
13
- * - ICE 是整个引擎的主入口类。
14
- * - 同一个 canvas 标签上只能初始化一个 ICE 实例。
15
- * - 同一个页面上可以存在多幅图。
16
- *
17
- * @author 大漠穷秋<damoqiongqiu@126.com>
18
- */
19
- declare class ICE {
20
- childNodes: any[];
21
- toolNodes: any[];
22
- evtBus: EventBus;
23
- root: any;
24
- canvasEl: any;
25
- ctx: any;
26
- canvasWidth: number;
27
- canvasHeight: number;
28
- canvasBoundingClientRect: any;
29
- selectionList: Array<any>;
30
- typeMapping: {};
31
- renderer: any;
32
- animationManager: AnimationManager;
33
- eventDispatcher: DOMEventDispatcher;
34
- controlPanelManager: ICEControlPanelManager;
35
- linkSlotManager: ICELinkSlotManager;
36
- serializer: Serializer;
37
- deserializer: Deserializer;
38
- imageCache: ImageCache;
39
- private __dirty;
40
- constructor();
41
- /**
42
- * @param ctx DOM id or CanvasContext
43
- */
44
- init(ctx: any): this;
45
- /**
46
- * @method addChild
47
- * 添加交互工具组件。
48
- * 工具组件不触发事件,不产生动画效果。
49
- * @param {ICEComponent} tool
50
- */
51
- addTool(tool: ICEComponent): void;
52
- /**
53
- * @methos removeTool
54
- * 删除交互工具组件。
55
- * 工具组件不触发事件,不产生动画效果。
56
- * @param tool
57
- */
58
- removeTool(tool: ICEComponent): void;
59
- /**
60
- *
61
- * 调用 ICE.addChild() 方法,会直接把对象画在 canvas 上。
62
- * 如果需要在容器中画组件,参见 @see ICEGroup.addChild() 方法
63
- *
64
- * @param component
65
- */
66
- addChild(component: any, markDirty?: boolean): void;
67
- addChildren(arr: Array<ICEComponent>): void;
68
- removeChild(component: ICEComponent, markDirty?: boolean): void;
69
- removeChildren(arr: Array<ICEComponent>): void;
70
- clearAll(): void;
71
- findComponent(id: string): any;
72
- set dirty(flag: boolean);
73
- get dirty(): boolean;
74
- /**
75
- * @method registerType 注册组件类型
76
- *
77
- * - 需要在反序列化之前调用,否则无法反序列化。
78
- * - ICE 内置的类型已经自动注册,不需要手动注册。
79
- *
80
- * @param className
81
- * @param Clazz
82
- */
83
- registerType(className: string, Clazz: Function): void;
84
- /**
85
- * @method getType 获取组件构造函数
86
- * @param className
87
- * @returns
88
- */
89
- getType(className: string): any;
90
- /**
91
- * 把对象序列化成 JSON 字符串:
92
- * - 容器型组件需要负责子节点的序列化操作
93
- * - 如果组件不需要序列化,需要返回 null
94
- * @returns Object
95
- */
96
- toJSONString(): string;
97
- /**
98
- * 把对象序列化成 JSON 对象:
99
- * - 容器型组件需要负责子节点的序列化操作
100
- * - 如果组件不需要序列化,需要返回 null
101
- * @returns Object
102
- */
103
- toJSONObject(): object;
104
- fromJSONObject(jsonObject: any): void;
105
- fromJSONString(jsonStr: string): void;
106
- }
107
- export default ICE;
1
+ import AnimationManager from './animation/AnimationManager';
2
+ import ICEControlPanelManager from './control-panel/ICEControlPanelManager';
3
+ import AlignmentGuideManager from './control-panel/AlignmentGuideManager';
4
+ import DOMEventDispatcher from './event/DOMEventDispatcher';
5
+ import EventBus from './event/EventBus';
6
+ import ICEComponent from './graphic/ICEComponent';
7
+ import ICELinkSlotManager from './graphic/link/ICELinkSlotManager';
8
+ import Deserializer from './persistence/Deserializer';
9
+ import Serializer from './persistence/Serializer';
10
+ import PluginHost, { ICEPlugin } from './plugin/PluginHost';
11
+ import { ICEAccessibleNode, ICEAccessibilityOptions } from './a11y/accessibility';
12
+ import ImageCache from './util/ImageCache';
13
+ import { ICETheme, ICESemanticTheme } from './theme/ICETheme';
14
+ /**
15
+ * @class ICE
16
+ *
17
+ * - ICE 是整个引擎的主入口类。
18
+ * - 同一个 canvas 标签上只能初始化一个 ICE 实例。
19
+ * - 同一个页面上可以存在多幅图。
20
+ *
21
+ * @author 大漠穷秋<damoqiongqiu@126.com>
22
+ */
23
+ declare class ICE {
24
+ childNodes: any[];
25
+ toolNodes: any[];
26
+ private __childSet;
27
+ private __toolSet;
28
+ evtBus: EventBus;
29
+ root: any;
30
+ canvasEl: any;
31
+ ctx: any;
32
+ canvasWidth: number;
33
+ canvasHeight: number;
34
+ canvasBoundingClientRect: any;
35
+ /** 视口变换(视图缩放/平移):屏幕 = 世界 * scale + translate。默认单位视口,不影响既有行为。 */
36
+ viewport: {
37
+ scale: number;
38
+ tx: number;
39
+ ty: number;
40
+ };
41
+ /**
42
+ * 设备像素比。默认 1(不改变既有行为)。
43
+ *
44
+ * 传 >1 时(`ICE.init(el, { dpr: 2 })`):引擎把 canvas 的 backing store 放大到 cssSize*dpr,
45
+ * 渲染变换乘以 dpr,从而在高分屏上不发虚。**交互侧(命中/拖拽/吸附)仍用 CSS 像素语义**,
46
+ * 因为鼠标/触摸坐标本身就是 CSS 像素,所以 screenToWorld 不参与 dpr。
47
+ */
48
+ dpr: number;
49
+ /** 渲染用视口缓存(= dpr · viewport),避免每组件每帧分配对象。 */
50
+ private __renderVp;
51
+ /**
52
+ * canvas 内容盒(绘制区)相对视口的偏移与尺寸。
53
+ *
54
+ * `getBoundingClientRect()` 返回的是 **border-box**,而 canvas 的绘制区是**内容盒**:
55
+ * 画布带 border / padding 时,若直接用 rect.left/top 换算鼠标坐标会整体偏移(差一个边框宽),
56
+ * backing store 尺寸也会被边框撑大。这里在刷新 rect 时一并读取 computedStyle 补偿。
57
+ */
58
+ private __contentBox;
59
+ selectionList: Array<any>;
60
+ /** 插件宿主:组件 / 渲染 / 交互工具三层注册点,见 `src/plugin/PluginHost.ts`。 */
61
+ plugins: PluginHost;
62
+ /**
63
+ * 当前实例持有的主题(**实例级**,互不污染)。
64
+ *
65
+ * 初始值取模块级默认主题;`setTheme()` 只改本实例。
66
+ * 组件构造时若用了 `preset`,会在加入本实例时按这里的主题重新解析一次
67
+ * (见 `addChild` / `addTool` 中的 `__reapplyPreset`)。
68
+ */
69
+ theme: ICETheme;
70
+ typeMapping: {};
71
+ /** 构造函数 → 类型名 的反查表(序列化用)。惰性构建,registerType/init 后失效重建。 */
72
+ private __typeIdMapping;
73
+ renderer: any;
74
+ animationManager: AnimationManager;
75
+ eventDispatcher: DOMEventDispatcher;
76
+ controlPanelManager: ICEControlPanelManager;
77
+ alignmentGuide: AlignmentGuideManager;
78
+ linkSlotManager: ICELinkSlotManager;
79
+ serializer: Serializer;
80
+ deserializer: Deserializer;
81
+ imageCache: ImageCache;
82
+ private __dirty;
83
+ constructor();
84
+ /** 是否已经完成初始化(用于 init 幂等 / destroy 配对) */
85
+ private __initialized;
86
+ /**
87
+ * 从 init 入参解析出 canvas 元素。
88
+ * 支持:HTMLCanvasElement、CanvasRenderingContext2D;解析不出则返回 null。
89
+ */
90
+ private __resolveCanvasEl;
91
+ /**
92
+ * @param ctx DOM id、HTMLCanvasElement 或 CanvasRenderingContext2D
93
+ * @param options 渲染配置。renderMode: 'dirty-rect'(默认) | 'full'
94
+ *
95
+ * 幂等:同一个 ICE 实例重复 init 到同一个 canvas 时直接返回自身。
96
+ * React StrictMode 下 effect 会被执行两次,幂等可以避免重复挂载 Manager / 重复绑定全局事件。
97
+ * 若要换一个 canvas,请先调用 destroy()。
98
+ */
99
+ init(ctx: any, options?: {
100
+ renderMode?: 'full' | 'dirty-rect';
101
+ dpr?: number;
102
+ }): this;
103
+ /**
104
+ * @method destroy 销毁当前实例
105
+ *
106
+ * 与 init() 配对:停止所有 Manager、解绑 canvas 上的原生事件、注销全局事件总线(FrameManager / DOMEventInterceptor 都是全局单例,必须显式注销)。
107
+ * 销毁之后可以再次 init(例如 React 组件重新挂载),不会累积监听或帧循环。
108
+ */
109
+ destroy(): void;
110
+ /**
111
+ * @method addChild
112
+ * 添加交互工具组件。
113
+ * 工具组件不触发事件,不产生动画效果。
114
+ * @param {ICEComponent} tool
115
+ */
116
+ addTool(tool: ICEComponent): void;
117
+ /**
118
+ * @methos removeTool
119
+ * 删除交互工具组件。
120
+ * 工具组件不触发事件,不产生动画效果。
121
+ * @param tool
122
+ */
123
+ removeTool(tool: ICEComponent): void;
124
+ /**
125
+ *
126
+ * 调用 ICE.addChild() 方法,会直接把对象画在 canvas 上。
127
+ * 如果需要在容器中画组件,参见 @see ICEGroup.addChild() 方法
128
+ *
129
+ * @param component
130
+ */
131
+ addChild(component: any, markDirty?: boolean): void;
132
+ addChildren(arr: Array<ICEComponent>): void;
133
+ removeChild(component: ICEComponent, markDirty?: boolean): void;
134
+ removeChildren(arr: Array<ICEComponent>): void;
135
+ clearAll(): void;
136
+ /**
137
+ * 按 id 查找组件。
138
+ *
139
+ * 查找范围:**先查顶层 `childNodes`**(同 id 时顶层优先,保持既有优先级),再深度优先递归整棵
140
+ * 子树。「连线连接嵌套子组件」依赖本方法(`ICEPolyLine.syncConnections` → 本方法)。
141
+ *
142
+ * **工具层 `toolNodes` 不参与查找**:工具是 UI 覆盖层(变换/连线手柄等),不应成为连线端点。
143
+ *
144
+ * 历史:早期只搜第一层,嵌套场景连线会静默失效;中途曾尝试放开递归但被回退 ——
145
+ * 当时表现为 `dirty-rect-pixel` 富场景 step1 约 900 px 差异,看起来像「连线端点推导与局部重绘
146
+ * 冲突」,实际根因是**折线的包围盒是退化的**(`state.width ≈ 0`),导致 dirty-rect 按快照盒
147
+ * 挑选重画对象时漏掉折线(擦除区域内的折线笔迹丢失)。该根因已修(见 `ICEComponent.__localBox`
148
+ * 与 `ICEPolyLine.calcComponentParams`),因此递归可以放开。
149
+ */
150
+ findComponent(id: string): any;
151
+ /** 深度优先查找子树(不含工具层)。 */
152
+ private __findComponentInTree;
153
+ set dirty(flag: boolean);
154
+ get dirty(): boolean;
155
+ /**
156
+ * @method registerType 注册组件类型
157
+ *
158
+ * - 需要在反序列化之前调用,否则无法反序列化。
159
+ * - ICE 内置的类型已经自动注册,不需要手动注册。
160
+ *
161
+ * @param className
162
+ * @param Clazz
163
+ */
164
+ registerType(className: string, Clazz: new (...args: any[]) => any): void;
165
+ /**
166
+ * 由构造函数反查稳定的类型名(序列化用)。
167
+ *
168
+ * - 已注册的类型:返回注册名(与类的 JS 名解耦,压缩改名不影响已存数据)
169
+ * - 未注册:返回 undefined,调用方回退到 `constructor.name`(保持既有行为)
170
+ * - 同一个构造函数注册了多个名字时,**先注册的优先**(内置类型因此不会被别名顶掉)
171
+ */
172
+ getTypeId(Clazz: new (...args: any[]) => any): string | undefined;
173
+ /**
174
+ * 注册插件(幂等:同名插件重复调用直接返回,不重复 setup)。
175
+ *
176
+ * 插件可提供三层扩展点:`components`(自定义图元类型)、`render`(每帧绘制回调)、
177
+ * `tools`(按选中组件匹配的交互工具)。详见 `src/plugin/PluginHost.ts`。
178
+ *
179
+ * @returns 是否本次真的注册(同名已存在时为 false)
180
+ */
181
+ use(plugin: ICEPlugin): boolean;
182
+ /**
183
+ * 注销插件:撤销其渲染回调与交互工具,并调用 `teardown`。
184
+ * 注意:`components` 里注册的类型**保留**(反序列化可能仍依赖,且撤销会让已存数据失效)。
185
+ */
186
+ unuse(name: string): boolean;
187
+ /** 已注册插件名(只读快照)。 */
188
+ getPlugins(): string[];
189
+ /**
190
+ * 更新选中集合的**统一入口**:写 `selectionList` 并同步插件工具。
191
+ * 约定:目前插件工具按「首个选中组件」匹配(引擎当前也仅支持单选)。
192
+ *
193
+ * @returns 是否有「排他」插件工具命中 —— 调用方据此禁用内置变换/连线面板
194
+ */
195
+ setSelection(components: Array<any> | any | null): boolean;
196
+ /**
197
+ * 无障碍:取「可访问节点快照」,供应用层渲染隐藏 DOM 镜像(screen reader / 键盘导航)。
198
+ *
199
+ * 引擎**不**自建 DOM 镜像层 —— 镜像的 DOM 结构、ARIA 属性、文案与焦点环高度依赖具体产品语义。
200
+ * 引擎负责给出:id / 角色建议 / 可读名称 / **屏幕坐标盒(CSS 像素)** / 层级 / tab 顺序 / 选中态;
201
+ * 应用层据此渲染 `<div role="img" aria-label=... style="position:absolute; ...">` 之类的镜像元素,
202
+ * 并用 `setFocusedComponent()` 把 DOM 焦点映射回组件。
203
+ *
204
+ * 不含未上屏(无有效变换矩阵)的组件,也不会修改任何组件 state。
205
+ */
206
+ getAccessibilityTree(options?: ICEAccessibilityOptions): ICEAccessibleNode[];
207
+ /**
208
+ * 设置键盘事件的焦点组件(无障碍 / 键盘导航原语)。
209
+ *
210
+ * 未设置时维持既有行为:键盘事件派发给「上次点击命中的组件」。
211
+ * 传入 id 字符串或组件实例;传 null / undefined 清除焦点。
212
+ */
213
+ setFocusedComponent(component: any | string | null): this;
214
+ /** 当前键盘焦点组件(未设置时为 null)。 */
215
+ getFocusedComponent(): any;
216
+ /**
217
+ * @method getType 获取组件构造函数
218
+ * @param className
219
+ * @returns
220
+ */
221
+ getType(className: string): any;
222
+ /**
223
+ * 加载自定义字体(平台适配):浏览器走 FontFace API,小程序走 wx.loadFont。
224
+ * 加载后,在 ICEText 的 style.fontFamily 里引用该字体名即可。
225
+ * @param family 字体族名(如 'MyFont')
226
+ * @param source 字体源(浏览器为 url/二进制,小程序为本地文件路径)
227
+ */
228
+ loadFont(family: string, source: string): Promise<any>;
229
+ /**
230
+ * 切换主题(string 按名切换 / object 浅合并 semantic),预设样式(preset)会自动跟随主题变量。
231
+ * 热切换:已渲染的组件里用了 preset 的会重新 resolve(用户显式传的样式优先)。
232
+ */
233
+ setTheme(theme: string | Partial<ICESemanticTheme>): this;
234
+ /**
235
+ * 设置视口(视图缩放 + 平移)。
236
+ *
237
+ * 屏幕坐标 = 世界坐标 * scale + translate。这是「视图缩放」,不改变任何组件的 state,
238
+ * 只影响渲染结果与命中检测的坐标换算。视口变化会让渲染器回退一次全量重绘并重建快照。
239
+ */
240
+ setViewport(scale: number, tx?: number, ty?: number): this;
241
+ /** 屏幕坐标(canvas 像素)→ 世界坐标(受视口逆变换)。 */
242
+ screenToWorld(sx: number, sy: number): [number, number];
243
+ /** 世界坐标 → 屏幕坐标(canvas 像素)。 */
244
+ worldToScreen(wx: number, wy: number): [number, number];
245
+ /**
246
+ * 刷新 canvas 的 getBoundingClientRect 缓存并返回。
247
+ *
248
+ * 输入事件用它把屏幕坐标换算成 canvas 内坐标;页面滚动 / 布局变化后必须刷新,
249
+ * 否则命中检测会整体偏移(旧实现只在 init 时取一次,滚动后即失效)。
250
+ * 高频的移动类事件复用缓存,见 DOMEventDispatcher.__resolveCanvasRect。
251
+ */
252
+ /**
253
+ * 渲染用视口 = dpr · viewport(仅「往画布上画」这一侧需要乘 dpr)。
254
+ * dpr === 1 时**直接返回 viewport 本身**:零分配、且与既有行为逐字节一致。
255
+ */
256
+ getRenderViewport(): {
257
+ scale: number;
258
+ tx: number;
259
+ ty: number;
260
+ };
261
+ /**
262
+ * 把 canvas 的 backing store 放大到 cssSize * dpr,并把 CSS 尺寸固定为逻辑尺寸。
263
+ * 只有传了 dpr>1 才会调用。
264
+ */
265
+ private __applyDevicePixelRatio;
266
+ updateCanvasBoundingRect(): any;
267
+ /**
268
+ * 读取 canvas 内容盒:把 border-box 的 rect 补偿成「绘制区」的偏移与尺寸。
269
+ * 无 getComputedStyle 的运行时(如小程序)补偿为 0,退回 rect 原值。
270
+ */
271
+ private __readContentBox;
272
+ /**
273
+ * 供输入派发器做坐标换算的矩形:**内容盒左上角**。
274
+ * 这样 `clientX - left` 就落在绘制区坐标里,与旧实现(offsetX)语义一致,不受 border/padding 影响。
275
+ */
276
+ getInputRect(): any;
277
+ /**
278
+ * 以屏幕点为锚点缩放视口(滚轮缩放 / 双指缩放可用的引擎原语)。
279
+ *
280
+ * 保持锚点下的世界坐标在缩放前后落在同一屏幕位置:先取锚点对应的世界坐标,
281
+ * 换算新 scale 后反解 translate。只改视口状态,**不修改任何组件的 state**
282
+ * (与 setViewport 同一约束)。
283
+ *
284
+ * 用法(应用层接滚轮,一行即可):
285
+ * ```js
286
+ * ice.evtBus.on('wheel', (e) => {
287
+ * ice.zoomAt(e.offsetX, e.offsetY, e.deltaY < 0 ? 1.1 : 1 / 1.1);
288
+ * });
289
+ * ```
290
+ *
291
+ * @param screenX 锚点屏幕 x(canvas 像素,通常是鼠标 / 触摸位置)
292
+ * @param screenY 锚点屏幕 y
293
+ * @param factor 缩放倍数,>1 放大、<1 缩小;非正数或非有限值直接忽略
294
+ * @param minScale 最小 scale(默认 0.05)
295
+ * @param maxScale 最大 scale(默认 20)
296
+ */
297
+ zoomAt(screenX: number, screenY: number, factor: number, minScale?: number, maxScale?: number): this;
298
+ /**
299
+ * 命中检测:屏幕坐标(canvas 像素)→ 命中的最上层可交互组件;无命中返回 null。
300
+ * 供应用层做「空白处拖拽平移 / 点击命中」等视口交互。
301
+ */
302
+ hitTest(sx: number, sy: number): any;
303
+ /**
304
+ * 注册命名主题(运行时注入,如多品牌 / 多租户 / 暗色主题)。
305
+ */
306
+ registerTheme(name: string, theme: ICETheme): this;
307
+ /**
308
+ * 获取当前主题对象({ base, semantic })。返回的是**本实例**的主题。
309
+ */
310
+ getTheme(): ICETheme;
311
+ /**
312
+ * 遍历组件树,对每个用了 preset 的组件重新 resolve preset(主题热切换)。
313
+ */
314
+ private __reapplyPresets;
315
+ /**
316
+ * 创建线性渐变对象,供组件 style.fillStyle/strokeStyle 使用。
317
+ * 用法:const g = ice.createLinearGradient(0,0,100,0); g.addColorStop(0,'red'); g.addColorStop(1,'blue');
318
+ * new ICERect({ style: { fillStyle: g } })
319
+ */
320
+ createLinearGradient(x0: number, y0: number, x1: number, y1: number): any;
321
+ /**
322
+ * 创建径向(圆形)渐变对象。
323
+ */
324
+ createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): any;
325
+ /**
326
+ * 创建锥形渐变(较新 API,Chrome 99+),不支持的环境返回 null。
327
+ */
328
+ createConicGradient(startAngle: number, x: number, y: number): any;
329
+ /**
330
+ * 创建图案填充(用图片平铺),供 style.fillStyle/strokeStyle 使用。
331
+ * @param image 图片源(HTMLImageElement/canvas 等)
332
+ * @param repetition 'repeat'|'repeat-x'|'repeat-y'|'no-repeat'
333
+ */
334
+ createPattern(image: any, repetition: string): any;
335
+ /**
336
+ * 读取画布指定区域的像素数据(取色、滤镜、橡皮擦等)。
337
+ */
338
+ getImageData(x: number, y: number, w: number, h: number): any;
339
+ /**
340
+ * 写入像素数据到画布。
341
+ */
342
+ putImageData(imageData: any, x: number, y: number): void;
343
+ createImageData(w: number, h: number): any;
344
+ /**
345
+ * 把画布导出为 dataURL(默认 PNG)。type 如 'image/png'/'image/jpeg',quality 0~1(jpeg)。
346
+ */
347
+ toDataURL(type?: string, quality?: number): string;
348
+ /**
349
+ * 把画布导出为 Blob(回调接收)。
350
+ */
351
+ toBlob(callback: (blob: Blob | null) => void, type?: string, quality?: number): void;
352
+ /**
353
+ * 把对象序列化成 JSON 字符串:
354
+ * - 容器型组件需要负责子节点的序列化操作
355
+ * - 如果组件不需要序列化,需要返回 null
356
+ * @returns Object
357
+ */
358
+ toJSONString(): string;
359
+ /**
360
+ * 把对象序列化成 JSON 对象:
361
+ * - 容器型组件需要负责子节点的序列化操作
362
+ * - 如果组件不需要序列化,需要返回 null
363
+ * @returns Object
364
+ */
365
+ toJSONObject(): object;
366
+ fromJSONObject(jsonObject: any): void;
367
+ fromJSONString(jsonStr: string): void;
368
+ }
369
+ export default ICE;
@@ -0,0 +1,46 @@
1
+ /** 可访问节点的角色建议(应用层可映射为 role / 元素类型)。 */
2
+ export type ICEAccessibleRole = 'graphic' | 'container' | 'link' | 'text' | 'image' | 'tool';
3
+ export interface ICEAccessibleNode {
4
+ /** 组件 id(`props.id`) */
5
+ id: string;
6
+ /** 角色建议 */
7
+ role: ICEAccessibleRole;
8
+ /** 可读名称:优先 `state.ariaLabel`,其次文本内容,最后回退 id */
9
+ label: string;
10
+ /** 屏幕坐标盒(CSS 像素,已含视口换算),应用层可直接用于绝对定位 */
11
+ box: {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ };
17
+ /** 在 canvas 内是否可见(`display !== false`) */
18
+ visible: boolean;
19
+ /** 是否参与交互(`interactive`)——决定 DOM 上是否可点击/可聚焦 */
20
+ interactive: boolean;
21
+ /** 是否建议可聚焦(可见 + 可交互) */
22
+ focusable: boolean;
23
+ /** 建议的 tab 顺序(按 zIndex 升序,从 0 开始) */
24
+ tabIndex: number;
25
+ /** 是否当前被选中 */
26
+ selected: boolean;
27
+ /** 树层级(根为 1) */
28
+ level: number;
29
+ /** 父组件 id(顶层为 null) */
30
+ parentId: string | null;
31
+ }
32
+ export interface ICEAccessibilityOptions {
33
+ /** 是否包含工具层(控制面板等)。默认 false —— 工具层通常不应出现在无障碍树里。 */
34
+ includeTools?: boolean;
35
+ /** 是否包含不可见组件。默认 false。 */
36
+ includeHidden?: boolean;
37
+ /** 只保留该谓词返回 true 的组件(在其它过滤之后应用)。 */
38
+ filter?: (component: any) => boolean;
39
+ }
40
+ /**
41
+ * 构建可访问节点快照。
42
+ *
43
+ * 顺序:按「树深度优先 + 同级 zIndex 升序」,与视觉堆叠顺序一致(应用可据此生成 tab 顺序)。
44
+ * 不含未上屏(无有效变换矩阵)的组件。
45
+ */
46
+ export declare function buildAccessibilityTree(ice: any, options?: ICEAccessibilityOptions): ICEAccessibleNode[];
@@ -0,0 +1,46 @@
1
+ /** 可访问节点的角色建议(应用层可映射为 role / 元素类型)。 */
2
+ export type ICEAccessibleRole = 'graphic' | 'container' | 'link' | 'text' | 'image' | 'tool';
3
+ export interface ICEAccessibleNode {
4
+ /** 组件 id(`props.id`) */
5
+ id: string;
6
+ /** 角色建议 */
7
+ role: ICEAccessibleRole;
8
+ /** 可读名称:优先 `state.ariaLabel`,其次文本内容,最后回退 id */
9
+ label: string;
10
+ /** 屏幕坐标盒(CSS 像素,已含视口换算),应用层可直接用于绝对定位 */
11
+ box: {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ };
17
+ /** 在 canvas 内是否可见(`display !== false`) */
18
+ visible: boolean;
19
+ /** 是否参与交互(`interactive`)——决定 DOM 上是否可点击/可聚焦 */
20
+ interactive: boolean;
21
+ /** 是否建议可聚焦(可见 + 可交互) */
22
+ focusable: boolean;
23
+ /** 建议的 tab 顺序(按 zIndex 升序,从 0 开始) */
24
+ tabIndex: number;
25
+ /** 是否当前被选中 */
26
+ selected: boolean;
27
+ /** 树层级(根为 1) */
28
+ level: number;
29
+ /** 父组件 id(顶层为 null) */
30
+ parentId: string | null;
31
+ }
32
+ export interface ICEAccessibilityOptions {
33
+ /** 是否包含工具层(控制面板等)。默认 false —— 工具层通常不应出现在无障碍树里。 */
34
+ includeTools?: boolean;
35
+ /** 是否包含不可见组件。默认 false。 */
36
+ includeHidden?: boolean;
37
+ /** 只保留该谓词返回 true 的组件(在其它过滤之后应用)。 */
38
+ filter?: (component: any) => boolean;
39
+ }
40
+ /**
41
+ * 构建可访问节点快照。
42
+ *
43
+ * 顺序:按「树深度优先 + 同级 zIndex 升序」,与视觉堆叠顺序一致(应用可据此生成 tab 顺序)。
44
+ * 不含未上屏(无有效变换矩阵)的组件。
45
+ */
46
+ export declare function buildAccessibilityTree(ice: any, options?: ICEAccessibilityOptions): ICEAccessibleNode[];
@@ -0,0 +1,96 @@
1
+ import ICEComponent from '../graphic/ICEComponent.mjs';
2
+ import ICE from '../ICE.mjs';
3
+ /**
4
+ * @class AnimationManager
5
+ *
6
+ * 动画管理器
7
+ *
8
+ * - 全局单例,一个 ICE 实例上只能有一个 AnimationManager 的实例。
9
+ *
10
+ * @singleton
11
+ * @see ICE
12
+ * @author 大漠穷秋<damoqiongqiu@126.com>
13
+ */
14
+ declare class AnimationManager {
15
+ private animationMap;
16
+ private ice;
17
+ private paused;
18
+ private pausedAt;
19
+ private warned;
20
+ constructor(ice: ICE);
21
+ start(): this;
22
+ stop(): this;
23
+ private frameEventHandler;
24
+ /**
25
+ * 把值按点路径写入目标对象(支持 `transform.rotate` / `style.globalAlpha` 这类嵌套字段)。
26
+ *
27
+ * 旧实现直接 `newState[key] = value`,键里的点会被当成**字面量键名**,
28
+ * 于是 `animations: { 'transform.rotate': ... }` 静默失效(既不报错也不生效)。
29
+ * 多段路径共用同一父级时会逐段合并(`transform.rotate` 与 `transform.scale` 不互相覆盖)。
30
+ */
31
+ private __writeValue;
32
+ /**
33
+ * 每一帧推进动画:计算各属性的取值。
34
+ *
35
+ * 支持三种配置形态(同一组件上可混用):
36
+ * 1. 单段补间:`{ from, to, duration }`
37
+ * 2. 关键帧时间轴:`{ keyframes: [{ offset, value, easing? }], duration }`
38
+ * - `offset` 为 0~1 的时间占比,缺省时按数组顺序均分,超出 [0,1] 会被夹紧;
39
+ * - `easing` 写在**段起始关键帧**上,作用于「该帧 → 下一帧」这一段;未写则用动画级 `easing`;
40
+ * - 时间轴之外的取值分别是首帧 / 末帧的值(保持,不外推)。
41
+ * 3. 缓动可用主题 motion token 语义名(`duration: 'normal'` / `easing: 'out'`)或 EasingProgress 方法名。
42
+ *
43
+ * 取值可以是**数值**,也可以是**等长的数字数组**(`transform.scale` / `transform.translate` /
44
+ * `transform.skew` 等逐元素补间)。
45
+ *
46
+ * 结束判定按**已流逝时间**而非「值是否越过 to」:弹簧类缓动中途会过冲(越过 to 再回落),
47
+ * 若按值判定,第一帧过冲就会被误判成结束、动画提前停在过冲点上。
48
+ */
49
+ private tween;
50
+ /** 取进度 p 处的值:单段在 from→to 之间插值;关键帧按段插值(段内进度再经该段缓动)。 */
51
+ private __sampleValue;
52
+ /** 按进度 p 在 from/to 之间插值:数值直接线性,等长数字数组逐元素。 */
53
+ private __interpolate;
54
+ /** 补间取值是否合法:都是数字,或都是**等长**的数字数组。 */
55
+ private __isTweenable;
56
+ /** 取值种类:number | array(非空且全为数字) | null(不支持)。 */
57
+ private __valueKind;
58
+ /** 归一化关键帧到 animation.__frames(只做一次):夹紧 offset、排序、校验各帧取值同型。 */
59
+ private __normalizeKeyframes;
60
+ /** 解析缓动名 → 归一化进度函数;未知名称回退 linear 并只提示一次。 */
61
+ private __easingFn;
62
+ /** round: true 时对补间结果取整(数组逐元素)。 */
63
+ private __roundIfNeeded;
64
+ /** 供告警信息使用的取值描述。 */
65
+ private __describe;
66
+ /** 拒绝一个非法的动画配置:标记结束(不再每帧重试)并只提示一次。 */
67
+ private __reject;
68
+ /** 同一个动画配置只告警一次,避免非法配置每帧刷屏。 */
69
+ private __warnOnce;
70
+ /**
71
+ * 把动画配置里的 motion token 语义名解析成实际值(首次触发时执行,结果写回 animation 对象缓存):
72
+ * - duration: 'fast' | 'normal' | 'slow' | 'slower' → 主题 motion.duration 里的 ms。
73
+ * - easing: 'linear' | 'out' | 'inOut' | 'outQuart' | 'spring' | 'springSoft' | 'springSnappy'
74
+ * → 主题 motion.easing 里的缓动方法名。
75
+ * 若传的是数字/已存在的 Easing 方法名,则原样保留(向后兼容)。
76
+ */
77
+ private __resolveMotion;
78
+ /**
79
+ * 判断动画到达终点后是否重复播放:
80
+ * - loop === true:无限循环;
81
+ * - iterationCount > 1:剩余次数递减,直到 1 次后结束。
82
+ */
83
+ private shouldRepeat;
84
+ /**
85
+ * 暂停所有动画(冻结进度,恢复时从暂停处继续)。
86
+ */
87
+ pause(): void;
88
+ /**
89
+ * 恢复所有动画:把每个动画的 startTime 往后移,抵消暂停期间的流逝。
90
+ */
91
+ resume(): void;
92
+ isPaused(): boolean;
93
+ add(component: ICEComponent): void;
94
+ remove(el: any): void;
95
+ }
96
+ export default AnimationManager;