ice-render 1.4.1 → 1.4.3
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.
- package/README.md +39 -0
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/index.umd.js +3 -3
- package/dist/types/ICE.d.mts +36 -0
- package/dist/types/ICE.d.ts +36 -0
- package/dist/types/cross-platform/Path2DRecorder.d.mts +76 -0
- package/dist/types/cross-platform/Path2DRecorder.d.ts +76 -0
- package/dist/types/cross-platform/PolyfillPath2D.d.mts +8 -18
- package/dist/types/cross-platform/PolyfillPath2D.d.ts +8 -18
- package/dist/types/export/SvgExporter.d.mts +54 -0
- package/dist/types/export/SvgExporter.d.ts +54 -0
- package/dist/types/graphic/ICEComponent.d.mts +31 -1
- package/dist/types/graphic/ICEComponent.d.ts +31 -1
- package/dist/types/graphic/ICEPath.d.mts +7 -0
- package/dist/types/graphic/ICEPath.d.ts +7 -0
- package/dist/types/graphic/text/ICEText.d.mts +21 -0
- package/dist/types/graphic/text/ICEText.d.ts +21 -0
- package/dist/types/index.d.mts +2 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +2 -2
package/dist/types/ICE.d.mts
CHANGED
|
@@ -9,6 +9,7 @@ import Deserializer from './persistence/Deserializer.mjs';
|
|
|
9
9
|
import Serializer from './persistence/Serializer.mjs';
|
|
10
10
|
import PluginHost, { ICEPlugin } from './plugin/PluginHost.mjs';
|
|
11
11
|
import { ICEAccessibleNode, ICEAccessibilityOptions } from './a11y/accessibility.mjs';
|
|
12
|
+
import type { SvgExportOptions, SvgExportResult } from './export/SvgExporter.mjs';
|
|
12
13
|
import ImageCache from './util/ImageCache.mjs';
|
|
13
14
|
import { ICETheme, ICESemanticTheme } from './theme/ICETheme.mjs';
|
|
14
15
|
/**
|
|
@@ -349,6 +350,41 @@ declare class ICE {
|
|
|
349
350
|
* 把画布导出为 Blob(回调接收)。
|
|
350
351
|
*/
|
|
351
352
|
toBlob(callback: (blob: Blob | null) => void, type?: string, quality?: number): void;
|
|
353
|
+
/**
|
|
354
|
+
* 把当前场景导出为 **SVG 矢量图**。
|
|
355
|
+
*
|
|
356
|
+
* 与 `toDataURL()` / `toBlob()` 的区别:那是画布的**光栅快照**(分辨率写死、缩放后糊),
|
|
357
|
+
* 这是从组件树 + 路径命令流重新生成的**矢量描述** —— 可以任意放大、丢进 Illustrator/Figma、
|
|
358
|
+
* 直接进打印/PDF 流程,也能在 Node 里生成(不需要 canvas)。
|
|
359
|
+
*
|
|
360
|
+
* 口径与画布渲染一致(顺序、矩阵、样式合并、有效透明度、祖先裁剪),细节与限制见
|
|
361
|
+
* `export/SvgExporter.ts` 的文件头。
|
|
362
|
+
*
|
|
363
|
+
* ```js
|
|
364
|
+
* const svg = ice.toSvg(); // 内容自适应、透明背景
|
|
365
|
+
* const svg = ice.toSvg({ background: '#fff', padding: 16 }); // 白底 + 留白
|
|
366
|
+
* const svg = ice.toSvg({ area: 'viewport' }); // 当前视口所见即所得
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
toSvg(options?: SvgExportOptions): string;
|
|
370
|
+
/**
|
|
371
|
+
* 创建一个**不依赖 canvas 的 ICE 实例**:服务端出图 / 无头批处理的入口。
|
|
372
|
+
*
|
|
373
|
+
* 它和 `init()` 出来的实例共用同一套组件树、矩阵、样式与导出逻辑,只是没有渲染器、
|
|
374
|
+
* 没有输入派发、也没有 rAF 帧循环 —— 因此能在 Node 里 `new` 完就 `addChild` + `toSvg()`。
|
|
375
|
+
*
|
|
376
|
+
* ```js
|
|
377
|
+
* const ice = ICE.headless();
|
|
378
|
+
* ice.addChild(new ICERect({ width: 100, height: 50, style: { fillStyle: '#4f46e5' } }));
|
|
379
|
+
* const svg = ice.toSvg();
|
|
380
|
+
* ```
|
|
381
|
+
*
|
|
382
|
+
* 注意:没有渲染循环,意味着**派生几何**(折线的点、文本的换行行)由导出器在导出时刷新
|
|
383
|
+
* (见 SvgExporter 里的 refreshParams/ensurePathBuilt),而不是靠帧循环。
|
|
384
|
+
*/
|
|
385
|
+
static headless(): ICE;
|
|
386
|
+
/** 同 `toSvg()`,但额外返回计算出的画布尺寸(写文件 / 布局预览要用的宽高) */
|
|
387
|
+
toSvgResult(options?: SvgExportOptions): SvgExportResult;
|
|
352
388
|
/**
|
|
353
389
|
* 把对象序列化成 JSON 字符串:
|
|
354
390
|
* - 容器型组件需要负责子节点的序列化操作
|
package/dist/types/ICE.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import Deserializer from './persistence/Deserializer';
|
|
|
9
9
|
import Serializer from './persistence/Serializer';
|
|
10
10
|
import PluginHost, { ICEPlugin } from './plugin/PluginHost';
|
|
11
11
|
import { ICEAccessibleNode, ICEAccessibilityOptions } from './a11y/accessibility';
|
|
12
|
+
import type { SvgExportOptions, SvgExportResult } from './export/SvgExporter';
|
|
12
13
|
import ImageCache from './util/ImageCache';
|
|
13
14
|
import { ICETheme, ICESemanticTheme } from './theme/ICETheme';
|
|
14
15
|
/**
|
|
@@ -349,6 +350,41 @@ declare class ICE {
|
|
|
349
350
|
* 把画布导出为 Blob(回调接收)。
|
|
350
351
|
*/
|
|
351
352
|
toBlob(callback: (blob: Blob | null) => void, type?: string, quality?: number): void;
|
|
353
|
+
/**
|
|
354
|
+
* 把当前场景导出为 **SVG 矢量图**。
|
|
355
|
+
*
|
|
356
|
+
* 与 `toDataURL()` / `toBlob()` 的区别:那是画布的**光栅快照**(分辨率写死、缩放后糊),
|
|
357
|
+
* 这是从组件树 + 路径命令流重新生成的**矢量描述** —— 可以任意放大、丢进 Illustrator/Figma、
|
|
358
|
+
* 直接进打印/PDF 流程,也能在 Node 里生成(不需要 canvas)。
|
|
359
|
+
*
|
|
360
|
+
* 口径与画布渲染一致(顺序、矩阵、样式合并、有效透明度、祖先裁剪),细节与限制见
|
|
361
|
+
* `export/SvgExporter.ts` 的文件头。
|
|
362
|
+
*
|
|
363
|
+
* ```js
|
|
364
|
+
* const svg = ice.toSvg(); // 内容自适应、透明背景
|
|
365
|
+
* const svg = ice.toSvg({ background: '#fff', padding: 16 }); // 白底 + 留白
|
|
366
|
+
* const svg = ice.toSvg({ area: 'viewport' }); // 当前视口所见即所得
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
toSvg(options?: SvgExportOptions): string;
|
|
370
|
+
/**
|
|
371
|
+
* 创建一个**不依赖 canvas 的 ICE 实例**:服务端出图 / 无头批处理的入口。
|
|
372
|
+
*
|
|
373
|
+
* 它和 `init()` 出来的实例共用同一套组件树、矩阵、样式与导出逻辑,只是没有渲染器、
|
|
374
|
+
* 没有输入派发、也没有 rAF 帧循环 —— 因此能在 Node 里 `new` 完就 `addChild` + `toSvg()`。
|
|
375
|
+
*
|
|
376
|
+
* ```js
|
|
377
|
+
* const ice = ICE.headless();
|
|
378
|
+
* ice.addChild(new ICERect({ width: 100, height: 50, style: { fillStyle: '#4f46e5' } }));
|
|
379
|
+
* const svg = ice.toSvg();
|
|
380
|
+
* ```
|
|
381
|
+
*
|
|
382
|
+
* 注意:没有渲染循环,意味着**派生几何**(折线的点、文本的换行行)由导出器在导出时刷新
|
|
383
|
+
* (见 SvgExporter 里的 refreshParams/ensurePathBuilt),而不是靠帧循环。
|
|
384
|
+
*/
|
|
385
|
+
static headless(): ICE;
|
|
386
|
+
/** 同 `toSvg()`,但额外返回计算出的画布尺寸(写文件 / 布局预览要用的宽高) */
|
|
387
|
+
toSvgResult(options?: SvgExportOptions): SvgExportResult;
|
|
352
388
|
/**
|
|
353
389
|
* 把对象序列化成 JSON 字符串:
|
|
354
390
|
* - 容器型组件需要负责子节点的序列化操作
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022 大漠穷秋.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @class Path2DRecorder
|
|
10
|
+
*
|
|
11
|
+
* 路径对象的**唯一入口**:一边把命令写给内存里的命令流,一边转发给运行时的原生 Path2D。
|
|
12
|
+
*
|
|
13
|
+
* 为什么需要它:原生 `Path2D` 是不透明的 —— 画得出来,但拿不到「这条路径到底是什么形状」。
|
|
14
|
+
* 而引擎的这几件事都需要**路径的几何描述**,不只是「画出来」:
|
|
15
|
+
*
|
|
16
|
+
* - 导出(SVG / 打印 / 服务端出图):要把路径转成 `d` 属性;
|
|
17
|
+
* - 服务端 / 小程序(无原生 Path2D):要靠命令流重放到 ctx(原先只有 PolyfillPath2D 能做到);
|
|
18
|
+
* - 测试与调试:可以直接断言「这个形状生成了哪几条命令」,不必截图比对像素。
|
|
19
|
+
*
|
|
20
|
+
* 设计取舍:
|
|
21
|
+
* - **有原生 Path2D 时仍然用原生对象上屏**(`native`),命令流只是顺带记录,渲染路径与旧版
|
|
22
|
+
* 完全一致;`ICEPath.doRender()` 用 `path2D.native || path2D` 取上屏对象。
|
|
23
|
+
* - **没有原生 Path2D 时**(小程序低版本 / Node)退化为纯记录器:`_isPolyfill` 为真,
|
|
24
|
+
* `ICEPath` 走「重放命令到 ctx」的老路径,行为与之前的 PolyfillPath2D 一致。
|
|
25
|
+
* - 路径是**几何变化时才重建**(`doRender` 只在 dirty 时调用 `createPathObject()`),因此
|
|
26
|
+
* 记录带来的开销只发生在路径重建时,不在每帧热路径上。
|
|
27
|
+
*
|
|
28
|
+
* 命令格式与 PolyfillPath2D 一致(也被 `replayPath()` 复用):
|
|
29
|
+
* `[['moveTo', x, y], ['rect', x, y, w, h], ...]`
|
|
30
|
+
*/
|
|
31
|
+
export default class Path2DRecorder {
|
|
32
|
+
/** 标记「没有原生 Path2D,需要重放命令」——与 PolyfillPath2D 的语义保持一致 */
|
|
33
|
+
_isPolyfill: boolean;
|
|
34
|
+
/** 记录的命令序列 */
|
|
35
|
+
_commands: Array<Array<any>>;
|
|
36
|
+
/** closePath 是幂等标记(doRender 每帧调用),不重复入队 */
|
|
37
|
+
_closed: boolean;
|
|
38
|
+
/** 原生 Path2D(有则上屏直接用它,命令流仍然记录);无则为 null */
|
|
39
|
+
readonly native: any;
|
|
40
|
+
/** 当前点(画布 arcTo / 圆弧的语义依赖它),[x, y];空表示没有当前子路径 */
|
|
41
|
+
private __current;
|
|
42
|
+
/** 当前子路径的起点(closePath 后当前点回到这里) */
|
|
43
|
+
private __subpathStart;
|
|
44
|
+
constructor(native?: any);
|
|
45
|
+
/** 上屏对象:有原生就用原生,否则用记录器自己(配合 replayPath 重放) */
|
|
46
|
+
get drawable(): any;
|
|
47
|
+
moveTo(x: number, y: number): void;
|
|
48
|
+
lineTo(x: number, y: number): void;
|
|
49
|
+
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
|
50
|
+
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
|
51
|
+
/**
|
|
52
|
+
* 圆角/切线圆弧。
|
|
53
|
+
*
|
|
54
|
+
* canvas 的 `arcTo` 依赖「当前点 + 控制点 + 半径」的切线关系,**SVG 没有对应命令**。
|
|
55
|
+
* 这里在记录阶段就把它**还原成 `lineTo(切点) + arc(圆心, 半径, 起止角)`**:
|
|
56
|
+
*
|
|
57
|
+
* - 出口是标准命令流,SVG 导出(以及任何重放到 ctx 的运行时)都不需要再懂 arcTo;
|
|
58
|
+
* - 原生 Path2D 收到的是等价的 lineTo/arc,渲染结果与直接 arcTo 一致;
|
|
59
|
+
* - 圆角矩形(ICERect 的 radius)就是靠它才能导出成真正的圆角,否则导出会变成切角。
|
|
60
|
+
*
|
|
61
|
+
* 数学:设 P0 = 当前点、P1 = 控制点、P2 = 终点,u = 单位(P0−P1)、v = 单位(P2−P1),
|
|
62
|
+
* 夹角 θ = ∠(u,v),切点到 P1 的距离 t = r / tan(θ/2),圆心在角平分线上距 P1 为 r / sin(θ/2)。
|
|
63
|
+
*/
|
|
64
|
+
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
|
65
|
+
rect(x: number, y: number, width: number, height: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* 圆弧。**必须实现**:事件圆等形状用的是 `arc`,此前 PolyfillPath2D 没有它,
|
|
68
|
+
* 于是「无原生 Path2D」的运行时(Node / 小程序低版本)画这类形状会直接抛
|
|
69
|
+
* `path.arc is not a function` —— 这正是服务端出图要修的第一件事。
|
|
70
|
+
*/
|
|
71
|
+
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
|
|
72
|
+
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: boolean): void;
|
|
73
|
+
closePath(): void;
|
|
74
|
+
/** 当前点(只读;调试与测试用) */
|
|
75
|
+
get currentPoint(): [number, number] | null;
|
|
76
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022 大漠穷秋.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @class Path2DRecorder
|
|
10
|
+
*
|
|
11
|
+
* 路径对象的**唯一入口**:一边把命令写给内存里的命令流,一边转发给运行时的原生 Path2D。
|
|
12
|
+
*
|
|
13
|
+
* 为什么需要它:原生 `Path2D` 是不透明的 —— 画得出来,但拿不到「这条路径到底是什么形状」。
|
|
14
|
+
* 而引擎的这几件事都需要**路径的几何描述**,不只是「画出来」:
|
|
15
|
+
*
|
|
16
|
+
* - 导出(SVG / 打印 / 服务端出图):要把路径转成 `d` 属性;
|
|
17
|
+
* - 服务端 / 小程序(无原生 Path2D):要靠命令流重放到 ctx(原先只有 PolyfillPath2D 能做到);
|
|
18
|
+
* - 测试与调试:可以直接断言「这个形状生成了哪几条命令」,不必截图比对像素。
|
|
19
|
+
*
|
|
20
|
+
* 设计取舍:
|
|
21
|
+
* - **有原生 Path2D 时仍然用原生对象上屏**(`native`),命令流只是顺带记录,渲染路径与旧版
|
|
22
|
+
* 完全一致;`ICEPath.doRender()` 用 `path2D.native || path2D` 取上屏对象。
|
|
23
|
+
* - **没有原生 Path2D 时**(小程序低版本 / Node)退化为纯记录器:`_isPolyfill` 为真,
|
|
24
|
+
* `ICEPath` 走「重放命令到 ctx」的老路径,行为与之前的 PolyfillPath2D 一致。
|
|
25
|
+
* - 路径是**几何变化时才重建**(`doRender` 只在 dirty 时调用 `createPathObject()`),因此
|
|
26
|
+
* 记录带来的开销只发生在路径重建时,不在每帧热路径上。
|
|
27
|
+
*
|
|
28
|
+
* 命令格式与 PolyfillPath2D 一致(也被 `replayPath()` 复用):
|
|
29
|
+
* `[['moveTo', x, y], ['rect', x, y, w, h], ...]`
|
|
30
|
+
*/
|
|
31
|
+
export default class Path2DRecorder {
|
|
32
|
+
/** 标记「没有原生 Path2D,需要重放命令」——与 PolyfillPath2D 的语义保持一致 */
|
|
33
|
+
_isPolyfill: boolean;
|
|
34
|
+
/** 记录的命令序列 */
|
|
35
|
+
_commands: Array<Array<any>>;
|
|
36
|
+
/** closePath 是幂等标记(doRender 每帧调用),不重复入队 */
|
|
37
|
+
_closed: boolean;
|
|
38
|
+
/** 原生 Path2D(有则上屏直接用它,命令流仍然记录);无则为 null */
|
|
39
|
+
readonly native: any;
|
|
40
|
+
/** 当前点(画布 arcTo / 圆弧的语义依赖它),[x, y];空表示没有当前子路径 */
|
|
41
|
+
private __current;
|
|
42
|
+
/** 当前子路径的起点(closePath 后当前点回到这里) */
|
|
43
|
+
private __subpathStart;
|
|
44
|
+
constructor(native?: any);
|
|
45
|
+
/** 上屏对象:有原生就用原生,否则用记录器自己(配合 replayPath 重放) */
|
|
46
|
+
get drawable(): any;
|
|
47
|
+
moveTo(x: number, y: number): void;
|
|
48
|
+
lineTo(x: number, y: number): void;
|
|
49
|
+
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
|
50
|
+
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
|
51
|
+
/**
|
|
52
|
+
* 圆角/切线圆弧。
|
|
53
|
+
*
|
|
54
|
+
* canvas 的 `arcTo` 依赖「当前点 + 控制点 + 半径」的切线关系,**SVG 没有对应命令**。
|
|
55
|
+
* 这里在记录阶段就把它**还原成 `lineTo(切点) + arc(圆心, 半径, 起止角)`**:
|
|
56
|
+
*
|
|
57
|
+
* - 出口是标准命令流,SVG 导出(以及任何重放到 ctx 的运行时)都不需要再懂 arcTo;
|
|
58
|
+
* - 原生 Path2D 收到的是等价的 lineTo/arc,渲染结果与直接 arcTo 一致;
|
|
59
|
+
* - 圆角矩形(ICERect 的 radius)就是靠它才能导出成真正的圆角,否则导出会变成切角。
|
|
60
|
+
*
|
|
61
|
+
* 数学:设 P0 = 当前点、P1 = 控制点、P2 = 终点,u = 单位(P0−P1)、v = 单位(P2−P1),
|
|
62
|
+
* 夹角 θ = ∠(u,v),切点到 P1 的距离 t = r / tan(θ/2),圆心在角平分线上距 P1 为 r / sin(θ/2)。
|
|
63
|
+
*/
|
|
64
|
+
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
|
65
|
+
rect(x: number, y: number, width: number, height: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* 圆弧。**必须实现**:事件圆等形状用的是 `arc`,此前 PolyfillPath2D 没有它,
|
|
68
|
+
* 于是「无原生 Path2D」的运行时(Node / 小程序低版本)画这类形状会直接抛
|
|
69
|
+
* `path.arc is not a function` —— 这正是服务端出图要修的第一件事。
|
|
70
|
+
*/
|
|
71
|
+
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
|
|
72
|
+
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: boolean): void;
|
|
73
|
+
closePath(): void;
|
|
74
|
+
/** 当前点(只读;调试与测试用) */
|
|
75
|
+
get currentPoint(): [number, number] | null;
|
|
76
|
+
}
|
|
@@ -5,27 +5,17 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
+
import Path2DRecorder from './Path2DRecorder.mjs';
|
|
8
9
|
/**
|
|
9
10
|
* @class PolyfillPath2D
|
|
10
11
|
*
|
|
11
|
-
* Path2D
|
|
12
|
-
*
|
|
12
|
+
* 「没有原生 Path2D」时的路径实现 —— 现在只是 `Path2DRecorder` 的别名:
|
|
13
|
+
* 记录器本身就是「无原生时退化为纯命令记录」的那个实现,两者再各写一份必然会漂移
|
|
14
|
+
* (历史上这里就少了 `arc`,导致小程序低版本 / Node 里画事件圆直接抛错)。
|
|
13
15
|
*
|
|
14
|
-
*
|
|
16
|
+
* 保留类名是为了不破坏既有 import 与测试里对它的引用。
|
|
17
|
+
*
|
|
18
|
+
* @deprecated 新代码请直接用 `Path2DRecorder`(或 `root.createPath2D()`)。
|
|
15
19
|
*/
|
|
16
|
-
export default class PolyfillPath2D {
|
|
17
|
-
/** 标记这是 polyfill,用于 ICEPath.doRender 区分原生 Path2D 与命令重放 */
|
|
18
|
-
_isPolyfill: boolean;
|
|
19
|
-
/** 记录的命令序列,如 [['rect', 0, 0, 10, 10], ['moveTo', 1, 1], ...] */
|
|
20
|
-
_commands: Array<Array<any>>;
|
|
21
|
-
/** closePath 是幂等标记(doRender 每帧调用),不重复入队 */
|
|
22
|
-
_closed: boolean;
|
|
23
|
-
moveTo(x: number, y: number): void;
|
|
24
|
-
lineTo(x: number, y: number): void;
|
|
25
|
-
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
|
26
|
-
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
|
27
|
-
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
|
28
|
-
rect(x: number, y: number, width: number, height: number): void;
|
|
29
|
-
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: boolean): void;
|
|
30
|
-
closePath(): void;
|
|
20
|
+
export default class PolyfillPath2D extends Path2DRecorder {
|
|
31
21
|
}
|
|
@@ -5,27 +5,17 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
+
import Path2DRecorder from './Path2DRecorder';
|
|
8
9
|
/**
|
|
9
10
|
* @class PolyfillPath2D
|
|
10
11
|
*
|
|
11
|
-
* Path2D
|
|
12
|
-
*
|
|
12
|
+
* 「没有原生 Path2D」时的路径实现 —— 现在只是 `Path2DRecorder` 的别名:
|
|
13
|
+
* 记录器本身就是「无原生时退化为纯命令记录」的那个实现,两者再各写一份必然会漂移
|
|
14
|
+
* (历史上这里就少了 `arc`,导致小程序低版本 / Node 里画事件圆直接抛错)。
|
|
13
15
|
*
|
|
14
|
-
*
|
|
16
|
+
* 保留类名是为了不破坏既有 import 与测试里对它的引用。
|
|
17
|
+
*
|
|
18
|
+
* @deprecated 新代码请直接用 `Path2DRecorder`(或 `root.createPath2D()`)。
|
|
15
19
|
*/
|
|
16
|
-
export default class PolyfillPath2D {
|
|
17
|
-
/** 标记这是 polyfill,用于 ICEPath.doRender 区分原生 Path2D 与命令重放 */
|
|
18
|
-
_isPolyfill: boolean;
|
|
19
|
-
/** 记录的命令序列,如 [['rect', 0, 0, 10, 10], ['moveTo', 1, 1], ...] */
|
|
20
|
-
_commands: Array<Array<any>>;
|
|
21
|
-
/** closePath 是幂等标记(doRender 每帧调用),不重复入队 */
|
|
22
|
-
_closed: boolean;
|
|
23
|
-
moveTo(x: number, y: number): void;
|
|
24
|
-
lineTo(x: number, y: number): void;
|
|
25
|
-
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
|
26
|
-
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
|
27
|
-
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
|
28
|
-
rect(x: number, y: number, width: number, height: number): void;
|
|
29
|
-
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: boolean): void;
|
|
30
|
-
closePath(): void;
|
|
20
|
+
export default class PolyfillPath2D extends Path2DRecorder {
|
|
31
21
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file SVG 导出
|
|
3
|
+
*
|
|
4
|
+
* 引擎的渲染是 canvas 光栅化的,但**几何描述一直都在**:`Path2DRecorder` 让每个路径组件都持有
|
|
5
|
+
* 自己的命令流(见 cross-platform/Path2DRecorder.ts),于是同一份场景可以再输出一份矢量。
|
|
6
|
+
*
|
|
7
|
+
* 导出器刻意**镜像渲染器的口径**,而不是另起一套:
|
|
8
|
+
* - 绘制顺序 = 渲染队列的顺序(`flattenTree` 后按 `state.zIndex` 稳定排序),工具层默认不导出;
|
|
9
|
+
* - 每个组件的变换 = `composeMatrix()`(本地 → 世界),整体再套一层「世界 → 视图」矩阵,
|
|
10
|
+
* 与 `applyTransformToCtx()` 的 `viewport · composed` 完全对应;
|
|
11
|
+
* - 填充/描边 = `state.fill` / `state.stroke` + `props.style` 与 `state.style` 合并后的键
|
|
12
|
+
* (state 覆盖 props,与 `applyStyleToCtx()` 同序);
|
|
13
|
+
* - 透明度 = `getEffectiveOpacity()`(自身 × 祖先),与画布的 `globalAlpha` 同一口径;
|
|
14
|
+
* - 裁剪 = 祖先链上所有 `clipChildren` 的世界包围盒,与 `__applyAncestorClips()` 一致。
|
|
15
|
+
*
|
|
16
|
+
* 已支持:任意 `ICEPath` 家族(矩形/圆角矩形/椭圆/自定义形状/折线/贝塞尔/组自身背景)、
|
|
17
|
+
* 文本(多行、水平/垂直对齐、换行后的行)、图片(含圆形裁剪)、线性/径向渐变、虚线、
|
|
18
|
+
* 视口或内容自适应尺寸、透明背景。
|
|
19
|
+
*
|
|
20
|
+
* 暂未支持(有意留白,都会在文档里写明):
|
|
21
|
+
* - 阴影(canvas 的 shadow* → SVG 需要 filter,且模糊半径语义不完全等价);
|
|
22
|
+
* - 雪碧图切图(`sx/sy/sw/sh`)与 `fillRule` 的奇偶填充差异;
|
|
23
|
+
* - 蚂蚁线动画(导出的是**静态瞬间**,只保留当前 dash 相位)。
|
|
24
|
+
*
|
|
25
|
+
* 文本的**字形度量**在 canvas 与 SVG 之间不可能逐像素一致(字体回退、行高、基线定义不同),
|
|
26
|
+
* 因此导出器用 `text-anchor` / `dominant-baseline` 表达对齐,而不是把测出来的宽度写死;
|
|
27
|
+
* 左对齐(默认)与画布逐字对齐,居中/右对齐按锚点对齐、宽度由渲染方自己定。
|
|
28
|
+
*/
|
|
29
|
+
export type SvgExportOptions = {
|
|
30
|
+
/** 导出范围:`content`(默认,按内容包围盒紧凑裁切)或 `viewport`(当前画布视口) */
|
|
31
|
+
area?: 'content' | 'viewport';
|
|
32
|
+
/** `area: 'content'` 时的四周留白,默认 0 */
|
|
33
|
+
padding?: number;
|
|
34
|
+
/** 缩放倍数,默认 1(内容模式下按世界尺寸 1:1) */
|
|
35
|
+
scale?: number;
|
|
36
|
+
/** 背景色;默认不铺背景(透明) */
|
|
37
|
+
background?: string | null;
|
|
38
|
+
/** 是否把工具层(控制面板、对齐辅助线)也导出,默认 false */
|
|
39
|
+
includeTools?: boolean;
|
|
40
|
+
/** 坐标保留小数位,默认 2(避免 `d` 属性里出现一长串浮点噪声) */
|
|
41
|
+
precision?: number;
|
|
42
|
+
};
|
|
43
|
+
export type SvgExportResult = {
|
|
44
|
+
svg: string;
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* 导出场景为 SVG 字符串。
|
|
50
|
+
*
|
|
51
|
+
* @param target ICE 实例(导出整幅画布)或任意组件(导出它的子树)
|
|
52
|
+
*/
|
|
53
|
+
export declare function exportSvg(target: any, options?: SvgExportOptions): string;
|
|
54
|
+
export declare function exportSvgResult(target: any, options?: SvgExportOptions): SvgExportResult;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file SVG 导出
|
|
3
|
+
*
|
|
4
|
+
* 引擎的渲染是 canvas 光栅化的,但**几何描述一直都在**:`Path2DRecorder` 让每个路径组件都持有
|
|
5
|
+
* 自己的命令流(见 cross-platform/Path2DRecorder.ts),于是同一份场景可以再输出一份矢量。
|
|
6
|
+
*
|
|
7
|
+
* 导出器刻意**镜像渲染器的口径**,而不是另起一套:
|
|
8
|
+
* - 绘制顺序 = 渲染队列的顺序(`flattenTree` 后按 `state.zIndex` 稳定排序),工具层默认不导出;
|
|
9
|
+
* - 每个组件的变换 = `composeMatrix()`(本地 → 世界),整体再套一层「世界 → 视图」矩阵,
|
|
10
|
+
* 与 `applyTransformToCtx()` 的 `viewport · composed` 完全对应;
|
|
11
|
+
* - 填充/描边 = `state.fill` / `state.stroke` + `props.style` 与 `state.style` 合并后的键
|
|
12
|
+
* (state 覆盖 props,与 `applyStyleToCtx()` 同序);
|
|
13
|
+
* - 透明度 = `getEffectiveOpacity()`(自身 × 祖先),与画布的 `globalAlpha` 同一口径;
|
|
14
|
+
* - 裁剪 = 祖先链上所有 `clipChildren` 的世界包围盒,与 `__applyAncestorClips()` 一致。
|
|
15
|
+
*
|
|
16
|
+
* 已支持:任意 `ICEPath` 家族(矩形/圆角矩形/椭圆/自定义形状/折线/贝塞尔/组自身背景)、
|
|
17
|
+
* 文本(多行、水平/垂直对齐、换行后的行)、图片(含圆形裁剪)、线性/径向渐变、虚线、
|
|
18
|
+
* 视口或内容自适应尺寸、透明背景。
|
|
19
|
+
*
|
|
20
|
+
* 暂未支持(有意留白,都会在文档里写明):
|
|
21
|
+
* - 阴影(canvas 的 shadow* → SVG 需要 filter,且模糊半径语义不完全等价);
|
|
22
|
+
* - 雪碧图切图(`sx/sy/sw/sh`)与 `fillRule` 的奇偶填充差异;
|
|
23
|
+
* - 蚂蚁线动画(导出的是**静态瞬间**,只保留当前 dash 相位)。
|
|
24
|
+
*
|
|
25
|
+
* 文本的**字形度量**在 canvas 与 SVG 之间不可能逐像素一致(字体回退、行高、基线定义不同),
|
|
26
|
+
* 因此导出器用 `text-anchor` / `dominant-baseline` 表达对齐,而不是把测出来的宽度写死;
|
|
27
|
+
* 左对齐(默认)与画布逐字对齐,居中/右对齐按锚点对齐、宽度由渲染方自己定。
|
|
28
|
+
*/
|
|
29
|
+
export type SvgExportOptions = {
|
|
30
|
+
/** 导出范围:`content`(默认,按内容包围盒紧凑裁切)或 `viewport`(当前画布视口) */
|
|
31
|
+
area?: 'content' | 'viewport';
|
|
32
|
+
/** `area: 'content'` 时的四周留白,默认 0 */
|
|
33
|
+
padding?: number;
|
|
34
|
+
/** 缩放倍数,默认 1(内容模式下按世界尺寸 1:1) */
|
|
35
|
+
scale?: number;
|
|
36
|
+
/** 背景色;默认不铺背景(透明) */
|
|
37
|
+
background?: string | null;
|
|
38
|
+
/** 是否把工具层(控制面板、对齐辅助线)也导出,默认 false */
|
|
39
|
+
includeTools?: boolean;
|
|
40
|
+
/** 坐标保留小数位,默认 2(避免 `d` 属性里出现一长串浮点噪声) */
|
|
41
|
+
precision?: number;
|
|
42
|
+
};
|
|
43
|
+
export type SvgExportResult = {
|
|
44
|
+
svg: string;
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* 导出场景为 SVG 字符串。
|
|
50
|
+
*
|
|
51
|
+
* @param target ICE 实例(导出整幅画布)或任意组件(导出它的子树)
|
|
52
|
+
*/
|
|
53
|
+
export declare function exportSvg(target: any, options?: SvgExportOptions): string;
|
|
54
|
+
export declare function exportSvgResult(target: any, options?: SvgExportOptions): SvgExportResult;
|
|
@@ -10,6 +10,30 @@ import EventBus from '../event/EventBus.mjs';
|
|
|
10
10
|
import ICEEventTarget from '../event/ICEEventTarget.mjs';
|
|
11
11
|
import ICEBoundingBox from '../geometry/ICEBoundingBox.mjs';
|
|
12
12
|
import ICE from '../ICE.mjs';
|
|
13
|
+
/**
|
|
14
|
+
* 阴影简写预设:style.shadow: 'sm' | 'md' | 'lg' 一行搞定浮起效果,
|
|
15
|
+
* 对应展开为 shadowColor / shadowBlur / shadowOffsetX / shadowOffsetY。
|
|
16
|
+
*/
|
|
17
|
+
export declare const SHADOW_PRESETS: {
|
|
18
|
+
sm: {
|
|
19
|
+
shadowColor: string;
|
|
20
|
+
shadowBlur: number;
|
|
21
|
+
shadowOffsetX: number;
|
|
22
|
+
shadowOffsetY: number;
|
|
23
|
+
};
|
|
24
|
+
md: {
|
|
25
|
+
shadowColor: string;
|
|
26
|
+
shadowBlur: number;
|
|
27
|
+
shadowOffsetX: number;
|
|
28
|
+
shadowOffsetY: number;
|
|
29
|
+
};
|
|
30
|
+
lg: {
|
|
31
|
+
shadowColor: string;
|
|
32
|
+
shadowBlur: number;
|
|
33
|
+
shadowOffsetX: number;
|
|
34
|
+
shadowOffsetY: number;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
13
37
|
declare abstract class ICEComponent extends ICEEventTarget {
|
|
14
38
|
ice: ICE;
|
|
15
39
|
root: any;
|
|
@@ -298,7 +322,13 @@ declare abstract class ICEComponent extends ICEEventTarget {
|
|
|
298
322
|
*
|
|
299
323
|
* 顶层组件直接返回(绝大多数组件没有祖先,热路径上不做遍历);非法值按 1 处理。
|
|
300
324
|
*/
|
|
301
|
-
|
|
325
|
+
/**
|
|
326
|
+
* 有效不透明度 = 自身 `state.opacity` × 所有祖先的 `state.opacity`(默认 1)。
|
|
327
|
+
*
|
|
328
|
+
* 渲染把相乘的结果叠到 `ctx.globalAlpha` 上(祖先的 opacity 不会自动继承,组件是逐个绘制的)。
|
|
329
|
+
* 公开出来是因为**离屏与 SVG 导出必须用同一口径**,否则导出的图会比画布亮/暗一截。
|
|
330
|
+
*/
|
|
331
|
+
getEffectiveOpacity(): number;
|
|
302
332
|
/**
|
|
303
333
|
* 世界坐标点是否落在某个「裁剪祖先」的盒子之外。
|
|
304
334
|
*
|
|
@@ -10,6 +10,30 @@ import EventBus from '../event/EventBus';
|
|
|
10
10
|
import ICEEventTarget from '../event/ICEEventTarget';
|
|
11
11
|
import ICEBoundingBox from '../geometry/ICEBoundingBox';
|
|
12
12
|
import ICE from '../ICE';
|
|
13
|
+
/**
|
|
14
|
+
* 阴影简写预设:style.shadow: 'sm' | 'md' | 'lg' 一行搞定浮起效果,
|
|
15
|
+
* 对应展开为 shadowColor / shadowBlur / shadowOffsetX / shadowOffsetY。
|
|
16
|
+
*/
|
|
17
|
+
export declare const SHADOW_PRESETS: {
|
|
18
|
+
sm: {
|
|
19
|
+
shadowColor: string;
|
|
20
|
+
shadowBlur: number;
|
|
21
|
+
shadowOffsetX: number;
|
|
22
|
+
shadowOffsetY: number;
|
|
23
|
+
};
|
|
24
|
+
md: {
|
|
25
|
+
shadowColor: string;
|
|
26
|
+
shadowBlur: number;
|
|
27
|
+
shadowOffsetX: number;
|
|
28
|
+
shadowOffsetY: number;
|
|
29
|
+
};
|
|
30
|
+
lg: {
|
|
31
|
+
shadowColor: string;
|
|
32
|
+
shadowBlur: number;
|
|
33
|
+
shadowOffsetX: number;
|
|
34
|
+
shadowOffsetY: number;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
13
37
|
declare abstract class ICEComponent extends ICEEventTarget {
|
|
14
38
|
ice: ICE;
|
|
15
39
|
root: any;
|
|
@@ -298,7 +322,13 @@ declare abstract class ICEComponent extends ICEEventTarget {
|
|
|
298
322
|
*
|
|
299
323
|
* 顶层组件直接返回(绝大多数组件没有祖先,热路径上不做遍历);非法值按 1 处理。
|
|
300
324
|
*/
|
|
301
|
-
|
|
325
|
+
/**
|
|
326
|
+
* 有效不透明度 = 自身 `state.opacity` × 所有祖先的 `state.opacity`(默认 1)。
|
|
327
|
+
*
|
|
328
|
+
* 渲染把相乘的结果叠到 `ctx.globalAlpha` 上(祖先的 opacity 不会自动继承,组件是逐个绘制的)。
|
|
329
|
+
* 公开出来是因为**离屏与 SVG 导出必须用同一口径**,否则导出的图会比画布亮/暗一截。
|
|
330
|
+
*/
|
|
331
|
+
getEffectiveOpacity(): number;
|
|
302
332
|
/**
|
|
303
333
|
* 世界坐标点是否落在某个「裁剪祖先」的盒子之外。
|
|
304
334
|
*
|
|
@@ -6,6 +6,13 @@ import ICEComponent from './ICEComponent.mjs';
|
|
|
6
6
|
*/
|
|
7
7
|
declare abstract class ICEPath extends ICEComponent {
|
|
8
8
|
path2D: any;
|
|
9
|
+
/**
|
|
10
|
+
* 确保路径命令流是最新的。
|
|
11
|
+
*
|
|
12
|
+
* 画布通道里由 `doRender()` 在 dirty 时重建;但**导出 / 服务端出图没有渲染循环**
|
|
13
|
+
* (Node 里连 canvas 都没有),此时必须显式建一次,否则命令流是空的、导出出来一片空白。
|
|
14
|
+
*/
|
|
15
|
+
ensurePathBuilt(): void;
|
|
9
16
|
/**
|
|
10
17
|
* @cfg
|
|
11
18
|
* {
|
|
@@ -6,6 +6,13 @@ import ICEComponent from './ICEComponent';
|
|
|
6
6
|
*/
|
|
7
7
|
declare abstract class ICEPath extends ICEComponent {
|
|
8
8
|
path2D: any;
|
|
9
|
+
/**
|
|
10
|
+
* 确保路径命令流是最新的。
|
|
11
|
+
*
|
|
12
|
+
* 画布通道里由 `doRender()` 在 dirty 时重建;但**导出 / 服务端出图没有渲染循环**
|
|
13
|
+
* (Node 里连 canvas 都没有),此时必须显式建一次,否则命令流是空的、导出出来一片空白。
|
|
14
|
+
*/
|
|
15
|
+
ensurePathBuilt(): void;
|
|
9
16
|
/**
|
|
10
17
|
* @cfg
|
|
11
18
|
* {
|
|
@@ -91,6 +91,15 @@ declare class ICEText extends ICEComponent {
|
|
|
91
91
|
width: any;
|
|
92
92
|
height: any;
|
|
93
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* 多行文本的行距系数。
|
|
96
|
+
*
|
|
97
|
+
* 为什么不能直接用 `actualBoundingBoxAscent + Descent`(字形墨迹高度)当行距:
|
|
98
|
+
* 墨迹只覆盖「有笔画的部分」,拉丁字母的 cap-height 比 em 小得多 —— 14px Tahoma 的
|
|
99
|
+
* 墨迹高 ≈ 12px,拿它当行距时中文(墨迹接近满 em)会**上下叠在一起**,看起来像文字被压扁。
|
|
100
|
+
* 按字号 × 1.35 取行距更接近系统的自然行高,同时保证 ≥ 墨迹高度(不会挤)。
|
|
101
|
+
*/
|
|
102
|
+
private static readonly LINE_HEIGHT_RATIO;
|
|
94
103
|
/**
|
|
95
104
|
* @method measureText
|
|
96
105
|
*
|
|
@@ -126,6 +135,18 @@ declare class ICEText extends ICEComponent {
|
|
|
126
135
|
private __applyMeasuredSize;
|
|
127
136
|
/** DOM 降级测量:line-height 归一为 1,减少 leading 干扰(旧环境/小程序)。 */
|
|
128
137
|
private __measureByDOM;
|
|
138
|
+
/**
|
|
139
|
+
* 文本的**渲染行布局**:每一行的内容与基线坐标(组件本地坐标)。
|
|
140
|
+
*
|
|
141
|
+
* 画布渲染与 SVG 导出共用这一份口径 —— 两处各算一遍必然漂移(改了对齐公式忘了另一处,
|
|
142
|
+
* 表现为「导出的文字整体偏移」)。返回的 `x` 是**文字左边缘**(左/居中/右对齐都按画布公式算好),
|
|
143
|
+
* `y` 是 baseline 位置。
|
|
144
|
+
*/
|
|
145
|
+
getRenderLines(): Array<{
|
|
146
|
+
text: string;
|
|
147
|
+
x: number;
|
|
148
|
+
y: number;
|
|
149
|
+
}>;
|
|
129
150
|
/**
|
|
130
151
|
* @method doRender
|
|
131
152
|
* @overwrite
|
|
@@ -91,6 +91,15 @@ declare class ICEText extends ICEComponent {
|
|
|
91
91
|
width: any;
|
|
92
92
|
height: any;
|
|
93
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* 多行文本的行距系数。
|
|
96
|
+
*
|
|
97
|
+
* 为什么不能直接用 `actualBoundingBoxAscent + Descent`(字形墨迹高度)当行距:
|
|
98
|
+
* 墨迹只覆盖「有笔画的部分」,拉丁字母的 cap-height 比 em 小得多 —— 14px Tahoma 的
|
|
99
|
+
* 墨迹高 ≈ 12px,拿它当行距时中文(墨迹接近满 em)会**上下叠在一起**,看起来像文字被压扁。
|
|
100
|
+
* 按字号 × 1.35 取行距更接近系统的自然行高,同时保证 ≥ 墨迹高度(不会挤)。
|
|
101
|
+
*/
|
|
102
|
+
private static readonly LINE_HEIGHT_RATIO;
|
|
94
103
|
/**
|
|
95
104
|
* @method measureText
|
|
96
105
|
*
|
|
@@ -126,6 +135,18 @@ declare class ICEText extends ICEComponent {
|
|
|
126
135
|
private __applyMeasuredSize;
|
|
127
136
|
/** DOM 降级测量:line-height 归一为 1,减少 leading 干扰(旧环境/小程序)。 */
|
|
128
137
|
private __measureByDOM;
|
|
138
|
+
/**
|
|
139
|
+
* 文本的**渲染行布局**:每一行的内容与基线坐标(组件本地坐标)。
|
|
140
|
+
*
|
|
141
|
+
* 画布渲染与 SVG 导出共用这一份口径 —— 两处各算一遍必然漂移(改了对齐公式忘了另一处,
|
|
142
|
+
* 表现为「导出的文字整体偏移」)。返回的 `x` 是**文字左边缘**(左/居中/右对齐都按画布公式算好),
|
|
143
|
+
* `y` 是 baseline 位置。
|
|
144
|
+
*/
|
|
145
|
+
getRenderLines(): Array<{
|
|
146
|
+
text: string;
|
|
147
|
+
x: number;
|
|
148
|
+
y: number;
|
|
149
|
+
}>;
|
|
129
150
|
/**
|
|
130
151
|
* @method doRender
|
|
131
152
|
* @overwrite
|
package/dist/types/index.d.mts
CHANGED
|
@@ -49,6 +49,8 @@ export { default as ICELayeredLayout } from './layout/ICELayeredLayout.mjs';
|
|
|
49
49
|
export { default as ICETheme, baseTokens, DEFAULT_THEME, DARK_THEME, registerTheme, setTheme, getTheme, STYLE_PRESETS, } from './theme/ICETheme.mjs';
|
|
50
50
|
export { default as ICE } from './ICE.mjs';
|
|
51
51
|
export { default as CanvasRenderer } from './renderer/CanvasRenderer.mjs';
|
|
52
|
+
export { exportSvg, exportSvgResult } from './export/SvgExporter.mjs';
|
|
53
|
+
export type { SvgExportOptions, SvgExportResult } from './export/SvgExporter.mjs';
|
|
52
54
|
export { default as PluginHost } from './plugin/PluginHost.mjs';
|
|
53
55
|
export type { ICEPlugin, ICEPluginTool, ICERenderHook, ICERenderFrame } from './plugin/PluginHost.mjs';
|
|
54
56
|
export { default as Serializer, SERIALIZATION_VERSION } from './persistence/Serializer.mjs';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export { default as ICELayeredLayout } from './layout/ICELayeredLayout';
|
|
|
49
49
|
export { default as ICETheme, baseTokens, DEFAULT_THEME, DARK_THEME, registerTheme, setTheme, getTheme, STYLE_PRESETS, } from './theme/ICETheme';
|
|
50
50
|
export { default as ICE } from './ICE';
|
|
51
51
|
export { default as CanvasRenderer } from './renderer/CanvasRenderer';
|
|
52
|
+
export { exportSvg, exportSvgResult } from './export/SvgExporter';
|
|
53
|
+
export type { SvgExportOptions, SvgExportResult } from './export/SvgExporter';
|
|
52
54
|
export { default as PluginHost } from './plugin/PluginHost';
|
|
53
55
|
export type { ICEPlugin, ICEPluginTool, ICERenderHook, ICERenderFrame } from './plugin/PluginHost';
|
|
54
56
|
export { default as Serializer, SERIALIZATION_VERSION } from './persistence/Serializer';
|