@vvfx/sdk 0.2.8 → 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.
- package/dist/config.js +231 -0
- package/dist/exporter/config.js +18 -0
- package/dist/exporter/const.js +71 -0
- package/dist/exporter/export-media.js +878 -0
- package/dist/exporter/exporter.js +121 -0
- package/dist/exporter/index.js +1 -0
- package/dist/exporter/types.js +1 -0
- package/dist/exporter/utils.js +190 -0
- package/dist/exporter/wav-audio.js +50 -0
- package/dist/gesture-handler/gizmo/adsorption-gizmo.js +227 -0
- package/dist/gesture-handler/gizmo/control-gizmo.js +149 -0
- package/dist/gesture-handler/gizmo/gizmo.js +17 -0
- package/dist/gesture-handler/gizmo/icon-gizmo.js +189 -0
- package/dist/gesture-handler/gizmo/index.js +6 -0
- package/dist/gesture-handler/gizmo/item-create-gizmo.js +256 -0
- package/dist/gesture-handler/gizmo/loading-gizmo.js +320 -0
- package/dist/gesture-handler/gizmo/mask-gizmo.js +648 -0
- package/dist/gesture-handler/gizmo/picture-cut-gizmo.js +550 -0
- package/dist/gesture-handler/gizmo/picture-expand-gizmo.js +491 -0
- package/dist/gesture-handler/gizmo/preference-gizmo.js +148 -0
- package/dist/gesture-handler/gizmo/selector-gizmo.d.ts +1 -1
- package/dist/gesture-handler/gizmo/selector-gizmo.js +468 -0
- package/dist/gesture-handler/gizmo/sprite-text-edit-gizmo.js +247 -0
- package/dist/gesture-handler/gizmo/text-gizmo.js +1033 -0
- package/dist/gesture-handler/gizmo/transform-gizmo.js +1199 -0
- package/dist/gesture-handler/gizmo/type.js +18 -0
- package/dist/gesture-handler/index.js +3 -0
- package/dist/gesture-handler/src/gesture-handler.js +770 -0
- package/dist/gesture-handler/src/icons.js +24 -0
- package/dist/gesture-handler/utils.js +40 -0
- package/dist/html-overlay/anchor-navigation-runtime.js +27 -0
- package/dist/html-overlay/auto-height-runtime.js +132 -0
- package/dist/html-overlay/document-runtime.js +71 -0
- package/dist/html-overlay/document-transform.js +96 -0
- package/dist/html-overlay/dom-order.js +8 -0
- package/dist/html-overlay/host-message-runtime.js +24 -0
- package/dist/html-overlay/html-capture-runtime.js +282 -0
- package/dist/html-overlay/html-viewport-style.js +10 -0
- package/dist/html-overlay/index.js +1 -0
- package/dist/html-overlay/manager.js +1663 -0
- package/dist/html-overlay/mime-utils.js +21 -0
- package/dist/html-overlay/overlay-transform.js +57 -0
- package/dist/html-overlay/path-utils.js +35 -0
- package/dist/html-overlay/shell-runtime.js +12 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -75311
- package/dist/index.mjs +75311 -0
- package/dist/{index.js.map → index.mjs.map} +1 -1
- package/dist/layer-order.js +8 -0
- package/dist/math/box2.js +396 -0
- package/dist/math/circle.js +131 -0
- package/dist/math/euler.js +35 -0
- package/dist/math/index.js +13 -0
- package/dist/math/line2.js +153 -0
- package/dist/math/line3.js +36 -0
- package/dist/math/matrix4.js +207 -0
- package/dist/math/plane.js +52 -0
- package/dist/math/quaternion.js +3 -0
- package/dist/math/ray-caster.js +25 -0
- package/dist/math/ray.js +47 -0
- package/dist/math/type.js +1 -0
- package/dist/math/utils.js +77 -0
- package/dist/math/vector2.js +70 -0
- package/dist/math/vector3.js +60 -0
- package/dist/screen-shot/index.js +1 -0
- package/dist/screen-shot/screen-shot.js +113 -0
- package/dist/sdk-item/base-item.js +160 -0
- package/dist/sdk-item/card-item.js +131 -0
- package/dist/sdk-item/effects-item.js +144 -0
- package/dist/sdk-item/frame-item.js +217 -0
- package/dist/sdk-item/generator-item.js +188 -0
- package/dist/sdk-item/group-item.js +116 -0
- package/dist/sdk-item/index.js +39 -0
- package/dist/sdk-item/sprite-item.js +147 -0
- package/dist/sdk-item/text-item.js +223 -0
- package/dist/sdk-item/types.d.ts +1 -1
- package/dist/sdk-item/types.js +15 -0
- package/dist/sdk-item/video-item.js +174 -0
- package/dist/sdk.js +1903 -0
- package/dist/service/UndoRedo.js +79 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +2 -0
- package/dist/shared/player.d.ts +1 -1
- package/dist/shared/player.js +9 -0
- package/dist/shared/spec.d.ts +1 -0
- package/dist/shared/spec.js +1 -0
- package/dist/size-adapte/index.js +1 -0
- package/dist/size-adapte/size-adapt.js +395 -0
- package/dist/types.d.ts +5 -1
- package/dist/types.js +17 -0
- package/dist/utils/background-manager.js +189 -0
- package/dist/utils/common-utils.js +183 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/interaction-utils.js +205 -0
- package/dist/utils/json-data-utils.js +1529 -0
- package/dist/utils/layout-utils.js +1217 -0
- package/dist/utils/page-data-utils.js +5397 -0
- package/dist/utils/player-data-utils.js +48 -0
- package/dist/utils/types.js +8 -0
- package/dist/wireframe/common/box.js +18 -0
- package/dist/wireframe/common/dashed-line.js +21 -0
- package/dist/wireframe/common/line.js +17 -0
- package/dist/wireframe/common/pixi-ext.js +1 -0
- package/dist/wireframe/common/pixi.js +31 -0
- package/dist/wireframe/index.js +4 -0
- package/package.json +10 -3
|
@@ -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
|
+
}
|