@vvfx/sdk 0.2.7 → 0.2.9

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 (108) hide show
  1. package/dist/config.js +231 -0
  2. package/dist/exporter/config.js +18 -0
  3. package/dist/exporter/const.js +71 -0
  4. package/dist/exporter/export-media.js +878 -0
  5. package/dist/exporter/exporter.js +121 -0
  6. package/dist/exporter/index.js +1 -0
  7. package/dist/exporter/types.js +1 -0
  8. package/dist/exporter/utils.js +190 -0
  9. package/dist/exporter/wav-audio.js +50 -0
  10. package/dist/gesture-handler/gizmo/adsorption-gizmo.js +227 -0
  11. package/dist/gesture-handler/gizmo/control-gizmo.js +149 -0
  12. package/dist/gesture-handler/gizmo/gizmo.js +17 -0
  13. package/dist/gesture-handler/gizmo/icon-gizmo.js +189 -0
  14. package/dist/gesture-handler/gizmo/index.js +6 -0
  15. package/dist/gesture-handler/gizmo/item-create-gizmo.js +256 -0
  16. package/dist/gesture-handler/gizmo/loading-gizmo.js +320 -0
  17. package/dist/gesture-handler/gizmo/mask-gizmo.js +648 -0
  18. package/dist/gesture-handler/gizmo/picture-cut-gizmo.js +550 -0
  19. package/dist/gesture-handler/gizmo/picture-expand-gizmo.js +491 -0
  20. package/dist/gesture-handler/gizmo/preference-gizmo.js +148 -0
  21. package/dist/gesture-handler/gizmo/selector-gizmo.d.ts +1 -1
  22. package/dist/gesture-handler/gizmo/selector-gizmo.js +468 -0
  23. package/dist/gesture-handler/gizmo/sprite-text-edit-gizmo.js +247 -0
  24. package/dist/gesture-handler/gizmo/text-gizmo.js +1033 -0
  25. package/dist/gesture-handler/gizmo/transform-gizmo.js +1199 -0
  26. package/dist/gesture-handler/gizmo/type.js +18 -0
  27. package/dist/gesture-handler/index.js +3 -0
  28. package/dist/gesture-handler/src/gesture-handler.js +770 -0
  29. package/dist/gesture-handler/src/icons.js +24 -0
  30. package/dist/gesture-handler/utils.js +40 -0
  31. package/dist/html-overlay/anchor-navigation-runtime.js +27 -0
  32. package/dist/html-overlay/auto-height-runtime.js +132 -0
  33. package/dist/html-overlay/document-runtime.js +71 -0
  34. package/dist/html-overlay/document-transform.js +96 -0
  35. package/dist/html-overlay/dom-order.js +8 -0
  36. package/dist/html-overlay/host-message-runtime.js +24 -0
  37. package/dist/html-overlay/html-capture-runtime.js +282 -0
  38. package/dist/html-overlay/html-viewport-style.js +10 -0
  39. package/dist/html-overlay/index.js +1 -0
  40. package/dist/html-overlay/manager.js +1663 -0
  41. package/dist/html-overlay/mime-utils.js +21 -0
  42. package/dist/html-overlay/overlay-transform.js +57 -0
  43. package/dist/html-overlay/path-utils.js +35 -0
  44. package/dist/html-overlay/shell-runtime.js +12 -0
  45. package/dist/index.cjs +1 -7
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.js +13 -75317
  48. package/dist/index.mjs +75311 -0
  49. package/dist/index.mjs.map +1 -0
  50. package/dist/layer-order.js +8 -0
  51. package/dist/math/box2.js +396 -0
  52. package/dist/math/circle.js +131 -0
  53. package/dist/math/euler.js +35 -0
  54. package/dist/math/index.js +13 -0
  55. package/dist/math/line2.js +153 -0
  56. package/dist/math/line3.js +36 -0
  57. package/dist/math/matrix4.js +207 -0
  58. package/dist/math/plane.js +52 -0
  59. package/dist/math/quaternion.js +3 -0
  60. package/dist/math/ray-caster.js +25 -0
  61. package/dist/math/ray.js +47 -0
  62. package/dist/math/type.js +1 -0
  63. package/dist/math/utils.js +77 -0
  64. package/dist/math/vector2.js +70 -0
  65. package/dist/math/vector3.js +60 -0
  66. package/dist/screen-shot/index.js +1 -0
  67. package/dist/screen-shot/screen-shot.js +113 -0
  68. package/dist/sdk-item/base-item.js +160 -0
  69. package/dist/sdk-item/card-item.js +131 -0
  70. package/dist/sdk-item/effects-item.js +144 -0
  71. package/dist/sdk-item/frame-item.js +217 -0
  72. package/dist/sdk-item/generator-item.js +188 -0
  73. package/dist/sdk-item/group-item.js +116 -0
  74. package/dist/sdk-item/index.js +39 -0
  75. package/dist/sdk-item/sprite-item.js +147 -0
  76. package/dist/sdk-item/text-item.js +223 -0
  77. package/dist/sdk-item/types.d.ts +1 -11
  78. package/dist/sdk-item/types.js +15 -0
  79. package/dist/sdk-item/video-item.js +174 -0
  80. package/dist/sdk.js +1903 -0
  81. package/dist/service/UndoRedo.js +79 -0
  82. package/dist/shared/index.d.ts +1 -0
  83. package/dist/shared/index.js +2 -0
  84. package/dist/shared/player.d.ts +1 -1
  85. package/dist/shared/player.js +9 -0
  86. package/dist/shared/spec.d.ts +1 -0
  87. package/dist/shared/spec.js +1 -0
  88. package/dist/size-adapte/index.js +1 -0
  89. package/dist/size-adapte/size-adapt.js +395 -0
  90. package/dist/types.d.ts +5 -1
  91. package/dist/types.js +17 -0
  92. package/dist/utils/background-manager.js +189 -0
  93. package/dist/utils/common-utils.js +183 -0
  94. package/dist/utils/index.js +8 -0
  95. package/dist/utils/interaction-utils.js +205 -0
  96. package/dist/utils/json-data-utils.js +1529 -0
  97. package/dist/utils/layout-utils.js +1217 -0
  98. package/dist/utils/page-data-utils.js +5397 -0
  99. package/dist/utils/player-data-utils.js +48 -0
  100. package/dist/utils/types.js +8 -0
  101. package/dist/wireframe/common/box.js +18 -0
  102. package/dist/wireframe/common/dashed-line.js +21 -0
  103. package/dist/wireframe/common/line.js +17 -0
  104. package/dist/wireframe/common/pixi-ext.js +1 -0
  105. package/dist/wireframe/common/pixi.js +31 -0
  106. package/dist/wireframe/index.js +4 -0
  107. package/package.json +10 -3
  108. package/dist/index.js.map +0 -1
