@vvfx/svg2ir 0.0.0-stage → 0.0.1-beta.0
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/LICENSE +22 -0
- package/README.md +179 -2
- package/dist/common/errors.d.ts +33 -0
- package/dist/common/types.d.ts +89 -0
- package/dist/convert.d.ts +19 -0
- package/dist/debug.d.ts +8 -0
- package/dist/helper.d.ts +5 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +16013 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +16008 -0
- package/dist/index.mjs.map +1 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.js +16030 -0
- package/dist/node.js.map +1 -0
- package/dist/node.mjs +16025 -0
- package/dist/node.mjs.map +1 -0
- package/dist/parse-svg/bridge.d.ts +10 -0
- package/dist/parse-svg/node.d.ts +3 -0
- package/dist/parse-svg/read-presentation-attribute.d.ts +5 -0
- package/dist/parse-svg/svg-parser.d.ts +46 -0
- package/dist/svg-preserved-data.d.ts +78 -0
- package/dist/svg2ge-adapter/assemble.d.ts +5 -0
- package/dist/svg2ge-adapter/convert.d.ts +5 -0
- package/dist/svg2ge-adapter/converter/animation.d.ts +10 -0
- package/dist/svg2ge-adapter/converter/data-path.d.ts +6 -0
- package/dist/svg2ge-adapter/normalize-shape-animation.d.ts +2 -0
- package/dist/svg2ge-adapter/post-process/apply-fonts.d.ts +6 -0
- package/dist/svg2ge-adapter/post-process/apply-shape-geometry-animation.d.ts +4 -0
- package/dist/svg2ge-adapter/post-process/apply-shape-paint-animation.d.ts +4 -0
- package/dist/svg2ge-adapter/post-process/paint-animation-sampling.d.ts +13 -0
- package/dist/svg2ge-adapter/post-process/restore-gradient-uv.d.ts +3 -0
- package/dist/svg2ge-adapter/post-process/rewrite-text-components.d.ts +13 -0
- package/dist/svg2ge-adapter/pre-process.d.ts +7 -0
- package/dist/svg2ge-adapter/types.d.ts +11 -0
- package/dist/svg2ir/assemble.d.ts +9 -0
- package/dist/svg2ir/convert-arc.d.ts +10 -0
- package/dist/svg2ir/convert.d.ts +21 -0
- package/dist/svg2ir/converter/clip/apply-mask.d.ts +4 -0
- package/dist/svg2ir/converter/clip/build-clip-mask.d.ts +35 -0
- package/dist/svg2ir/converter/clip/collect-geometry.d.ts +32 -0
- package/dist/svg2ir/converter/clip/warn-unsupported.d.ts +7 -0
- package/dist/svg2ir/converter/diagnostics/collect-warnings.d.ts +6 -0
- package/dist/svg2ir/converter/diagnostics/inspect-filter.d.ts +4 -0
- package/dist/svg2ir/converter/diagnostics/warn-unsupported.d.ts +8 -0
- package/dist/svg2ir/converter/image/parse-image.d.ts +14 -0
- package/dist/svg2ir/converter/layers/build-layers.d.ts +8 -0
- package/dist/svg2ir/converter/layers/conversion-session.d.ts +161 -0
- package/dist/svg2ir/converter/layers/convert-group-element.d.ts +3 -0
- package/dist/svg2ir/converter/layers/convert-image-element.d.ts +3 -0
- package/dist/svg2ir/converter/layers/convert-shape-element.d.ts +3 -0
- package/dist/svg2ir/converter/layers/convert-text-element.d.ts +3 -0
- package/dist/svg2ir/converter/layers/convert-use-element.d.ts +3 -0
- package/dist/svg2ir/converter/layers/element-categories.d.ts +2 -0
- package/dist/svg2ir/converter/layers/registry.d.ts +4 -0
- package/dist/svg2ir/converter/paint/resolve-gradient.d.ts +29 -0
- package/dist/svg2ir/converter/shape/convert-annulus.d.ts +10 -0
- package/dist/svg2ir/converter/shape/parse-dash.d.ts +23 -0
- package/dist/svg2ir/converter/shape/parse-shape-element.d.ts +4 -0
- package/dist/svg2ir/converter/shape/parse-shape-primitives.d.ts +15 -0
- package/dist/svg2ir/converter/smil/apply-opacity-composition.d.ts +6 -0
- package/dist/svg2ir/converter/smil/apply-transform-animation.d.ts +14 -0
- package/dist/svg2ir/converter/smil/apply-transform-composition.d.ts +4 -0
- package/dist/svg2ir/converter/smil/build-keyframes.d.ts +10 -0
- package/dist/svg2ir/converter/smil/collect-geometry-animation.d.ts +7 -0
- package/dist/svg2ir/converter/smil/inspect-animation.d.ts +6 -0
- package/dist/svg2ir/converter/smil/parse-motion.d.ts +4 -0
- package/dist/svg2ir/converter/smil/parse-paint-animation.d.ts +13 -0
- package/dist/svg2ir/converter/smil/parse-shape-animation.d.ts +4 -0
- package/dist/svg2ir/converter/smil/parse-timeline.d.ts +4 -0
- package/dist/svg2ir/converter/smil/resolve-animation-target.d.ts +4 -0
- package/dist/svg2ir/converter/smil/sample-composition-frames.d.ts +42 -0
- package/dist/svg2ir/converter/smil/scan-duration.d.ts +4 -0
- package/dist/svg2ir/converter/smil/timeline-schedule.d.ts +17 -0
- package/dist/svg2ir/converter/smil/timeline-values.d.ts +20 -0
- package/dist/svg2ir/converter/smil/types.d.ts +129 -0
- package/dist/svg2ir/converter/switch-branch.d.ts +3 -0
- package/dist/svg2ir/converter/text/build-per-line-text-layers.d.ts +11 -0
- package/dist/svg2ir/converter/text/build-single-text-layer.d.ts +11 -0
- package/dist/svg2ir/converter/text/build-split-text-layers.d.ts +11 -0
- package/dist/svg2ir/converter/text/build-vertical-text-layers.d.ts +10 -0
- package/dist/svg2ir/converter/text/font-metrics.d.ts +53 -0
- package/dist/svg2ir/converter/text/inspect-content.d.ts +42 -0
- package/dist/svg2ir/converter/text/parse.d.ts +10 -0
- package/dist/svg2ir/converter/text/text-layout.d.ts +29 -0
- package/dist/svg2ir/converter/transform/build-transform.d.ts +15 -0
- package/dist/svg2ir/converter/use/collect-group-use-instances.d.ts +16 -0
- package/dist/svg2ir/converter/use/expand-use.d.ts +31 -0
- package/dist/svg2ir/css-named-colors.d.ts +1 -0
- package/dist/svg2ir/index.d.ts +2 -0
- package/dist/svg2ir/map-color.d.ts +3 -0
- package/dist/svg2ir/matrix.d.ts +67 -0
- package/dist/svg2ir/normalize-path.d.ts +52 -0
- package/dist/svg2ir/read-attributes.d.ts +12 -0
- package/dist/svg2layers-adapter/assemble.d.ts +8 -0
- package/dist/svg2layers-adapter/convert.d.ts +4 -0
- package/dist/svg2layers-adapter/converter/diagnostics/collect-warnings.d.ts +10 -0
- package/dist/svg2layers-adapter/converter/image/convert-image-layer.d.ts +5 -0
- package/dist/svg2layers-adapter/converter/layers/build-layers.d.ts +3 -0
- package/dist/svg2layers-adapter/converter/layers/conversion-session.d.ts +14 -0
- package/dist/svg2layers-adapter/converter/layers/registry.d.ts +9 -0
- package/dist/svg2layers-adapter/converter/layers/resolve-visual-state.d.ts +4 -0
- package/dist/svg2layers-adapter/converter/text/convert-text-layer.d.ts +5 -0
- package/dist/svg2layers-adapter/converter/text/parse-text-runs.d.ts +11 -0
- package/dist/svg2layers-adapter/converter/text/text-layout.d.ts +9 -0
- package/dist/svg2layers-adapter/converter/transform/build-transform.d.ts +8 -0
- package/dist/svg2layers-adapter/matrix.d.ts +16 -0
- package/dist/svg2layers-adapter/post-process/inline-image-resources.d.ts +3 -0
- package/dist/svg2layers-adapter/types.d.ts +61 -0
- package/package.json +61 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type EditableSVG from '../../../parse-svg/svg-parser';
|
|
2
|
+
import type { Element } from '@svgdotjs/svg.js';
|
|
3
|
+
import type { IRShape } from '@vvfx/animation-ir';
|
|
4
|
+
import { type SVGMatrix } from '../../matrix';
|
|
5
|
+
export interface GroupUseInstance {
|
|
6
|
+
kind: 'shape' | 'text' | 'image';
|
|
7
|
+
source: Element;
|
|
8
|
+
target: Element;
|
|
9
|
+
shape?: IRShape;
|
|
10
|
+
matrix: SVGMatrix;
|
|
11
|
+
name: string;
|
|
12
|
+
ancestorStopNode: globalThis.Element | null;
|
|
13
|
+
opacity: number;
|
|
14
|
+
visible: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function collectGroupUseInstances(es: EditableSVG, groupEl: Element, idShapes: ReadonlyMap<string, IRShape>, idEls: ReadonlyMap<string, Element>): GroupUseInstance[];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG `<use href="#id">` 展开成实例图层。
|
|
3
|
+
*
|
|
4
|
+
* Effects shape 使用按值数据,没有 SVG symbol/use 的共享引用语义,因此 SVG → IR 阶段复制
|
|
5
|
+
* 目标形状或文本并应用 use 的 x/y、transform 与继承样式。多次 use 会生成独立实例。
|
|
6
|
+
*/
|
|
7
|
+
import type EditableSVG from '../../../parse-svg/svg-parser';
|
|
8
|
+
import type { Element } from '@svgdotjs/svg.js';
|
|
9
|
+
import { type IRShape, type IRTransform } from '@vvfx/animation-ir';
|
|
10
|
+
import { type SVGMatrix } from '../../matrix';
|
|
11
|
+
/** 读取 <use> 引用的目标 id,支持 href 和 xlink:href。 */
|
|
12
|
+
export declare function readUseTarget(es: EditableSVG, el: Element): string | undefined;
|
|
13
|
+
/** 读取 <use> 的 x/y 平移属性。 */
|
|
14
|
+
export declare function readUseTranslate(es: EditableSVG, el: Element): {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
};
|
|
18
|
+
export declare function buildUseMatrix(useEl: Element, useX: number, useY: number): SVGMatrix;
|
|
19
|
+
/**
|
|
20
|
+
* 构建 use 实例的完整 transform。
|
|
21
|
+
*
|
|
22
|
+
* 矩阵顺序为 `祖先变换 × use 自身 transform × translate(x, y)`;shape.position
|
|
23
|
+
* 作为实例的局部 anchor,避免在 Effects lowering 阶段重复计算形状中心。
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildUseTransform(useEl: Element, shape: IRShape, useX: number, useY: number, targetMatrix?: SVGMatrix, targetOpacity?: number): IRTransform;
|
|
26
|
+
/**
|
|
27
|
+
* 用 use 自身的 presentation 属性覆盖目标 shape 的 paint 与线条属性。
|
|
28
|
+
* use 的显式属性优先于目标属性;未显式设置时,沿 use 所在 DOM 树读取继承值。
|
|
29
|
+
* 带 filter 的 use 保留目标 paint,因为 Effects 不支持 filter,直接应用覆盖色会产生错误的硬边阴影。
|
|
30
|
+
*/
|
|
31
|
+
export declare function applyUseStyleOverrides(es: EditableSVG, useEl: Element, targetEl: Element | undefined, shape: IRShape): IRShape;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CSS_NAMED_COLORS: Map<string, readonly [number, number, number]>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG transform matrix 累乘 + 点变换(嵌套 g 父子 transform 用)。
|
|
3
|
+
*
|
|
4
|
+
* SVG 规范:子元素最终变换 = 父 g transform × 子自身 transform(矩阵左乘)。
|
|
5
|
+
* svg2ir 用 find('*') 平铺遍历,丢失 DOM 嵌套继承。这里算祖先结构容器的累计 matrix,
|
|
6
|
+
* 应用到子元素的 position/scale(rectify 坐标)。比建 null parent 层轻(IR 直接烘焙世界变换,避免额外重建 DOM 父子层级)。
|
|
7
|
+
*
|
|
8
|
+
* matrix(a,b,c,d,e,f): [a c e; b d f; 0 0 1]。点 变换后:(a*x+c*y+e, b*x+d*y+f)。
|
|
9
|
+
*/
|
|
10
|
+
export interface SVGMatrix {
|
|
11
|
+
a: number;
|
|
12
|
+
b: number;
|
|
13
|
+
c: number;
|
|
14
|
+
d: number;
|
|
15
|
+
e: number;
|
|
16
|
+
f: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const IDENTITY: SVGMatrix;
|
|
19
|
+
/** 解析 `matrix(a b c d e f)`、`translate(x y)`、`scale(s)`、`rotate(d)` 为 SVGMatrix。 */
|
|
20
|
+
export declare function parseTransform(transform: string): SVGMatrix;
|
|
21
|
+
/** 矩阵乘法 result = a × b(矩阵乘,用于 transform 累乘)。 */
|
|
22
|
+
export declare function multiply(a: SVGMatrix, b: SVGMatrix): SVGMatrix;
|
|
23
|
+
/** 用矩阵变换点 → (a*x+c*y+e, b*x+d*y+f)。 */
|
|
24
|
+
export declare function transformPoint(m: SVGMatrix, x: number, y: number): {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
/** 2D affine 矩阵 {a,b,c,d,e,f}([a c e; b d f; 0 0 1])求逆。det=ad-bc,不可逆(退化)返回 IDENTITY。
|
|
29
|
+
* 用于把"经 transform 的世界坐标点"映回 transform 前的局部坐标(rotation/scale/translate 都正确处理)。 */
|
|
30
|
+
export declare function invertSVGMatrix(m: SVGMatrix): SVGMatrix;
|
|
31
|
+
/** 把 2×3 矩阵拆成 scale(允许负号表达镜像) + rotation(度)。
|
|
32
|
+
* 假设无 shear(skew 已在转换侧 warn 并丢弃);非均匀缩放由 sx/sy 不同表达。
|
|
33
|
+
* rotation 用度,与 IR transform.rotation.z / IR 坐标约定一致。
|
|
34
|
+
*/
|
|
35
|
+
export declare function decomposeMatrix(m: {
|
|
36
|
+
a: number;
|
|
37
|
+
b: number;
|
|
38
|
+
c: number;
|
|
39
|
+
d: number;
|
|
40
|
+
}): {
|
|
41
|
+
sx: number;
|
|
42
|
+
sy: number;
|
|
43
|
+
rotation: number;
|
|
44
|
+
};
|
|
45
|
+
/** 累乘元素及其所有祖先 <g> 的 opacity(遇 svg 停止),模拟 group opacity 对子元素的影响。
|
|
46
|
+
* SVG 中 opacity 在 <g> 上作用于整组合成,但 svg2ir 把组拍平,这里把祖先 opacity
|
|
47
|
+
* 乘到每个子元素,比完全忽略更接近浏览器效果。
|
|
48
|
+
*/
|
|
49
|
+
export declare function accumulateOpacity(el: {
|
|
50
|
+
node?: unknown;
|
|
51
|
+
}): number;
|
|
52
|
+
/**
|
|
53
|
+
* 累乘元素所有祖先 <g> 的 transform(从自身往上,每层左乘),返回 M_最外×...×M_最内父。
|
|
54
|
+
* 用 DOM getAttribute('transform') 取原始值,绕过 SVG 解析底座的继承(它对自带 transform
|
|
55
|
+
* 的子元素不 inherit g,且多层嵌套只合最内层、外层丢失)。调用方再 × 自身 transform = 完整世界矩阵。
|
|
56
|
+
* 遇 <svg> root 停止。非 g 祖先(如 <svg>/<defs>)跳过(不累乘)。
|
|
57
|
+
*/
|
|
58
|
+
export declare function accumulateAncestors(el: {
|
|
59
|
+
node?: unknown;
|
|
60
|
+
}): SVGMatrix;
|
|
61
|
+
/** 构建 SVG viewBox → 外部 viewport 的仿射矩阵(preserveAspectRatio 支持 meet/slice/none)。 */
|
|
62
|
+
export declare function buildViewBoxMatrix(node: {
|
|
63
|
+
getAttribute?: (name: string) => string | null;
|
|
64
|
+
}, viewport?: {
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
}): SVGMatrix | undefined;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG path d 命令 → IRBezierPath(顶点切线模型)。
|
|
3
|
+
*
|
|
4
|
+
* 两步处理:(1) tokenize 并升阶到 M/L/C/Z;(2) 按 IR 顶点切线模型填充
|
|
5
|
+
* points/inTangents/outTangents。使用本地 tokenizer,按 SVG 规范命令表解析,不引入额外布局依赖。
|
|
6
|
+
*
|
|
7
|
+
* IR 顶点切线模型:每个顶点 i 携带 inTangents[i]/outTangents[i](相对该顶点的入/出切线偏移)。
|
|
8
|
+
* 段 i→i+1 三次贝塞尔的两个控制点 = points[i]+outTangents[i] 与 points[i+1]+inTangents[i+1]。
|
|
9
|
+
*/
|
|
10
|
+
import type { IRBezierPath } from '@vvfx/animation-ir';
|
|
11
|
+
/** 规整化后的命令:只剩 M/L/C/Z(绝对坐标)。 */
|
|
12
|
+
type NormalizedCommand = {
|
|
13
|
+
cmd: 'M';
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
} | {
|
|
17
|
+
cmd: 'L';
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
} | {
|
|
21
|
+
cmd: 'C';
|
|
22
|
+
x1: number;
|
|
23
|
+
y1: number;
|
|
24
|
+
x2: number;
|
|
25
|
+
y2: number;
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
} | {
|
|
29
|
+
cmd: 'Z';
|
|
30
|
+
};
|
|
31
|
+
interface NormalizePathOptions {
|
|
32
|
+
arcSegmentAngle?: number;
|
|
33
|
+
}
|
|
34
|
+
/** tokenize + 相对转绝对 + H/V→L + Q/T/S/A 升阶成 C。M 开头(规整化补 M(0,0) 防 C/L 越界)。 */
|
|
35
|
+
export declare function normalizePathCommands(d: string, options?: NormalizePathOptions): NormalizedCommand[];
|
|
36
|
+
/** 规整化命令 → IRBezierPath(顶点切线模型,每个 sub-path 一个)。一行 d 多 sub-path 时产多个。 */
|
|
37
|
+
export declare function normalizedToCustomShapePaths(cmds: NormalizedCommand[]): IRBezierPath[];
|
|
38
|
+
/**
|
|
39
|
+
* 将多个闭合 sub-path 缝合成一条 IRBezierPath。
|
|
40
|
+
*
|
|
41
|
+
* Effects 的 ShapeComponent 会把 `shapes` 数组里的每个 shape 独立 triangulate/fill;因此
|
|
42
|
+
* 一个外框 + 一个内框会被渲染成两个实心矩形,中间看不到洞。SVG 的 fill-rule(默认
|
|
43
|
+
* nonzero / evenodd)需要在同一次 triangulation 里把所有 contour 一起处理。Effects 底层的
|
|
44
|
+
* libtess 默认 odd(evenodd),所以 svg2ir 只要在同一个 CustomShape 里把 contour 连
|
|
45
|
+
* 成一个简单多边形,Effects 就会按 odd 规则把内部 contour 当成洞。
|
|
46
|
+
*
|
|
47
|
+
* 这里用“零面积桥接”:把每个 sub-path 的起点复制一次作为闭合边,再用直线桥接到下一个
|
|
48
|
+
* sub-path 的起点;桥接边在 odd 规则下互相抵消,等价于多个独立 contour。只在所有
|
|
49
|
+
* sub-path 都闭合时生效。
|
|
50
|
+
*/
|
|
51
|
+
export declare function mergeClosedSubpaths(paths: IRBezierPath[]): IRBezierPath[];
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type EditableSVG from '../parse-svg/svg-parser';
|
|
2
|
+
import type { Element } from '@svgdotjs/svg.js';
|
|
3
|
+
/** 从 SVG 元素读取数值属性;支持 px、无单位数值和常见 viewport 百分比。 */
|
|
4
|
+
export declare function readSVGNumberAttribute(es: EditableSVG, el: Element, attribute: string, fallback?: number): number | undefined;
|
|
5
|
+
/** 从 SVG 元素读取字符串属性。 */
|
|
6
|
+
export declare function readSVGStringAttribute(es: EditableSVG, el: Element, attribute: string): string;
|
|
7
|
+
/** display:none 或 visibility:hidden 的 SVG 元素不参与渲染。 */
|
|
8
|
+
export declare function isSVGElementVisible(es: EditableSVG, el: Element): boolean;
|
|
9
|
+
/** 读取元素自身 opacity,不包含祖先组。 */
|
|
10
|
+
export declare function readSVGOwnOpacity(el: Element): number;
|
|
11
|
+
/** 读取元素自身 opacity,并乘入所有祖先组 opacity。 */
|
|
12
|
+
export declare function readSVGElementOpacity(el: Element): number;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IRScene } from '@vvfx/animation-ir';
|
|
2
|
+
import { type ConvertOptions, type SVG2IRWarning } from '../common/types';
|
|
3
|
+
import type { SVGPreservedData } from '../svg-preserved-data';
|
|
4
|
+
import type { SVGStaticLayer } from './types';
|
|
5
|
+
export declare function assembleSVGStaticLayers(scene: IRScene, options: ConvertOptions, warnings: SVG2IRWarning[], preservedData?: SVGPreservedData): {
|
|
6
|
+
size: [number, number];
|
|
7
|
+
data: SVGStaticLayer[];
|
|
8
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ConvertOptions, SVGSource } from '../common/types';
|
|
2
|
+
import type { SVGPreservedData } from '../svg-preserved-data';
|
|
3
|
+
import type { SVGImageResourceLoader, SVGToLayersResult } from './types';
|
|
4
|
+
export declare function convertSVGToLayers(source: SVGSource, options: ConvertOptions, loadImage?: SVGImageResourceLoader, preservedData?: SVGPreservedData): Promise<SVGToLayersResult>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IRLayer } from '@vvfx/animation-ir';
|
|
2
|
+
import { type ConvertOptions, type SVG2IRWarning, type SVG2IRWarningCode } from '../../../common/types';
|
|
3
|
+
export declare class LayerConversionError extends Error {
|
|
4
|
+
readonly code: SVG2IRWarningCode;
|
|
5
|
+
constructor(code: SVG2IRWarningCode, message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function throwUnsupportedLayerFeature(message: string): never;
|
|
8
|
+
export declare function throwInvalidLayerData(message: string): never;
|
|
9
|
+
export declare function collectLayerWarning(warnings: SVG2IRWarning[], options: ConvertOptions, code: SVG2IRWarningCode, message: string, selector?: string): void;
|
|
10
|
+
export declare function collectUnsupportedIRLayer(layer: IRLayer, selector: string, warnings: SVG2IRWarning[], options: ConvertOptions): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IRImageLayer } from '@vvfx/animation-ir';
|
|
2
|
+
import type { StaticLayerState } from '../transform/build-transform';
|
|
3
|
+
import type { SVGImageLayer } from '../../types';
|
|
4
|
+
import type { LayerConversionSession } from '../layers/conversion-session';
|
|
5
|
+
export declare function convertIRImageLayer(layer: IRImageLayer, state: StaticLayerState, session: LayerConversionSession, id: string): SVGImageLayer;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IRAsset, IRComposition, IRLayer, IRScene } from '@vvfx/animation-ir';
|
|
2
|
+
import type { ConvertOptions, SVG2IRWarning } from '../../../common/types';
|
|
3
|
+
import type { SVGPreservedData } from '../../../svg-preserved-data';
|
|
4
|
+
import { type StaticLayerState } from '../transform/build-transform';
|
|
5
|
+
export interface LayerConversionSession {
|
|
6
|
+
readonly composition: IRComposition;
|
|
7
|
+
readonly assets: ReadonlyMap<string, IRAsset>;
|
|
8
|
+
readonly maskSourceIds: ReadonlySet<string>;
|
|
9
|
+
readonly preservedData: SVGPreservedData | undefined;
|
|
10
|
+
readonly resolveLayerState: (layer: IRLayer) => StaticLayerState;
|
|
11
|
+
readonly options: ConvertOptions;
|
|
12
|
+
readonly warnings: SVG2IRWarning[];
|
|
13
|
+
}
|
|
14
|
+
export declare function buildLayerConversionSession(scene: IRScene, options: ConvertOptions, warnings: SVG2IRWarning[], preservedData?: SVGPreservedData): LayerConversionSession;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IRLayer } from '@vvfx/animation-ir';
|
|
2
|
+
import type { StaticLayerState } from '../transform/build-transform';
|
|
3
|
+
import type { SVGStaticLayer } from '../../types';
|
|
4
|
+
import type { LayerConversionSession } from './conversion-session';
|
|
5
|
+
export interface LayerConverter {
|
|
6
|
+
readonly layerType: SVGStaticLayer['type'];
|
|
7
|
+
readonly convert: (layer: IRLayer, state: StaticLayerState, id: string) => SVGStaticLayer | undefined;
|
|
8
|
+
}
|
|
9
|
+
export declare function createLayerConverterRegistry(session: LayerConversionSession): ReadonlyMap<IRLayer['type'], LayerConverter>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type IRLayer } from '@vvfx/animation-ir';
|
|
2
|
+
import type { StaticLayerState } from '../transform/build-transform';
|
|
3
|
+
import type { LayerConversionSession } from './conversion-session';
|
|
4
|
+
export declare function resolveIRVisualState(layer: IRLayer, session: LayerConversionSession): StaticLayerState | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IRTextLayer } from '@vvfx/animation-ir';
|
|
2
|
+
import type { LayerConversionSession } from '../layers/conversion-session';
|
|
3
|
+
import type { StaticLayerState } from '../transform/build-transform';
|
|
4
|
+
import type { SVGTextLayer } from '../../types';
|
|
5
|
+
export declare function convertIRTextLayer(layer: IRTextLayer, state: StaticLayerState, session: LayerConversionSession, id: string): SVGTextLayer | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IRFontAsset, IRTextLayer } from '@vvfx/animation-ir';
|
|
2
|
+
import type { SVGPreservedTextData } from '../../../svg-preserved-data';
|
|
3
|
+
export interface TextRun {
|
|
4
|
+
text: string;
|
|
5
|
+
fontSize: number;
|
|
6
|
+
color: string;
|
|
7
|
+
alpha: number;
|
|
8
|
+
bold: boolean;
|
|
9
|
+
italic: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseTextRuns(layer: IRTextLayer, font: IRFontAsset, preserved?: SVGPreservedTextData): TextRun[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IRTextContent } from '@vvfx/animation-ir';
|
|
2
|
+
import { type ConvertOptions, type SVG2IRWarning } from '../../../common/types';
|
|
3
|
+
import type { SVGLayerBBox } from '../../types';
|
|
4
|
+
import type { TextRun } from './parse-text-runs';
|
|
5
|
+
export interface PositionedTextRun {
|
|
6
|
+
run: TextRun;
|
|
7
|
+
box: SVGLayerBBox;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildTextRunLayout(runs: TextRun[], family: string, spacing: number, content: IRTextContent, size: [number, number], conversionOptions: ConvertOptions, warnings: SVG2IRWarning[], id: string, segmented?: boolean): PositionedTextRun[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IRLayer } from '@vvfx/animation-ir';
|
|
2
|
+
import { type LayerMatrix } from '../../matrix';
|
|
3
|
+
export interface StaticLayerState {
|
|
4
|
+
matrix: LayerMatrix;
|
|
5
|
+
opacity: number;
|
|
6
|
+
visible: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function buildIRStaticStateResolver(layers: ReadonlyMap<string, IRLayer>, inPoint: number): (layer: IRLayer) => StaticLayerState;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SVGLayerBBox } from './types';
|
|
2
|
+
export interface LayerMatrix {
|
|
3
|
+
a: number;
|
|
4
|
+
b: number;
|
|
5
|
+
c: number;
|
|
6
|
+
d: number;
|
|
7
|
+
e: number;
|
|
8
|
+
f: number;
|
|
9
|
+
}
|
|
10
|
+
export type LayerPoint = [number, number];
|
|
11
|
+
export declare const IDENTITY_MATRIX: LayerMatrix;
|
|
12
|
+
export declare function multiplyMatrices(parent: LayerMatrix, local: LayerMatrix): LayerMatrix;
|
|
13
|
+
export declare function transformPoint(matrix: LayerMatrix, x: number, y: number): LayerPoint;
|
|
14
|
+
export declare function transformBoxCorners(matrix: LayerMatrix, box: SVGLayerBBox): LayerPoint[];
|
|
15
|
+
export declare function mapPointsToBBox(points: readonly LayerPoint[]): SVGLayerBBox;
|
|
16
|
+
export declare function roundPixel(value: number): number;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { SVG2IRWarning } from '../common/types';
|
|
2
|
+
/** 图片读取结果;data 为原始文件字节,不是 Base64 字符串。 */
|
|
3
|
+
export interface SVGImageResource {
|
|
4
|
+
data: Uint8Array;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
}
|
|
7
|
+
/** 读取外链、本地文件或需要鉴权的图片资源。 */
|
|
8
|
+
export type SVGImageResourceLoader = (url: string) => Promise<SVGImageResource>;
|
|
9
|
+
/** 像素边界:[左、上、右、下]。 */
|
|
10
|
+
export type SVGLayerBBox = [number, number, number, number];
|
|
11
|
+
export interface SVGImageLayer {
|
|
12
|
+
id: string;
|
|
13
|
+
type: 'image';
|
|
14
|
+
/** 图层业务角色;原生 SVG 图片默认为 content,不根据图片内容推断。 */
|
|
15
|
+
role: 'background' | 'content' | 'text_pixels';
|
|
16
|
+
bbox: SVGLayerBBox;
|
|
17
|
+
/** 缩放后的显示宽高(px),不包含旋转造成的包围盒扩张。 */
|
|
18
|
+
size: [number, number];
|
|
19
|
+
/** XYZ 欧拉角(度);二维 SVG 仅 Z 生效,正值在画布上顺时针旋转。 */
|
|
20
|
+
rotation: [number, number, number];
|
|
21
|
+
/** 内联图片资源,格式为 data:image/...;base64,...。 */
|
|
22
|
+
url: string;
|
|
23
|
+
/** 兼容字段:轴对齐 bbox 的宽高;还原图片显示尺寸应使用 size。 */
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
}
|
|
27
|
+
export interface SVGTextFragment {
|
|
28
|
+
content: string;
|
|
29
|
+
/** 相对文字层左上角的坐标。 */
|
|
30
|
+
bbox: SVGLayerBBox;
|
|
31
|
+
/** 相对文字层的布局四边形,依次为变换前的左上、右上、右下、左下角;不是字形轮廓。 */
|
|
32
|
+
polygon: Array<[number, number]> | null;
|
|
33
|
+
font_family: string;
|
|
34
|
+
font_size: number;
|
|
35
|
+
color: string;
|
|
36
|
+
letter_spacing: number;
|
|
37
|
+
direction: 'horizontal' | 'vertical';
|
|
38
|
+
rotation: number;
|
|
39
|
+
}
|
|
40
|
+
export interface SVGLayerEraseOperation {
|
|
41
|
+
source_layer_id: string;
|
|
42
|
+
bbox: SVGLayerBBox;
|
|
43
|
+
}
|
|
44
|
+
export interface SVGTextLayer {
|
|
45
|
+
id: string;
|
|
46
|
+
type: 'text';
|
|
47
|
+
/** 原生文字已可编辑,不属于从图片识别出的待转换候选。 */
|
|
48
|
+
state: 'active';
|
|
49
|
+
bbox: SVGLayerBBox;
|
|
50
|
+
content: string;
|
|
51
|
+
fragments: SVGTextFragment[];
|
|
52
|
+
/** 原生文字没有对应的图片擦除操作。 */
|
|
53
|
+
erase_operations: SVGLayerEraseOperation[];
|
|
54
|
+
}
|
|
55
|
+
export type SVGStaticLayer = SVGImageLayer | SVGTextLayer;
|
|
56
|
+
export interface SVGToLayersResult {
|
|
57
|
+
/** 独立返回的画布宽高(px),不属于 data 中的图层 JSON。 */
|
|
58
|
+
size: [number, number];
|
|
59
|
+
data: SVGStaticLayer[];
|
|
60
|
+
warnings: SVG2IRWarning[];
|
|
61
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vvfx/svg2ir",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.1-beta.0",
|
|
4
|
+
"description": "SVG to Animation IR and Galacean Effects conversion engine",
|
|
5
|
+
"module": "./dist/index.mjs",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"node": {
|
|
14
|
+
"types": "./dist/node.d.ts",
|
|
15
|
+
"import": "./dist/node.mjs",
|
|
16
|
+
"require": "./dist/node.js"
|
|
17
|
+
},
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@galacean/effects-specification": "2.7.2",
|
|
25
|
+
"@svgdotjs/svg.js": "3.2.7",
|
|
26
|
+
"svgdom": "0.1.14",
|
|
27
|
+
"@vvfx/animation-ir": "0.0.1-beta.11",
|
|
28
|
+
"@vvfx/ge-ir": "0.0.1-beta.11"
|
|
29
|
+
},
|
|
30
|
+
"contributors": [
|
|
31
|
+
{
|
|
32
|
+
"name": "鳞息"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"author": "Ant Group CO., Ltd.",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public",
|
|
39
|
+
"registry": "https://registry.npmjs.org"
|
|
40
|
+
},
|
|
41
|
+
"repository": "https://github.com/galacean/design-bridge",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/galacean/design-bridge/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/galacean/design-bridge/tree/main/packages/svg2ir#readme",
|
|
46
|
+
"keywords": [
|
|
47
|
+
"svg",
|
|
48
|
+
"animation",
|
|
49
|
+
"animation-ir",
|
|
50
|
+
"galacean-effects",
|
|
51
|
+
"converter"
|
|
52
|
+
],
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=22"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"prebuild": "pnpm clean",
|
|
58
|
+
"build": "pnpm build:declaration && pnpm build:module",
|
|
59
|
+
"build:module": "rollup -c --bundleConfigAsCjs",
|
|
60
|
+
"build:declaration": "tsc -b ../animation-ir ../ge-ir tsconfig.json --emitDeclarationOnly",
|
|
61
|
+
"clean": "rimraf dist *.tsbuildinfo",
|
|
62
|
+
"test": "vitest run"
|
|
63
|
+
}
|
|
6
64
|
}
|