@vvfx/sdk 0.2.8 → 0.2.10
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-layout.d.ts +6 -0
- package/dist/html-overlay/auto-height-layout.js +7 -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.d.ts +1 -0
- package/dist/html-overlay/manager.js +1677 -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 +34 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -75311
- package/dist/index.mjs +75337 -0
- package/dist/index.mjs.map +1 -0
- 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 +1908 -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
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通用撤销重做类,支持任意数据类型
|
|
3
|
+
*/
|
|
4
|
+
export class GizmoUndoRedo {
|
|
5
|
+
// 下标
|
|
6
|
+
index = -1;
|
|
7
|
+
// 操作记录
|
|
8
|
+
operations = [];
|
|
9
|
+
get canUndo() {
|
|
10
|
+
return this.index > -1;
|
|
11
|
+
}
|
|
12
|
+
get canRedo() {
|
|
13
|
+
return this.index < this.operations.length - 1;
|
|
14
|
+
}
|
|
15
|
+
push(operation) {
|
|
16
|
+
this.index++;
|
|
17
|
+
this.operations[this.index] = operation;
|
|
18
|
+
// 将 operation 列表后面的内容清理掉
|
|
19
|
+
this.operations.length = this.index + 1;
|
|
20
|
+
}
|
|
21
|
+
undo() {
|
|
22
|
+
if (this.index < 0) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const result = this.operations[this.index];
|
|
26
|
+
this.index--;
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
redo() {
|
|
30
|
+
if (this.index >= this.operations.length - 1) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.index++;
|
|
34
|
+
return this.operations[this.index];
|
|
35
|
+
}
|
|
36
|
+
clear() {
|
|
37
|
+
this.operations = [];
|
|
38
|
+
this.index = -1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export class UndoRedo {
|
|
42
|
+
// 下标
|
|
43
|
+
index = -1;
|
|
44
|
+
// 操作记录
|
|
45
|
+
operations = [];
|
|
46
|
+
get canUndo() {
|
|
47
|
+
return this.index > -1;
|
|
48
|
+
}
|
|
49
|
+
get canRedo() {
|
|
50
|
+
return this.index < this.operations.length - 1;
|
|
51
|
+
}
|
|
52
|
+
// 存储变更前的数据
|
|
53
|
+
oldData;
|
|
54
|
+
push(operation) {
|
|
55
|
+
this.index++;
|
|
56
|
+
this.operations[this.index] = operation;
|
|
57
|
+
// 将 operation 列表后面的内容清理掉
|
|
58
|
+
this.operations.length = this.index + 1;
|
|
59
|
+
}
|
|
60
|
+
undo() {
|
|
61
|
+
if (this.index < 0) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const result = this.operations[this.index];
|
|
65
|
+
this.index--;
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
redo() {
|
|
69
|
+
if (this.index >= this.operations.length - 1) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.index++;
|
|
73
|
+
return this.operations[this.index];
|
|
74
|
+
}
|
|
75
|
+
clear() {
|
|
76
|
+
this.operations = [];
|
|
77
|
+
this.index = -1;
|
|
78
|
+
}
|
|
79
|
+
}
|
package/dist/shared/index.d.ts
CHANGED
package/dist/shared/player.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@galacean/effects';
|
|
2
|
-
export {
|
|
2
|
+
export { VFXItem, Player, math, Composition, type Region, EventEmitter, assertExist, SpriteComponent, TextComponent, Texture, generateGUID, version as PlayerVersion } from '@galacean/effects';
|
|
3
3
|
import '@galacean/effects-plugin-rich-text';
|
|
4
4
|
export { RichTextComponent } from '@galacean/effects-plugin-rich-text';
|
|
5
5
|
import '@galacean/effects-plugin-model';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import '@galacean/effects';
|
|
2
|
+
export { VFXItem, Player, math, Composition, EventEmitter, assertExist, SpriteComponent, TextComponent, Texture, generateGUID, version as PlayerVersion } from '@galacean/effects';
|
|
3
|
+
import '@galacean/effects-plugin-rich-text';
|
|
4
|
+
export { RichTextComponent } from '@galacean/effects-plugin-rich-text';
|
|
5
|
+
import '@galacean/effects-plugin-model';
|
|
6
|
+
import '@galacean/effects-plugin-multimedia';
|
|
7
|
+
export { VideoComponent } from '@galacean/effects-plugin-multimedia';
|
|
8
|
+
import '@galacean/effects-plugin-spine';
|
|
9
|
+
import '@galacean/effects-plugin-ffd';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { spec } from '@galacean/effects';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { spec } from '@galacean/effects';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './size-adapt';
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { Box2, Matrix4, Vector2, Vector3 } from '../math';
|
|
2
|
+
import { SDK } from '../sdk';
|
|
3
|
+
import { Player, spec } from '../shared';
|
|
4
|
+
import { clearPlayerAssets } from '../exporter/utils';
|
|
5
|
+
import { SafeConstraint } from '../utils/types';
|
|
6
|
+
/**
|
|
7
|
+
* @description 尺寸适配工具
|
|
8
|
+
*/
|
|
9
|
+
export class SizeAdapt {
|
|
10
|
+
/**
|
|
11
|
+
* @description 尺寸适配播放器
|
|
12
|
+
*/
|
|
13
|
+
_player;
|
|
14
|
+
/**
|
|
15
|
+
* @description 尺寸播放器容器
|
|
16
|
+
*/
|
|
17
|
+
_container;
|
|
18
|
+
/**
|
|
19
|
+
* @description 视图大小
|
|
20
|
+
*/
|
|
21
|
+
size = [0, 0];
|
|
22
|
+
constructor() {
|
|
23
|
+
this._container = document.createElement('canvas');
|
|
24
|
+
this._player = new Player({
|
|
25
|
+
canvas: this._container,
|
|
26
|
+
manualRender: true,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async adjustment(scene, tick, originSize, viewSize, safeArea, direction) {
|
|
30
|
+
if (!SDK.config.sizeAdaptConfig.enabled) {
|
|
31
|
+
console.warn('Size adapt is not opened, use #SDK.setConfig() open this feature.');
|
|
32
|
+
return scene;
|
|
33
|
+
}
|
|
34
|
+
this._player ??= new Player({
|
|
35
|
+
canvas: this._container,
|
|
36
|
+
manualRender: true,
|
|
37
|
+
});
|
|
38
|
+
safeArea ??= [0, 0, 0, 0];
|
|
39
|
+
direction ??= originSize[0] < originSize[1] ? 'y' : 'x';
|
|
40
|
+
this.size = [...viewSize];
|
|
41
|
+
this._container.width = this.size[0];
|
|
42
|
+
this._container.height = this.size[1];
|
|
43
|
+
clearPlayerAssets(this._player);
|
|
44
|
+
this._player.resize();
|
|
45
|
+
const loadScene = JSON.parse(JSON.stringify(scene));
|
|
46
|
+
await this._player.loadScene(loadScene, {
|
|
47
|
+
reusable: true,
|
|
48
|
+
autoplay: false,
|
|
49
|
+
});
|
|
50
|
+
this._player.gotoAndStop(tick);
|
|
51
|
+
const composition = this._player.getCompositions()[0];
|
|
52
|
+
if (composition) {
|
|
53
|
+
const [viewWidth, viewHeight] = viewSize;
|
|
54
|
+
const originRatio = originSize[0] / originSize[1];
|
|
55
|
+
const viewRatio = viewWidth / viewHeight;
|
|
56
|
+
if (originRatio > viewRatio) {
|
|
57
|
+
this.keepDistribute(scene, composition, viewRatio / originRatio, viewSize);
|
|
58
|
+
}
|
|
59
|
+
const [safeTop, safeBottom, safeLeft, safeRight] = safeArea;
|
|
60
|
+
const width = viewWidth - safeLeft - safeRight;
|
|
61
|
+
const height = viewHeight - safeTop - safeBottom;
|
|
62
|
+
const translation = [(safeLeft - safeRight) / 2, (safeTop - safeBottom) / 2];
|
|
63
|
+
const originViewBox = new Box2().setFromCenterAndSize(new Vector2(viewWidth, viewHeight).divide(2), new Vector2(viewWidth, viewHeight));
|
|
64
|
+
const resultViewBox = new Box2().setFromCenterAndSize(new Vector2(viewWidth, viewHeight).divide(2).add(new Vector2(...translation)), new Vector2(width, height));
|
|
65
|
+
// 纵向吸附自适应规则
|
|
66
|
+
this.keepAdsorption('topAdsorption', scene, composition, translation, originViewBox, resultViewBox, direction);
|
|
67
|
+
this.keepAdsorption('bottomAdsorption', scene, composition, translation, originViewBox, resultViewBox, direction);
|
|
68
|
+
// 横向吸附自适应规则
|
|
69
|
+
this.keepAdsorption('leftAdsorption', scene, composition, translation, originViewBox, resultViewBox, direction);
|
|
70
|
+
this.keepAdsorption('rightAdsorption', scene, composition, translation, originViewBox, resultViewBox, direction);
|
|
71
|
+
// 中心自适应规则
|
|
72
|
+
this.keepAdsorption('centerAdsorption', scene, composition, translation, originViewBox, resultViewBox, direction);
|
|
73
|
+
this.keepDoubleAdsorption('bottomCenterAdsorption', scene, composition, translation, originViewBox, resultViewBox, direction);
|
|
74
|
+
}
|
|
75
|
+
return scene;
|
|
76
|
+
}
|
|
77
|
+
// 根据宽高比变化,保持物体垂直排布
|
|
78
|
+
keepDistribute(scene, composition, ratio, viewSize) {
|
|
79
|
+
const translateByPixel = (item, x, y) => {
|
|
80
|
+
const { z } = item.transform.getWorldPosition();
|
|
81
|
+
const { x: rx, y: ry } = composition.camera.getInverseVPRatio(z);
|
|
82
|
+
item.transform.translate(2 * x * rx / viewSize[0], -2 * y * ry / viewSize[1], 0);
|
|
83
|
+
};
|
|
84
|
+
const projectPoint = (point) => {
|
|
85
|
+
const vpMatrix = new Matrix4().copyFrom(composition.camera.getViewProjectionMatrix());
|
|
86
|
+
const viewPoint = new Vector2().copyFrom(point.applyMatrix(vpMatrix).toVector2()).toViewCoordinate(viewSize[0], viewSize[1]);
|
|
87
|
+
return viewPoint;
|
|
88
|
+
};
|
|
89
|
+
// 根据ratio以及当前的视图宽高模拟原视图中位置
|
|
90
|
+
['topAdsorption', 'centerAdsorption', 'bottomAdsorption'].forEach((type) => {
|
|
91
|
+
//@ts-expect-error type to fix
|
|
92
|
+
const targetItems = composition.items.filter(item => item.name.split('-')[0]?.toLocaleUpperCase() === SafeConstraint[type] && !item.parentId);
|
|
93
|
+
targetItems.forEach(item => {
|
|
94
|
+
const childrenItems = composition.items.filter(i => i.parentId === item.getInstanceId());
|
|
95
|
+
const checkBoxItem = childrenItems.find(item => item.name === 'check-area');
|
|
96
|
+
const startCheckBox = checkBoxItem
|
|
97
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
98
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
99
|
+
const startPosition = item.transform.position.clone();
|
|
100
|
+
const itemCenter = startCheckBox.getCenter();
|
|
101
|
+
const viewCenter = new Vector2(...viewSize.map(n => n / 2));
|
|
102
|
+
const currentDistance = itemCenter.y - viewCenter.y;
|
|
103
|
+
const resultDistance = currentDistance / ratio;
|
|
104
|
+
const shift = resultDistance - currentDistance;
|
|
105
|
+
translateByPixel(item, 0, shift);
|
|
106
|
+
item.transform.updateLocalMatrix();
|
|
107
|
+
const resultPosition = item.transform.position.clone();
|
|
108
|
+
const translationShift = resultPosition.subtract(startPosition).toArray();
|
|
109
|
+
this.transformSceneItem(scene, item.getInstanceId(), 'position', translationShift);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
keepAdsorption(type, scene, composition, translation, originViewBox, resultViewBox, adsorptionDirection) {
|
|
114
|
+
const { x: originWidth, y: originHeight } = originViewBox.getSize();
|
|
115
|
+
const translateByPixel = (item, x, y) => {
|
|
116
|
+
const { z } = item.transform.getWorldPosition();
|
|
117
|
+
const { x: rx, y: ry } = composition.camera.getInverseVPRatio(z);
|
|
118
|
+
item.transform.translate(2 * x * rx / originWidth, -2 * y * ry / originHeight, 0);
|
|
119
|
+
};
|
|
120
|
+
const projectPoint = (point) => {
|
|
121
|
+
const vpMatrix = new Matrix4().copyFrom(composition.camera.getViewProjectionMatrix());
|
|
122
|
+
const viewPoint = new Vector2().copyFrom(point.applyMatrix(vpMatrix).toVector2()).toViewCoordinate(originWidth, originHeight);
|
|
123
|
+
return viewPoint;
|
|
124
|
+
};
|
|
125
|
+
const keyWord = SafeConstraint[type];
|
|
126
|
+
const targetItems = composition.items.filter(item => item.name.split('-')[0]?.toLocaleUpperCase() === keyWord && !item.parentId);
|
|
127
|
+
targetItems.forEach(item => {
|
|
128
|
+
const childrenItems = composition.items.filter(i => i.parentId === item.getInstanceId());
|
|
129
|
+
const checkBoxItem = childrenItems.find(item => item.name === 'check-area');
|
|
130
|
+
const startPosition = item.transform.position.clone();
|
|
131
|
+
const direction = ['leftAdsorption', 'rightAdsorption'].includes(type) ? 'x' : 'y';
|
|
132
|
+
const directionScale = ['leftAdsorption', 'topAdsorption'].includes(type) ? 1 : -1;
|
|
133
|
+
const constraint = ['leftAdsorption', 'topAdsorption'].includes(type) ? 'min' : 'max';
|
|
134
|
+
const ratioConstraint = ['leftAdsorption', 'topAdsorption'].includes(type) ? 'max' : 'min';
|
|
135
|
+
const ratioConstraintEnabled = item.name.split('-').length === 3;
|
|
136
|
+
const ratioConstraintValue = Number(item.name.split('-')[1]);
|
|
137
|
+
const ratioShift = new Vector2();
|
|
138
|
+
const scaleShift = [1, 1];
|
|
139
|
+
// 场景自适应规则 - 跟随出血区位移与缩放
|
|
140
|
+
const startCheckBox = checkBoxItem
|
|
141
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
142
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
143
|
+
translateByPixel(item, ...translation);
|
|
144
|
+
const scaleDirection = adsorptionDirection === 'y' ? 'x' : 'y';
|
|
145
|
+
if (startCheckBox.getSize()[scaleDirection] > resultViewBox.getSize()[scaleDirection]) {
|
|
146
|
+
scaleShift[0] = resultViewBox.getSize()[scaleDirection] / startCheckBox.getSize()[scaleDirection];
|
|
147
|
+
scaleShift[1] = resultViewBox.getSize()[scaleDirection] / startCheckBox.getSize()[scaleDirection];
|
|
148
|
+
item.scale(...scaleShift, 1);
|
|
149
|
+
}
|
|
150
|
+
item.transform.updateLocalMatrix();
|
|
151
|
+
// 包含约束 - 确保元素位于安全区
|
|
152
|
+
const afterBaseCheckBox = checkBoxItem
|
|
153
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
154
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
155
|
+
const constraintOffset = new Vector2();
|
|
156
|
+
if (!resultViewBox.containsBox(afterBaseCheckBox)) {
|
|
157
|
+
const { min: afterBaseCheckBoxMin, max: afterBaseCheckBoxMax } = afterBaseCheckBox;
|
|
158
|
+
const { min: resultViewBoxMin, max: resultViewBoxMax } = resultViewBox;
|
|
159
|
+
constraintOffset.x += afterBaseCheckBoxMin.x < resultViewBoxMin.x ? resultViewBoxMin.x - afterBaseCheckBoxMin.x : 0;
|
|
160
|
+
constraintOffset.x += afterBaseCheckBoxMax.x > resultViewBoxMax.x ? resultViewBoxMax.x - afterBaseCheckBoxMax.x : 0;
|
|
161
|
+
constraintOffset.y += afterBaseCheckBoxMin.y < resultViewBoxMin.y ? resultViewBoxMin.y - afterBaseCheckBoxMin.y : 0;
|
|
162
|
+
constraintOffset.y += afterBaseCheckBoxMax.y > resultViewBoxMax.y ? resultViewBoxMax.y - afterBaseCheckBoxMax.y : 0;
|
|
163
|
+
translateByPixel(item, ...constraintOffset.toArray());
|
|
164
|
+
item.transform.updateLocalMatrix();
|
|
165
|
+
}
|
|
166
|
+
// 比例约束 - 确保元素占比满足比例约束
|
|
167
|
+
const afterContainCheckBox = checkBoxItem
|
|
168
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
169
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
170
|
+
if (!Number.isNaN(ratioConstraintValue) && ratioConstraintEnabled) {
|
|
171
|
+
if (type !== 'centerAdsorption') {
|
|
172
|
+
const scaleConstraintDistance = Math.abs(afterContainCheckBox[ratioConstraint][direction] - resultViewBox[constraint][direction]);
|
|
173
|
+
const scaleDistance = resultViewBox.getSize()[direction] * ratioConstraintValue;
|
|
174
|
+
if (scaleConstraintDistance > scaleDistance) {
|
|
175
|
+
ratioShift[direction] = (scaleDistance - scaleConstraintDistance) * directionScale;
|
|
176
|
+
translateByPixel(item, ...ratioShift.toArray());
|
|
177
|
+
item.transform.updateLocalMatrix();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
const size = afterContainCheckBox.getSize()[adsorptionDirection];
|
|
182
|
+
const viewSize = resultViewBox.getSize()[adsorptionDirection];
|
|
183
|
+
if (size / viewSize > ratioConstraintValue) {
|
|
184
|
+
const ratioResultSize = viewSize * ratioConstraintValue;
|
|
185
|
+
const ratioScaleShift = ratioResultSize / size;
|
|
186
|
+
item.scale(ratioScaleShift, ratioScaleShift, 1);
|
|
187
|
+
scaleShift[0] *= ratioScaleShift;
|
|
188
|
+
scaleShift[1] *= ratioScaleShift;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// 压板遮挡规则 - 确保元素不被压板遮挡
|
|
193
|
+
const currentCheckBox = checkBoxItem
|
|
194
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
195
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
196
|
+
const topItems = composition.items.filter(item => item.name.split('-')[0]?.toLocaleUpperCase() === 'T' && !item.parentId);
|
|
197
|
+
const topBox = new Box2();
|
|
198
|
+
topItems.forEach(topItem => {
|
|
199
|
+
const topChildrenItems = composition.items.filter(i => i.parentId === topItem.getInstanceId());
|
|
200
|
+
const topCheckBoxItem = topChildrenItems.find(item => item.name === 'check-area');
|
|
201
|
+
const topCheckBox = topCheckBoxItem
|
|
202
|
+
? this.getViewBoxByHeadlessPlayerItem(topCheckBoxItem, [], projectPoint)
|
|
203
|
+
: this.getViewBoxByHeadlessPlayerItem(topItem, topChildrenItems, projectPoint);
|
|
204
|
+
topBox.union(topCheckBox);
|
|
205
|
+
});
|
|
206
|
+
if (!topBox.isEmpty() && topBox.max.y > currentCheckBox.min.y) {
|
|
207
|
+
if (type === 'centerAdsorption') {
|
|
208
|
+
const centerShift = topBox.max.y - currentCheckBox.min.y;
|
|
209
|
+
translateByPixel(item, 0, centerShift);
|
|
210
|
+
item.transform.updateLocalMatrix();
|
|
211
|
+
}
|
|
212
|
+
else if (['leftAdsorption', 'rightAdsorption'].includes(type)) {
|
|
213
|
+
const sideBoxY = currentCheckBox.getSize().y;
|
|
214
|
+
const noPlateY = resultViewBox.getSize().y - (topBox.max.y - resultViewBox.min.y);
|
|
215
|
+
let sideShift = topBox.max.y - currentCheckBox.min.y;
|
|
216
|
+
if (sideBoxY > noPlateY) {
|
|
217
|
+
const sideScale = noPlateY / sideBoxY;
|
|
218
|
+
scaleShift[0] *= sideScale;
|
|
219
|
+
scaleShift[1] *= sideScale;
|
|
220
|
+
item.scale(sideScale, sideScale, 1);
|
|
221
|
+
item.transform.updateLocalMatrix();
|
|
222
|
+
sideShift -= (sideBoxY - noPlateY) / 2;
|
|
223
|
+
}
|
|
224
|
+
translateByPixel(item, 0, sideShift);
|
|
225
|
+
item.transform.updateLocalMatrix();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const resultPosition = item.transform.position.clone();
|
|
229
|
+
const translationShift = resultPosition.subtract(startPosition).toArray();
|
|
230
|
+
this.transformSceneItem(scene, item.getInstanceId(), 'position', translationShift);
|
|
231
|
+
this.transformSceneItem(scene, item.getInstanceId(), 'scale', scaleShift);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
keepDoubleAdsorption(type, scene, composition, translation, originViewBox, resultViewBox, adsorptionDirection) {
|
|
235
|
+
const { x: originWidth, y: originHeight } = originViewBox.getSize();
|
|
236
|
+
const translateByPixel = (item, x, y) => {
|
|
237
|
+
const { z } = item.transform.getWorldPosition();
|
|
238
|
+
const { x: rx, y: ry } = composition.camera.getInverseVPRatio(z);
|
|
239
|
+
item.transform.translate(2 * x * rx / originWidth, -2 * y * ry / originHeight, 0);
|
|
240
|
+
};
|
|
241
|
+
const projectPoint = (point) => {
|
|
242
|
+
const vpMatrix = new Matrix4().copyFrom(composition.camera.getViewProjectionMatrix());
|
|
243
|
+
const viewPoint = new Vector2().copyFrom(point.applyMatrix(vpMatrix).toVector2()).toViewCoordinate(originWidth, originHeight);
|
|
244
|
+
return viewPoint;
|
|
245
|
+
};
|
|
246
|
+
const keyWord = SafeConstraint[type];
|
|
247
|
+
const targetItems = composition.items.filter(item => item.name.split('-')[0]?.toLocaleUpperCase() === keyWord && !item.parentId);
|
|
248
|
+
targetItems.forEach(item => {
|
|
249
|
+
const childrenItems = composition.items.filter(i => i.parentId === item.getInstanceId());
|
|
250
|
+
const checkBoxItem = childrenItems.find(item => item.name === 'check-area');
|
|
251
|
+
const startPosition = item.transform.position.clone();
|
|
252
|
+
const ratioConstraintEnabled = item.name.split('-').length === 3;
|
|
253
|
+
const ratioConstraintValue = Number(item.name.split('-')[1]);
|
|
254
|
+
const scaleShift = [1, 1];
|
|
255
|
+
const startCheckBox = checkBoxItem
|
|
256
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
257
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
258
|
+
translateByPixel(item, ...translation);
|
|
259
|
+
const scaleDirection = adsorptionDirection === 'y' ? 'x' : 'y';
|
|
260
|
+
if (startCheckBox.getSize()[scaleDirection] > resultViewBox.getSize()[scaleDirection]) {
|
|
261
|
+
scaleShift[0] = resultViewBox.getSize()[scaleDirection] / startCheckBox.getSize()[scaleDirection];
|
|
262
|
+
scaleShift[1] = resultViewBox.getSize()[scaleDirection] / startCheckBox.getSize()[scaleDirection];
|
|
263
|
+
item.scale(...scaleShift, 1);
|
|
264
|
+
}
|
|
265
|
+
item.transform.updateLocalMatrix();
|
|
266
|
+
// 元素元素在包围盒内
|
|
267
|
+
const checkBox = checkBoxItem
|
|
268
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
269
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
270
|
+
if (!Number.isNaN(ratioConstraintValue) && ratioConstraintEnabled) {
|
|
271
|
+
const size = checkBox.getSize()[scaleDirection];
|
|
272
|
+
const viewSize = resultViewBox.getSize()[scaleDirection];
|
|
273
|
+
if (size / viewSize > ratioConstraintValue) {
|
|
274
|
+
const ratioResultSize = viewSize * ratioConstraintValue;
|
|
275
|
+
const ratioScaleShift = ratioResultSize / size;
|
|
276
|
+
item.scale(ratioScaleShift, ratioScaleShift, 1);
|
|
277
|
+
scaleShift[0] *= ratioScaleShift;
|
|
278
|
+
scaleShift[1] *= ratioScaleShift;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// 强制吸底
|
|
282
|
+
const ratioCheckBox = checkBoxItem
|
|
283
|
+
? this.getViewBoxByHeadlessPlayerItem(checkBoxItem, [], projectPoint)
|
|
284
|
+
: this.getViewBoxByHeadlessPlayerItem(item, childrenItems, projectPoint);
|
|
285
|
+
const constraintOffset = new Vector2();
|
|
286
|
+
if (!resultViewBox.containsBox(ratioCheckBox)) {
|
|
287
|
+
const { min: checkBoxMin, max: checkBoxMax } = ratioCheckBox;
|
|
288
|
+
const { min: viewBoxMin, max: viewBoxMax } = resultViewBox;
|
|
289
|
+
constraintOffset.x += checkBoxMin.x < viewBoxMin.x ? viewBoxMin.x - checkBoxMin.x : 0;
|
|
290
|
+
constraintOffset.x += checkBoxMax.x > viewBoxMax.x ? viewBoxMax.x - checkBoxMax.x : 0;
|
|
291
|
+
constraintOffset.y += checkBoxMin.y < viewBoxMin.y ? viewBoxMin.y - checkBoxMin.y : 0;
|
|
292
|
+
constraintOffset.y += checkBoxMax.y > viewBoxMax.y ? viewBoxMax.y - checkBoxMax.y : 0;
|
|
293
|
+
// 根据比例修改缩放值,可以让元素位置更加均衡,后续有需要的时候可加
|
|
294
|
+
// constraintOffset.multiply(scaleShift[0])
|
|
295
|
+
translateByPixel(item, ...constraintOffset.toArray());
|
|
296
|
+
item.transform.updateLocalMatrix();
|
|
297
|
+
}
|
|
298
|
+
const resultPosition = item.transform.position.clone();
|
|
299
|
+
const translationShift = resultPosition.subtract(startPosition).toArray();
|
|
300
|
+
this.transformSceneItem(scene, item.getInstanceId(), 'position', translationShift);
|
|
301
|
+
this.transformSceneItem(scene, item.getInstanceId(), 'scale', scaleShift);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
getViewBoxByHeadlessPlayerItem(targetItem, childrenItem, projectPoint) {
|
|
305
|
+
const box = new Box2();
|
|
306
|
+
const { transform, composition } = targetItem;
|
|
307
|
+
switch (targetItem.type) {
|
|
308
|
+
case spec.ItemType.sprite:
|
|
309
|
+
case spec.ItemType.plugin:
|
|
310
|
+
case spec.ItemType.video:
|
|
311
|
+
case spec.ItemType.richtext:
|
|
312
|
+
case spec.ItemType.text:
|
|
313
|
+
case spec.ItemType.shape: {
|
|
314
|
+
transform.setValid(true);
|
|
315
|
+
transform.updateLocalMatrix();
|
|
316
|
+
const { size } = transform;
|
|
317
|
+
const compositionMatrix = new Matrix4().copyFrom(composition?.transform.getWorldMatrix() ?? new Matrix4()).invert();
|
|
318
|
+
const itemWorldMatrix = compositionMatrix.multiply(transform.getWorldMatrix());
|
|
319
|
+
const { x, y } = size.clone().divide(2);
|
|
320
|
+
const corner1 = new Vector3(x, y, 0).applyMatrix(itemWorldMatrix);
|
|
321
|
+
const corner2 = new Vector3(x, -y, 0).applyMatrix(itemWorldMatrix);
|
|
322
|
+
const corner3 = new Vector3(-x, -y, 0).applyMatrix(itemWorldMatrix);
|
|
323
|
+
const corner4 = new Vector3(-x, y, 0).applyMatrix(itemWorldMatrix);
|
|
324
|
+
const viewCorner1 = projectPoint(corner1).round(2);
|
|
325
|
+
const viewCorner2 = projectPoint(corner2).round(2);
|
|
326
|
+
const viewCorner3 = projectPoint(corner3).round(2);
|
|
327
|
+
const viewCorner4 = projectPoint(corner4).round(2);
|
|
328
|
+
box.setFromVec2Array([viewCorner1, viewCorner2, viewCorner3, viewCorner4]);
|
|
329
|
+
const childBoxes = childrenItem?.map(item => {
|
|
330
|
+
const childItems = composition?.items.filter(i => i.parentId === item.getInstanceId()) ?? [];
|
|
331
|
+
const childBox = this.getViewBoxByHeadlessPlayerItem(item, childItems, projectPoint);
|
|
332
|
+
return childBox;
|
|
333
|
+
});
|
|
334
|
+
if (childBoxes) {
|
|
335
|
+
childBoxes.map(b => box.union(b));
|
|
336
|
+
}
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
case spec.ItemType.null: {
|
|
340
|
+
const childBoxes = childrenItem?.map(item => {
|
|
341
|
+
const childItems = composition?.items.filter(i => i.parentId === item.getInstanceId()) ?? [];
|
|
342
|
+
const childBox = this.getViewBoxByHeadlessPlayerItem(item, childItems, projectPoint);
|
|
343
|
+
return childBox;
|
|
344
|
+
});
|
|
345
|
+
if (childBoxes) {
|
|
346
|
+
childBoxes.map(b => box.union(b));
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
default: {
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return box;
|
|
355
|
+
}
|
|
356
|
+
transformSceneItem(scene, itemId, propertyName, propertyValue) {
|
|
357
|
+
const item = scene.items.find(i => i.id === itemId);
|
|
358
|
+
switch (propertyName) {
|
|
359
|
+
case 'position': {
|
|
360
|
+
const value = propertyValue;
|
|
361
|
+
if (Array.isArray(propertyValue) && value.length === 3) {
|
|
362
|
+
if (item?.transform) {
|
|
363
|
+
item.transform.position.x += value[0];
|
|
364
|
+
item.transform.position.y += value[1];
|
|
365
|
+
item.transform.position.z += value[2];
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case 'rotation': {
|
|
371
|
+
if (Array.isArray(propertyValue) && propertyValue.length === 3) {
|
|
372
|
+
const value = propertyValue;
|
|
373
|
+
if (item?.transform) {
|
|
374
|
+
item.transform.eulerHint.x += value[0];
|
|
375
|
+
item.transform.eulerHint.y += value[1];
|
|
376
|
+
item.transform.eulerHint.z += value[2];
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
case 'scale': {
|
|
382
|
+
if (Array.isArray(propertyValue) && propertyValue.length === 2) {
|
|
383
|
+
if (item?.transform) {
|
|
384
|
+
item.transform.scale.x *= propertyValue[0];
|
|
385
|
+
item.transform.scale.y *= propertyValue[1];
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
dispose() {
|
|
393
|
+
this._player?.dispose();
|
|
394
|
+
}
|
|
395
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* 只导出类型和枚举
|
|
3
|
+
*/
|
|
4
|
+
import type { spec } from './shared/spec';
|
|
2
5
|
import { SizeAdaptDirection } from './size-adapte';
|
|
3
6
|
import type { ExportMediaItemOptions } from './exporter';
|
|
4
7
|
import { SDKItemType } from './sdk-item/types';
|
|
5
8
|
import { SDKItem } from './sdk-item';
|
|
6
9
|
import { GlobalLayoutMode } from './utils';
|
|
10
|
+
export { SDKItemType };
|
|
7
11
|
export type BaseItemProperty = {
|
|
8
12
|
position: [number, number];
|
|
9
13
|
rotation: [number, number, number];
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SDKItemType } from './sdk-item/types';
|
|
2
|
+
export { SDKItemType };
|
|
3
|
+
/**
|
|
4
|
+
* @description Frame 画板元素布局模式
|
|
5
|
+
*/
|
|
6
|
+
export var FrameLayoutMode;
|
|
7
|
+
(function (FrameLayoutMode) {
|
|
8
|
+
FrameLayoutMode["AUTO"] = "auto";
|
|
9
|
+
FrameLayoutMode["FREE"] = "free";
|
|
10
|
+
})(FrameLayoutMode || (FrameLayoutMode = {}));
|
|
11
|
+
export var ItemOrderAction;
|
|
12
|
+
(function (ItemOrderAction) {
|
|
13
|
+
ItemOrderAction[ItemOrderAction["BringToFront"] = 0] = "BringToFront";
|
|
14
|
+
ItemOrderAction[ItemOrderAction["SendToBack"] = 1] = "SendToBack";
|
|
15
|
+
ItemOrderAction[ItemOrderAction["BringForward"] = 2] = "BringForward";
|
|
16
|
+
ItemOrderAction[ItemOrderAction["SendBackward"] = 3] = "SendBackward";
|
|
17
|
+
})(ItemOrderAction || (ItemOrderAction = {}));
|