@@ -0,0 +1,60 @@
1
+ import { math } from '../shared';
2
+ import { Quaternion } from './quaternion';
3
+ export class Vector3 extends math.Vector3 {
4
+ clone() {
5
+ return new Vector3(this.x, this.y, this.z);
6
+ }
7
+ /**
8
+ * 由空间变换矩阵保存三维分量
9
+ * @param {Matrix4} m 四维矩阵
10
+ * @param {number} index 下标
11
+ * @returns {Vec3} 指定三维分量
12
+ */
13
+ setFromMatrixColumn(m, index) {
14
+ // 这里断言了,类型不安全,之后加 lint,必须有明显的 disable lint 起提示作用
15
+ return this.set(...m.elements.slice(index * 4));
16
+ }
17
+ applyEuler(euler, _out) {
18
+ return this.applyQuaternion(new Quaternion().setFromEuler(euler));
19
+ }
20
+ /**
21
+ * 三维点根据四元数绕点的旋转
22
+ * @param {Quaternion} q 四元数
23
+ * @param {Vec3} [center=new Vec3()] 旋转中心
24
+ * @returns {Vec3} 旋转结果
25
+ */
26
+ applyQuaternion(q, center = new Vector3()) {
27
+ const { x: qx, y: qy, z: qz, w: qw } = q;
28
+ const { x: vx, y: vy, z: vz } = this.subtract(center);
29
+ const ix = qw * vx + qy * vz - qz * vy;
30
+ const iy = qw * vy + qz * vx - qx * vz;
31
+ const iz = qw * vz + qx * vy - qy * vx;
32
+ const iw = -qx * vx - qy * vy - qz * vz;
33
+ this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy + center.x;
34
+ this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz + center.y;
35
+ this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx + center.z;
36
+ return this;
37
+ }
38
+ /**
39
+ * 由空间变换矩阵保存三维偏移值
40
+ * @param {Matrix4} m 四维矩阵
41
+ * @returns {Vec3} 偏移值
42
+ */
43
+ setFromMatrixPosition(m) {
44
+ const e = m.elements;
45
+ this.x = e[12];
46
+ this.y = e[13];
47
+ this.z = e[14];
48
+ return this;
49
+ }
50
+ applyMatrix(matrix, center = new Vector3()) {
51
+ const e = matrix.elements;
52
+ const { x: vx, y: vy, z: vz } = this.subtract(center);
53
+ let w = 1 / (e[3] * vx + e[7] * vy + e[11] * vz + e[15]);
54
+ w = isNaN(w) ? 1 : w;
55
+ this.x = (e[0] * vx + e[4] * vy + e[8] * vz + e[12]) * w + center.x;
56
+ this.y = (e[1] * vx + e[5] * vy + e[9] * vz + e[13]) * w + center.y;
57
+ this.z = (e[2] * vx + e[6] * vy + e[10] * vz + e[14]) * w + center.z;
58
+ return this;
59
+ }
60
+ }
@@ -0,0 +1 @@
1
+ export * from './screen-shot';
@@ -0,0 +1,113 @@
1
+ import { clamp } from '../math';
2
+ import { Player } from '../shared';
3
+ import { clearPlayerAssets } from '../exporter/utils';
4
+ import { SDK } from '../sdk';
5
+ /**
6
+ * @description 截图工具
7
+ */
8
+ export class ScreenShot {
9
+ /**
10
+ * @description 功能开关
11
+ */
12
+ enabled = true;
13
+ /**
14
+ * @description 截图播放器
15
+ */
16
+ _player;
17
+ /**
18
+ * @description 截图播放器容器
19
+ */
20
+ _container;
21
+ constructor() {
22
+ this._container = document.createElement('canvas');
23
+ this._player = new Player({
24
+ canvas: this._container,
25
+ manualRender: true,
26
+ pixelRatio: 2,
27
+ env: 'editor',
28
+ renderOptions: {
29
+ willCaptureImage: true,
30
+ },
31
+ });
32
+ }
33
+ /**
34
+ * @description 生成截图
35
+ * @param scene 场景数据
36
+ * @param resultSize 截图大小
37
+ * @param tick 截图时刻
38
+ * @param screenArea 截图范围【可选】 - [左上角x坐标, 左上角y坐标, 截图宽度, 截图高度]
39
+ * @returns 截图base64数据
40
+ */
41
+ async generate(scene, containerSize, resultSize, tick, background) {
42
+ if (!SDK.config.screenShotConfig.enabled) {
43
+ console.warn('Screen shot is not opened, use #SDK.setConfig() open this feature.');
44
+ return;
45
+ }
46
+ clearPlayerAssets(this._player);
47
+ const [containerWidth, containerHieght] = containerSize;
48
+ this._container.width = containerWidth;
49
+ this._container.height = containerHieght;
50
+ this._player.resize();
51
+ const resultScene = typeof scene === 'string' ? scene : JSON.parse(JSON.stringify(scene));
52
+ await this._player.loadScene(resultScene);
53
+ this._player.gotoAndStop(tick);
54
+ const [width, height] = resultSize;
55
+ const result = document.createElement('canvas');
56
+ result.width = width;
57
+ result.height = height;
58
+ const ctx = result.getContext('2d');
59
+ background ??= SDK.config.screenShotConfig.defaultBackgroundColor;
60
+ if (ctx) {
61
+ ctx.fillStyle = `rgba(${background.join(',')})`;
62
+ ctx.fillRect(0, 0, width, height);
63
+ this.drawImageCover(ctx, this._player.canvas, 0, 0, width, height, 0.5, 0.5);
64
+ }
65
+ const thumbnail = result.toDataURL('image/png');
66
+ clearPlayerAssets(this._player);
67
+ return thumbnail;
68
+ }
69
+ dispose() {
70
+ this._player.dispose();
71
+ }
72
+ drawImageCover(ctx, img, x, y, w, h, offsetX, offsetY, sourceRect) {
73
+ if (arguments.length === 2) {
74
+ x = y = 0;
75
+ w = ctx.canvas.width;
76
+ h = ctx.canvas.height;
77
+ }
78
+ // default offset is center
79
+ offsetX = typeof offsetX === 'number' ? clamp(offsetX, 0, 1) : 0.5;
80
+ offsetY = typeof offsetY === 'number' ? clamp(offsetY, 0, 1) : 0.5;
81
+ // keep bounds [0.0, 1.0]
82
+ // if (offsetX < 0) { offsetX = 0 }
83
+ // if (offsetY < 0) { offsetY = 0 }
84
+ // if (offsetX > 1) { offsetX = 1 }
85
+ // if (offsetY > 1) { offsetY = 1 }
86
+ sourceRect ??= {
87
+ left: 0,
88
+ top: 0,
89
+ width: img instanceof HTMLVideoElement ? img.videoWidth : img.width,
90
+ height: img instanceof HTMLVideoElement ? img.videoHeight : img.height,
91
+ };
92
+ const iw = sourceRect.width, ih = sourceRect.height, r = Math.min(w / iw, h / ih);
93
+ let nw = iw * r, // new prop. width
94
+ nh = ih * r, // new prop. height
95
+ ar = 1;
96
+ // decide which gap to fill
97
+ if (nw < w) {
98
+ ar = w / nw;
99
+ }
100
+ if (Math.abs(ar - 1) < 1e-14 && nh < h) {
101
+ ar = h / nh;
102
+ } // updated
103
+ nw *= ar;
104
+ nh *= ar;
105
+ // calc source rectangle
106
+ const cw = Math.max(iw / (nw / w), 0);
107
+ const ch = Math.max(ih / (nh / h), 0);
108
+ const cx = Math.min((iw - cw) * offsetX, iw);
109
+ const cy = Math.min((ih - ch) * offsetY, ih);
110
+ // fill image in dest. rectangle
111
+ ctx.drawImage(img, cx + sourceRect.left, cy + sourceRect.top, cw, ch, x, y, w, h);
112
+ }
113
+ }
@@ -0,0 +1,160 @@
1
+ import { spec } from '../shared';
2
+ import { deepClone } from '../utils/common-utils';
3
+ /**
4
+ * @description SDKItem 抽象基类
5
+ * @description 支持属性扩展,允许添加任意自定义属性
6
+ */
7
+ export class BaseItem {
8
+ /**
9
+ * @description 元素ID
10
+ */
11
+ id;
12
+ /**
13
+ * @description 元素名称
14
+ */
15
+ name;
16
+ /**
17
+ * @description 父节点ID
18
+ */
19
+ parentId;
20
+ /**
21
+ * @description 元素生命周期
22
+ */
23
+ duration;
24
+ /**
25
+ * @description 元素生命周期延时
26
+ */
27
+ delay;
28
+ /**
29
+ * @description 元素结束行为
30
+ */
31
+ endBehavior;
32
+ /**
33
+ * @description 是否可见
34
+ */
35
+ visible;
36
+ /**
37
+ * @description 是否处于锁定状态
38
+ */
39
+ isLocked;
40
+ /**
41
+ * @description 核心数据是否支持编辑
42
+ */
43
+ isCoreEditable;
44
+ /**
45
+ * @description 扩展属性存储(与 property 同级)
46
+ */
47
+ extension = new Map();
48
+ constructor(options) {
49
+ this.id = options.id;
50
+ this.name = options.name;
51
+ this.parentId = options.parentId;
52
+ this.duration = options.duration ?? 999;
53
+ this.delay = options.delay ?? 0;
54
+ this.endBehavior = options.endBehavior ?? spec.EndBehavior.freeze;
55
+ this.visible = options.visible ?? true;
56
+ this.isLocked = options.isLocked ?? false;
57
+ this.isCoreEditable = options.isCoreEditable;
58
+ // 处理显式扩展属性
59
+ if (options.extension) {
60
+ Object.entries(options.extension).forEach(([key, value]) => {
61
+ this.extension.set(key, value);
62
+ });
63
+ }
64
+ }
65
+ get pixelWidth() {
66
+ return this.property.width * (this.property.scale?.[0] ?? 1);
67
+ }
68
+ get pixelHeight() {
69
+ return this.property.height * (this.property.scale?.[1] ?? 1);
70
+ }
71
+ // ==================== 扩展属性支持 ====================
72
+ /**
73
+ * @description 设置扩展属性
74
+ * @param key 属性名
75
+ * @param value 属性值
76
+ */
77
+ setExtension(key, value) {
78
+ this.extension.set(key, value);
79
+ }
80
+ /**
81
+ * @description 获取扩展属性
82
+ * @param key 属性名
83
+ * @returns 属性值
84
+ */
85
+ getExtension(key) {
86
+ return this.extension.get(key);
87
+ }
88
+ /**
89
+ * @description 检查是否存在指定扩展属性
90
+ * @param key 属性名
91
+ * @returns 是否存在
92
+ */
93
+ hasExtension(key) {
94
+ return this.extension.has(key);
95
+ }
96
+ /**
97
+ * @description 删除扩展属性
98
+ * @param key 属性名
99
+ * @returns 是否删除成功
100
+ */
101
+ deleteExtension(key) {
102
+ return this.extension.delete(key);
103
+ }
104
+ /**
105
+ * @description 获取所有扩展属性的键名列表
106
+ * @returns 键名数组
107
+ */
108
+ getExtensionKeys() {
109
+ return Array.from(this.extension.keys());
110
+ }
111
+ /**
112
+ * @description 获取所有扩展属性
113
+ * @returns 扩展属性对象
114
+ */
115
+ getAllExtension() {
116
+ return deepClone(Object.fromEntries(this.extension.entries()));
117
+ }
118
+ /**
119
+ * @description 批量设置扩展属性
120
+ * @param extensions 扩展属性对象
121
+ */
122
+ setExtensions(extensions) {
123
+ Object.entries(extensions).forEach(([key, value]) => {
124
+ this.extension.set(key, value);
125
+ });
126
+ }
127
+ /**
128
+ * @description 清空所有扩展属性
129
+ */
130
+ clearExtension() {
131
+ this.extension.clear();
132
+ }
133
+ // ==================== 通用方法 ====================
134
+ /**
135
+ * @description 获取基础属性的 JSON 对象,转换为普通对象(用于序列化)
136
+ * @returns 普通对象
137
+ */
138
+ toJSON() {
139
+ return {
140
+ id: this.id,
141
+ name: this.name,
142
+ type: this.type,
143
+ parentId: this.parentId,
144
+ duration: this.duration,
145
+ delay: this.delay,
146
+ endBehavior: this.endBehavior,
147
+ isLocked: this.isLocked,
148
+ property: deepClone(this.property),
149
+ extension: this.getAllExtension()
150
+ };
151
+ }
152
+ }
153
+ /**
154
+ * @description 类型守卫函数:检查对象是否是 BaseItem
155
+ * @param obj 要检查的对象
156
+ * @returns 是否是 BaseItem 实例
157
+ */
158
+ export function isBaseItem(obj) {
159
+ return obj instanceof BaseItem;
160
+ }
@@ -0,0 +1,131 @@
1
+ import { SDKItemType } from './types';
2
+ import { BaseItem } from './base-item';
3
+ import { deepClone } from '../utils/common-utils';
4
+ import { generateGUID } from '../shared';
5
+ import { SDK } from '../sdk';
6
+ /**
7
+ * @description 卡片元素 SDKItem 类
8
+ * @description 在 Player 中以 SpriteItem 形式渲染(透明占位,无图)
9
+ * @description 支持设置卡片类型(cardType)
10
+ */
11
+ export class CardItem extends BaseItem {
12
+ /**
13
+ * @description 元素类型
14
+ */
15
+ type = SDKItemType.CARD;
16
+ /**
17
+ * @description 元素属性(包含 cardType)
18
+ */
19
+ property;
20
+ constructor(options) {
21
+ super(options);
22
+ // 初始化属性(包含 cardType)
23
+ this.property = {
24
+ position: options.property?.position ?? [0, 0],
25
+ rotation: options.property?.rotation ?? [0, 0, 0],
26
+ width: options.property?.width ?? 0,
27
+ height: options.property?.height ?? 0,
28
+ scale: options.property?.scale ?? [1, 1],
29
+ cardType: options.property?.cardType ?? 'unknown',
30
+ };
31
+ }
32
+ // ==================== cardType 访问器 ====================
33
+ /**
34
+ * @description 卡片类型
35
+ */
36
+ get cardType() {
37
+ return this.property.cardType;
38
+ }
39
+ set cardType(value) {
40
+ this.property.cardType = value;
41
+ }
42
+ // ==================== 便捷访问器 ====================
43
+ /**
44
+ * @description 位置
45
+ */
46
+ get position() {
47
+ return this.property.position;
48
+ }
49
+ set position(value) {
50
+ this.property.position = value;
51
+ }
52
+ get isAutoScale() {
53
+ const config = SDK.config.itemConfig.cardConfig.cardTypes.find(t => t.type === this.cardType);
54
+ return config?.autoScale !== false;
55
+ }
56
+ /**
57
+ * @description 宽度
58
+ */
59
+ get width() {
60
+ return this.property.width;
61
+ }
62
+ set width(value) {
63
+ this.property.width = value;
64
+ }
65
+ /**
66
+ * @description 高度
67
+ */
68
+ get height() {
69
+ return this.property.height;
70
+ }
71
+ set height(value) {
72
+ this.property.height = value;
73
+ }
74
+ /**
75
+ * @description 旋转(二维旋转角度)
76
+ */
77
+ get rotation() {
78
+ return this.property.rotation[2];
79
+ }
80
+ set rotation(value) {
81
+ this.property.rotation[2] = value;
82
+ }
83
+ /**
84
+ * @description 完整旋转(包含 x, y, z)
85
+ */
86
+ get fullRotation() {
87
+ return this.property.rotation;
88
+ }
89
+ set fullRotation(value) {
90
+ this.property.rotation = value;
91
+ }
92
+ // ==================== 实现抽象方法 ====================
93
+ /**
94
+ * @description 转换为 CardCreateInfo
95
+ * @param withParent 是否包含父节点ID
96
+ */
97
+ toCreateInfo(withParent) {
98
+ const extension = this.getAllExtension();
99
+ return {
100
+ type: SDKItemType.CARD,
101
+ id: this.id,
102
+ name: this.name,
103
+ parentId: withParent ? this.parentId : undefined,
104
+ extension: Object.keys(extension).length > 0 ? extension : undefined,
105
+ property: deepClone(this.property)
106
+ };
107
+ }
108
+ /**
109
+ * @description 克隆 SDKItem
110
+ */
111
+ clone() {
112
+ return new CardItem({
113
+ id: generateGUID(),
114
+ name: this.name,
115
+ parentId: this.parentId,
116
+ duration: this.duration,
117
+ delay: this.delay,
118
+ endBehavior: this.endBehavior,
119
+ isLocked: this.isLocked,
120
+ isCoreEditable: this.isCoreEditable,
121
+ property: deepClone(this.property),
122
+ extension: this.getAllExtension()
123
+ });
124
+ }
125
+ }
126
+ /**
127
+ * @description 类型守卫:检查是否是 CardItem
128
+ */
129
+ export function isCardItem(obj) {
130
+ return obj instanceof CardItem;
131
+ }
@@ -0,0 +1,144 @@
1
+ import { SDKItemType } from './types';
2
+ import { BaseItem } from './base-item';
3
+ import { deepClone } from '../utils/common-utils';
4
+ import { generateGUID } from '../shared';
5
+ /**
6
+ * @description 特效产物 元素 SDKItem 类
7
+ */
8
+ export class EffectsItem extends BaseItem {
9
+ /**
10
+ * @description 元素类型(独立类型,不属于 spec.ItemType)
11
+ */
12
+ type = SDKItemType.EFFECTS;
13
+ /**
14
+ * @description 预合成元素ID
15
+ */
16
+ subCompositionItemId;
17
+ /**
18
+ * @description 元素属性
19
+ */
20
+ property;
21
+ constructor(options) {
22
+ super(options);
23
+ this.subCompositionItemId = '';
24
+ this.property = {
25
+ position: options.property?.position ?? [0, 0],
26
+ rotation: options.property?.rotation ?? [0, 0, 0],
27
+ width: options.property?.width ?? 0,
28
+ height: options.property?.height ?? 0,
29
+ scale: options.property?.scale ?? [1, 1],
30
+ effects: options.property?.effects ?? '',
31
+ children: options.property?.children ?? []
32
+ };
33
+ }
34
+ // ==================== 便捷访问器 ====================
35
+ /**
36
+ * @description 特效资源地址
37
+ */
38
+ get effects() {
39
+ return this.property.effects;
40
+ }
41
+ set effects(value) {
42
+ this.property.effects = value;
43
+ }
44
+ /**
45
+ * @description 位置
46
+ */
47
+ get position() {
48
+ return this.property.position;
49
+ }
50
+ set position(value) {
51
+ this.property.position = value;
52
+ }
53
+ /**
54
+ * @description 宽度
55
+ */
56
+ get width() {
57
+ return this.property.width;
58
+ }
59
+ set width(value) {
60
+ this.property.width = value;
61
+ }
62
+ /**
63
+ * @description 高度
64
+ */
65
+ get height() {
66
+ return this.property.height;
67
+ }
68
+ set height(value) {
69
+ this.property.height = value;
70
+ }
71
+ /**
72
+ * @description 旋转(二维旋转角度)
73
+ */
74
+ get rotation() {
75
+ return this.property.rotation[2];
76
+ }
77
+ set rotation(value) {
78
+ this.property.rotation[2] = value;
79
+ }
80
+ /**
81
+ * @description 完整旋转(包含 x, y, z)
82
+ */
83
+ get fullRotation() {
84
+ return this.property.rotation;
85
+ }
86
+ set fullRotation(value) {
87
+ this.property.rotation = value;
88
+ }
89
+ /**
90
+ * @description 是否正在编辑关键属性
91
+ * @deprecated 该属性即将废弃,使用 isCoreEditable 代替
92
+ */
93
+ get keyPropertyEditing() {
94
+ return this.isCoreEditable;
95
+ }
96
+ set keyPropertyEditing(value) {
97
+ this.isCoreEditable = value;
98
+ }
99
+ // ==================== 实现抽象方法 ====================
100
+ /**
101
+ * @description 转换为 EffectsCreateInfo
102
+ * @param withParent 是否包含父节点ID
103
+ */
104
+ toCreateInfo(withParent) {
105
+ const createInfo = {
106
+ type: SDKItemType.EFFECTS,
107
+ id: this.id,
108
+ name: this.name,
109
+ property: deepClone(this.property)
110
+ };
111
+ if (withParent && this.parentId) {
112
+ createInfo.parentId = this.parentId;
113
+ }
114
+ // 添加扩展属性
115
+ const extension = this.getAllExtension();
116
+ if (Object.keys(extension).length > 0) {
117
+ createInfo.extension = extension;
118
+ }
119
+ return createInfo;
120
+ }
121
+ /**
122
+ * @description 克隆 SDKItem
123
+ */
124
+ clone() {
125
+ return new EffectsItem({
126
+ id: generateGUID(),
127
+ name: this.name,
128
+ parentId: this.parentId,
129
+ duration: this.duration,
130
+ delay: this.delay,
131
+ endBehavior: this.endBehavior,
132
+ isLocked: this.isLocked,
133
+ isCoreEditable: this.isCoreEditable,
134
+ property: deepClone(this.property),
135
+ extension: this.getAllExtension()
136
+ });
137
+ }
138
+ }
139
+ /**
140
+ * @description 类型守卫:检查是否是 EffectsItem
141
+ */
142
+ export function isEffectsItem(obj) {
143
+ return obj instanceof EffectsItem;
144
+ }