@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,149 @@
1
+ import { SDK } from '../../sdk';
2
+ import { Vector2 } from '../../math';
3
+ import { Gizmo } from './gizmo';
4
+ export class ControlGizmo extends Gizmo {
5
+ type = 'control';
6
+ _interactionType = 'mouse';
7
+ /**
8
+ * @description 是否处于交互态
9
+ */
10
+ active = false;
11
+ /**
12
+ * 上一时刻鼠标交互位置
13
+ */
14
+ lastPoint = new Vector2();
15
+ cursorResult = {
16
+ type: 'normal',
17
+ angle: 0,
18
+ };
19
+ SDKUtils;
20
+ get interactive() {
21
+ return SDK.config.gestureHandlerConfig.controlGizmoEnabled;
22
+ }
23
+ set interactive(bool) {
24
+ SDK.config.gestureHandlerConfig.controlGizmoEnabled = true;
25
+ }
26
+ get interactionType() {
27
+ return this._interactionType;
28
+ }
29
+ set interactionType(type) {
30
+ if (type !== this._interactionType) {
31
+ return;
32
+ }
33
+ this._interactionType = type;
34
+ this.refreshCursorResult();
35
+ }
36
+ constructor(utils) {
37
+ super();
38
+ this.SDKUtils = utils;
39
+ }
40
+ get useCameraControl() {
41
+ return SDK.config.mode === 'editor';
42
+ }
43
+ /**
44
+ * 行动准备事件[当buttons === 0,且在mouseMove时触发]
45
+ * @param event 鼠标事件
46
+ */
47
+ preparationAction() {
48
+ return undefined;
49
+ }
50
+ cancelPreparation() { }
51
+ refreshResults() { }
52
+ /**
53
+ * 行动前置事件[在mouseDown时触发]
54
+ * @param event 鼠标事件
55
+ */
56
+ preAction(event) {
57
+ if (this.interactionType === 'mouse') {
58
+ this.active = true;
59
+ this.lastPoint = new Vector2(event.clientX, event.clientY);
60
+ }
61
+ this.refreshCursorResult();
62
+ return this.interactionType === 'mouse' ? this.type : undefined;
63
+ }
64
+ /**
65
+ * 行动事件[当buttons !== 0,且在mouseMove时触发 || 2D模式下仅在onWheel中触发]
66
+ * @param event 鼠标事件
67
+ */
68
+ action(event) {
69
+ if (!SDK.config.gestureHandlerConfig.controlGizmoEnabled) {
70
+ console.warn('Control gizmo is not opened, use #SDK.setControlConfig() open this feature.');
71
+ return;
72
+ }
73
+ // 二维场景
74
+ const { metaKey, ctrlKey, shiftKey } = event;
75
+ if (event.buttons === 0) {
76
+ const { deltaX, deltaY, offsetX, offsetY } = event;
77
+ const shift = new Vector2(deltaX, deltaY);
78
+ // 缩放场景
79
+ if (metaKey || ctrlKey) {
80
+ const dollyCenter = this.useCameraControl ? new Vector2(offsetX, offsetY) : new Vector2();
81
+ const zoomFactor = -shift.y * SDK.config.gestureHandlerConfig.controlGizmoConfig.zoomStep;
82
+ this.SDKUtils.pageZoom(zoomFactor, dollyCenter);
83
+ }
84
+ else {
85
+ // 平移场景
86
+ // 支持触控板
87
+ shift.x = shiftKey && shift.y !== 0 ? Math.sqrt(shift.x ** 2 + shift.y ** 2) * shift.y / Math.abs(shift.y) : shift.x;
88
+ shift.y = shiftKey ? 0 : shift.y;
89
+ this.SDKUtils.pageMove(shift.negate());
90
+ }
91
+ }
92
+ else if (this.active && event instanceof MouseEvent && [1, 4].includes(event.buttons)) {
93
+ const { clientX, clientY } = event;
94
+ const currentPoint = new Vector2(clientX, clientY);
95
+ const shift = new Vector2().subtractVectors(currentPoint, this.lastPoint);
96
+ shift.x = shiftKey && shift.y !== 0 ? Math.sqrt(shift.x ** 2 + shift.y ** 2) * shift.y / Math.abs(shift.y) : shift.x;
97
+ shift.y = shiftKey ? 0 : shift.y;
98
+ this.SDKUtils.pageMove(shift);
99
+ this.lastPoint.copyFrom(currentPoint);
100
+ }
101
+ }
102
+ /**
103
+ * 行动结束事件[在mouseUp时触发]
104
+ * @param event 鼠标事件
105
+ */
106
+ endAction() {
107
+ this.active = false;
108
+ this.refreshCursorResult();
109
+ return this.interactionType === 'mouse' ? this.type : undefined;
110
+ }
111
+ /**
112
+ * 交互中断事件 - ControlGizmo交互不会被中断
113
+ * @returns this
114
+ */
115
+ interruption() {
116
+ return this.type;
117
+ }
118
+ /**
119
+ * @description 键盘交互事件
120
+ * @param keyCode 键位信息
121
+ */
122
+ actionKey() { }
123
+ /**
124
+ * @description 键盘交互结束事件
125
+ * @param keyCode 键位信息
126
+ */
127
+ endActionKey() { }
128
+ refreshCursorResult() {
129
+ if (this.interactionType === 'mouse') {
130
+ this.cursorResult = {
131
+ type: this.active ? 'active-hand' : 'hand',
132
+ angle: 0,
133
+ };
134
+ }
135
+ else {
136
+ this.cursorResult = {
137
+ type: 'normal',
138
+ angle: 0,
139
+ };
140
+ }
141
+ }
142
+ /**
143
+ * 获取辅助层渲染对象
144
+ * @returns 空
145
+ */
146
+ getRenderObjects() {
147
+ return [];
148
+ }
149
+ }
@@ -0,0 +1,17 @@
1
+ export class Gizmo {
2
+ type;
3
+ /**
4
+ * @description 是否处于交互态
5
+ */
6
+ active;
7
+ get interactive() {
8
+ return this.active;
9
+ }
10
+ set interactive(bool) {
11
+ this.active = bool;
12
+ }
13
+ constructor() {
14
+ this.type = 'null';
15
+ this.active = false;
16
+ }
17
+ }
@@ -0,0 +1,189 @@
1
+ import { Sprite } from '@pixi/sprite';
2
+ import { Gizmo } from './gizmo';
3
+ import { IconType } from './type';
4
+ import { Box2, Vector2 } from '../../math';
5
+ import { SDK } from '../../sdk';
6
+ import { SDKItemType } from '../../sdk-item/types';
7
+ import { isGeneratorItem } from '../../sdk-item';
8
+ import { Texture } from '../../wireframe';
9
+ /**
10
+ * @description 用于渲染元素辅助Icon
11
+ */
12
+ export class IconGizmo extends Gizmo {
13
+ type = 'icon';
14
+ results = [];
15
+ interactionParam = {
16
+ type: 'none'
17
+ };
18
+ textureMap;
19
+ videoPlaySpriteTexture;
20
+ videoGeneratorTexture;
21
+ imageGeneratorTexture;
22
+ cursorResult = {
23
+ type: 'normal',
24
+ angle: 0,
25
+ };
26
+ renderSprites = [];
27
+ _pageDataUtils;
28
+ _eventEmitter;
29
+ get interactive() {
30
+ return SDK.config.gestureHandlerConfig.iconGizmoEnabled;
31
+ }
32
+ set interactive(state) {
33
+ if (state === SDK.config.gestureHandlerConfig.iconGizmoEnabled) {
34
+ return;
35
+ }
36
+ SDK.config.gestureHandlerConfig.iconGizmoEnabled = state;
37
+ }
38
+ constructor(pageDataUtils, emitter) {
39
+ super();
40
+ this._pageDataUtils = pageDataUtils;
41
+ this._eventEmitter = emitter;
42
+ }
43
+ async init() {
44
+ const { imageGeneratorUrl, videoGeneratorUrl, videoPlayUrl } = SDK.config.gestureHandlerConfig.iconGizmoConfig;
45
+ this.imageGeneratorTexture = await Texture.fromURL(imageGeneratorUrl);
46
+ this.videoGeneratorTexture = await Texture.fromURL(videoGeneratorUrl);
47
+ this.videoPlaySpriteTexture = await Texture.fromURL(videoPlayUrl);
48
+ this.textureMap = {
49
+ [IconType.VIDEO_PLAY]: this.videoPlaySpriteTexture,
50
+ [IconType.IMAGE_GENERATOR]: this.imageGeneratorTexture,
51
+ [IconType.VIDEO_GENERATOR]: this.videoGeneratorTexture,
52
+ };
53
+ }
54
+ preparationAction(event) {
55
+ if (!this.interactive) {
56
+ return undefined;
57
+ }
58
+ const mouse = new Vector2(event.offsetX, event.offsetY);
59
+ this.refreshVideoIconId(mouse);
60
+ const videoPlayResult = this.results.find(result => result.type === IconType.VIDEO_PLAY);
61
+ if (videoPlayResult?.box.containsPoint(mouse)) {
62
+ this.interactionParam.type = 'preSelected';
63
+ }
64
+ else {
65
+ this.interactionParam.type = 'none';
66
+ }
67
+ this.refreshCursorResult();
68
+ return this.interactionParam.type === 'none' ? undefined : this.type;
69
+ }
70
+ preAction(event, isDoubleClick) {
71
+ const videoPlayResult = this.results.find(result => result.type === IconType.VIDEO_PLAY);
72
+ if (videoPlayResult) {
73
+ const time = this._pageDataUtils.getVideoItemPlayTime(videoPlayResult.id);
74
+ this._eventEmitter.emit('videoPlay', { id: videoPlayResult.id, time });
75
+ this.interactionParam.type = 'none';
76
+ this.refreshCursorResult();
77
+ }
78
+ return this.type;
79
+ }
80
+ action(event) { }
81
+ endAction(event) {
82
+ return undefined;
83
+ }
84
+ interruption() {
85
+ return undefined;
86
+ }
87
+ actionKey(keyCode) { }
88
+ endActionKey(keyCode) { }
89
+ cancelPreparation() { }
90
+ refreshCursorResult() {
91
+ switch (this.interactionParam.type) {
92
+ case 'none': {
93
+ this.cursorResult = {
94
+ type: 'normal',
95
+ angle: 0,
96
+ };
97
+ break;
98
+ }
99
+ case 'preSelected': {
100
+ this.cursorResult = {
101
+ type: 'pointer',
102
+ angle: 0
103
+ };
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * @description 根据鼠标位置,刷新视频播放Icon的状态
110
+ * @param mouse 鼠标位置
111
+ */
112
+ refreshVideoIconId(mouse) {
113
+ this.interactionParam.hoverVideoId = undefined;
114
+ const pageData = this._pageDataUtils.getPageData();
115
+ if (!this.interactive || !pageData) {
116
+ return;
117
+ }
118
+ const videoItems = pageData.items.filter(item => item.type === SDKItemType.VIDEO).reverse();
119
+ videoItems.forEach(item => {
120
+ if (this.interactionParam.hoverVideoId) {
121
+ return;
122
+ }
123
+ const itemViewBox = this._pageDataUtils.getViewBoxById(item.id);
124
+ if (itemViewBox.containsPoint(mouse)) {
125
+ this.interactionParam.hoverVideoId = item.id;
126
+ }
127
+ });
128
+ this.refreshResults();
129
+ }
130
+ refreshResults() {
131
+ const pageData = this._pageDataUtils.getPageData();
132
+ if (!this.interactive || !pageData) {
133
+ return;
134
+ }
135
+ this.results = [];
136
+ const generatorItems = pageData.items.filter(item => isGeneratorItem(item));
137
+ const viewScale = this._pageDataUtils.interactionUtils.viewportParam.scale;
138
+ const { videoPlayWidth, videoPlayHeight, videoPlayShift, generatorHeight, generatorWidth } = SDK.config.gestureHandlerConfig.iconGizmoConfig;
139
+ if (this.interactionParam.hoverVideoId) {
140
+ const itemViewBox = this._pageDataUtils.getViewBoxById(this.interactionParam.hoverVideoId);
141
+ const size = itemViewBox.getSize();
142
+ if (!(size.x < 50 || size.y < 100)) {
143
+ const { max } = itemViewBox;
144
+ const position = new Vector2(max.x - videoPlayShift[0], max.y - videoPlayShift[1]);
145
+ const boxSize = new Vector2(videoPlayWidth, videoPlayHeight);
146
+ this.results.push({
147
+ id: this.interactionParam.hoverVideoId,
148
+ type: IconType.VIDEO_PLAY,
149
+ box: new Box2().setFromCenterAndSize(position, boxSize)
150
+ });
151
+ }
152
+ }
153
+ generatorItems.forEach(item => {
154
+ const itemViewBox = this._pageDataUtils.getViewBoxById(item.id);
155
+ const position = itemViewBox.getCenter();
156
+ const size = new Vector2(generatorWidth, generatorHeight).multiply(viewScale);
157
+ this.results.push({
158
+ id: item.id,
159
+ type: item.generatorType === 'image' ? IconType.IMAGE_GENERATOR : IconType.VIDEO_GENERATOR,
160
+ box: new Box2().setFromCenterAndSize(position, size)
161
+ });
162
+ });
163
+ }
164
+ getRenderObjects() {
165
+ if (!this.interactive || !this.results.length) {
166
+ return [];
167
+ }
168
+ this.renderSprites.forEach(sprite => {
169
+ sprite.destroy();
170
+ });
171
+ this.renderSprites = [];
172
+ if (!this.textureMap) {
173
+ void this.init();
174
+ }
175
+ this.results.forEach(result => {
176
+ const texture = this.textureMap[result.type];
177
+ const sprite = Sprite.from(texture);
178
+ const position = result.box.getCenter();
179
+ const size = result.box.getSize();
180
+ sprite.anchor.set(0.5, 0.5);
181
+ sprite.x = position.x;
182
+ sprite.y = position.y;
183
+ sprite.width = size.x;
184
+ sprite.height = size.y;
185
+ this.renderSprites.push(sprite);
186
+ });
187
+ return this.renderSprites;
188
+ }
189
+ }
@@ -0,0 +1,6 @@
1
+ export * from './type';
2
+ export * from './gizmo';
3
+ export * from './control-gizmo';
4
+ export * from './selector-gizmo';
5
+ export * from './transform-gizmo';
6
+ export * from './adsorption-gizmo';
@@ -0,0 +1,256 @@
1
+ import { Graphics } from '@pixi/graphics';
2
+ import { Gizmo } from './gizmo';
3
+ import { SDK } from '../../sdk';
4
+ import { generateGUID } from '@galacean/effects';
5
+ import { Box2, Vector2 } from '../../math';
6
+ import { FrameLayoutMode } from '../../types';
7
+ import { SDKItemType } from '../../sdk-item/types';
8
+ import { isEffectsItem, isFrameItem } from '../../sdk-item';
9
+ export class ItemCreateGizmo extends Gizmo {
10
+ type = 'item-create';
11
+ _createType = 'none';
12
+ /**
13
+ * 鼠标状态绘制结果
14
+ */
15
+ cursorResult = {
16
+ type: 'normal',
17
+ angle: 0,
18
+ };
19
+ _pageDataUtils;
20
+ _eventEmitter;
21
+ // ===== Frame 拖拽绘制相关 =====
22
+ graphics = new Graphics();
23
+ dragStartPoint = null;
24
+ dragCurrentPoint = null;
25
+ dragStartViewPoint = null;
26
+ isDragging = false;
27
+ frameBox = null;
28
+ frameChildren = [];
29
+ interactiveChildrenBoxes = new Map();
30
+ constructor(utils, emitter) {
31
+ super();
32
+ this._pageDataUtils = utils;
33
+ this._eventEmitter = emitter;
34
+ }
35
+ get interactive() {
36
+ return SDK.config.gestureHandlerConfig.itemCreateGizmoEnabled;
37
+ }
38
+ set interactive(bool) {
39
+ if (bool === SDK.config.gestureHandlerConfig.itemCreateGizmoEnabled) {
40
+ return;
41
+ }
42
+ if (bool) {
43
+ this._pageDataUtils.clearSelectedItems();
44
+ }
45
+ SDK.config.gestureHandlerConfig.itemCreateGizmoEnabled = bool;
46
+ this._createType = bool ? this._createType : 'none';
47
+ }
48
+ get createType() {
49
+ return this._createType;
50
+ }
51
+ set createType(type) {
52
+ if (type === this._createType) {
53
+ return;
54
+ }
55
+ this._createType = type;
56
+ this.refreshCursorResult();
57
+ }
58
+ preparationAction(event) {
59
+ return this.interactive ? this.type : undefined;
60
+ }
61
+ preAction(event, isDoubleClick) {
62
+ if (!this.interactive) {
63
+ return undefined;
64
+ }
65
+ // Frame 类型:启动拖拽模式
66
+ if (this._createType === 'frame') {
67
+ this.dragStartViewPoint = new Vector2(event.offsetX, event.offsetY);
68
+ this.dragStartPoint = new Vector2(event.clientX, event.clientY);
69
+ this.dragCurrentPoint = this.dragStartPoint.clone();
70
+ this.isDragging = true;
71
+ this.frameBox = null;
72
+ this.frameChildren = [];
73
+ this.refreshInteractiveChildrenBoxes();
74
+ }
75
+ return this.type;
76
+ }
77
+ action(event) {
78
+ this.frameChildren = [];
79
+ // Frame 类型:处理拖拽绘制
80
+ if (this._createType === 'frame' && this.isDragging && this.dragStartPoint && this.dragStartViewPoint) {
81
+ this.dragCurrentPoint = new Vector2(event.clientX, event.clientY);
82
+ const shift = new Vector2().subtractVectors(this.dragCurrentPoint, this.dragStartPoint);
83
+ const endPoint = this.dragStartViewPoint?.clone().add(shift);
84
+ // 计算矩形框(屏幕坐标系)
85
+ const minX = Math.min(this.dragStartViewPoint.x, endPoint.x);
86
+ const minY = Math.min(this.dragStartViewPoint.y, endPoint.y);
87
+ const maxX = Math.max(this.dragStartViewPoint.x, endPoint.x);
88
+ const maxY = Math.max(this.dragStartViewPoint.y, endPoint.y);
89
+ this.frameBox = new Box2(new Vector2(minX, minY), new Vector2(maxX, maxY));
90
+ this.interactiveChildrenBoxes.forEach((box, id) => {
91
+ if (this.frameBox?.containsBox(box)) {
92
+ this.frameChildren.push(id);
93
+ }
94
+ });
95
+ }
96
+ }
97
+ endAction(event) {
98
+ const createItemId = generateGUID();
99
+ // Frame 类型:创建画板元素
100
+ if (this._createType === 'frame') {
101
+ // 判断是否触发拖拽(鼠标按下与松开距离超过10)
102
+ let isDragged = false;
103
+ if (this.isDragging && this.dragStartViewPoint) {
104
+ const dragDistance = this.dragStartViewPoint.distanceTo(new Vector2(event.offsetX, event.offsetY));
105
+ isDragged = dragDistance >= 10;
106
+ }
107
+ const pixelPosition = isDragged && this.frameBox && !this.frameBox.isEmpty() ?
108
+ this._pageDataUtils.interactionUtils.getPixelPositionByViewPoint(this.frameBox.getCenter())
109
+ : this._pageDataUtils.interactionUtils.getPixelPositionByViewPoint(new Vector2(event.offsetX, event.offsetY));
110
+ if (isDragged && this.frameBox && !this.frameBox.isEmpty()) {
111
+ // 有拖拽:根据拖拽范围创建
112
+ const size = this.frameBox.getSize();
113
+ const pixelSize = this._pageDataUtils.interactionUtils.getPixelSizeByViewSize(size);
114
+ const createInfo = {
115
+ type: SDKItemType.FRAME,
116
+ id: createItemId,
117
+ name: '画板',
118
+ property: {
119
+ width: pixelSize.x,
120
+ height: pixelSize.y,
121
+ position: [pixelPosition.x, pixelPosition.y],
122
+ layoutMode: FrameLayoutMode.FREE,
123
+ children: this.frameChildren,
124
+ }
125
+ };
126
+ void this._pageDataUtils.addFrameItem(createInfo);
127
+ }
128
+ else {
129
+ // 无拖拽:创建默认大小 1048*1048 的画布元素
130
+ const createInfo = {
131
+ type: SDKItemType.FRAME,
132
+ id: createItemId,
133
+ name: '画板',
134
+ property: {
135
+ width: 1048,
136
+ height: 1048,
137
+ position: [pixelPosition.x, pixelPosition.y],
138
+ layoutMode: FrameLayoutMode.FREE,
139
+ children: this.frameChildren,
140
+ }
141
+ };
142
+ void this._pageDataUtils.addFrameItem(createInfo);
143
+ }
144
+ this.resetDragState();
145
+ // 单次创建完成后,触发 itemCreate 事件通知 SDK 关闭 Gizmo
146
+ this._eventEmitter.emit('itemCreate', { type: this._createType, id: createItemId, position: pixelPosition.toArray() });
147
+ return undefined;
148
+ }
149
+ // 文本类型:在鼠标松开位置创建文本
150
+ if (this._createType === 'text') {
151
+ const position = this._pageDataUtils.interactionUtils.getPixelPositionByViewPoint(new Vector2(event.offsetX, event.offsetY)).toArray();
152
+ this._eventEmitter.emit('itemCreate', { type: this.createType, id: createItemId, position });
153
+ return undefined;
154
+ }
155
+ // 其他类型:保持原有逻辑
156
+ if (this._createType !== 'none') {
157
+ const position = this._pageDataUtils.interactionUtils.getPixelPositionByViewPoint(new Vector2(event.offsetX, event.offsetY)).toArray();
158
+ this._eventEmitter.emit('itemCreate', { type: this.createType, id: createItemId, position });
159
+ }
160
+ return undefined;
161
+ }
162
+ interruption() {
163
+ this.resetDragState();
164
+ return this.type;
165
+ }
166
+ resetDragState() {
167
+ this.isDragging = false;
168
+ this.dragStartPoint = null;
169
+ this.dragCurrentPoint = null;
170
+ this.dragStartViewPoint = null;
171
+ this.frameBox = null;
172
+ this.graphics.clear();
173
+ }
174
+ actionKey(keyCode) { }
175
+ endActionKey(keyCode) { }
176
+ cancelPreparation() { }
177
+ refreshResults() {
178
+ this.graphics.clear();
179
+ // Frame 类型:绘制拖拽矩形
180
+ if (this._createType === 'frame' && this.isDragging && this.frameBox && !this.frameBox.isEmpty()) {
181
+ const { min, max } = this.frameBox;
182
+ const width = max.x - min.x;
183
+ const height = max.y - min.y;
184
+ const { frameFillAlpha, frameFillColor, frameBorderAlpha, frameBorderColor, frameBorderWidth, frameChildBoxAlpha, frameChildBoxColor, } = SDK.config.gestureHandlerConfig.itemCreateGizmoConfig;
185
+ // 绘制边框
186
+ this.graphics.lineStyle(frameBorderWidth, frameBorderColor, frameBorderAlpha);
187
+ this.graphics.drawRect(min.x, min.y, width, height);
188
+ // 绘制半透明填充
189
+ this.graphics.beginFill(frameFillColor, frameFillAlpha);
190
+ this.graphics.drawRect(min.x, min.y, width, height);
191
+ this.graphics.endFill();
192
+ this.frameChildren.forEach(id => {
193
+ const box = this.interactiveChildrenBoxes.get(id);
194
+ if (!box) {
195
+ return;
196
+ }
197
+ const { min, max } = box;
198
+ const width = max.x - min.x;
199
+ const height = max.y - min.y;
200
+ this.graphics.beginFill(frameChildBoxColor, frameChildBoxAlpha);
201
+ this.graphics.drawRect(min.x, min.y, width, height);
202
+ this.graphics.endFill();
203
+ });
204
+ }
205
+ }
206
+ getRenderObjects() {
207
+ // Frame 类型:返回绘制对象
208
+ if (this._createType === 'frame' && this.isDragging) {
209
+ this.refreshResults();
210
+ return [this.graphics];
211
+ }
212
+ return [];
213
+ }
214
+ refreshCursorResult() {
215
+ switch (this._createType) {
216
+ case 'text': {
217
+ this.cursorResult = {
218
+ type: 'text-create',
219
+ angle: 0,
220
+ };
221
+ break;
222
+ }
223
+ case 'frame': {
224
+ this.cursorResult = {
225
+ type: 'frame-create',
226
+ angle: 0,
227
+ };
228
+ break;
229
+ }
230
+ case 'none':
231
+ case 'sprite-generator':
232
+ case 'video-generator': {
233
+ this.cursorResult = {
234
+ type: 'normal',
235
+ angle: 0,
236
+ };
237
+ break;
238
+ }
239
+ }
240
+ }
241
+ refreshInteractiveChildrenBoxes() {
242
+ const items = this._pageDataUtils.getPageData()?.items;
243
+ if (!items?.length) {
244
+ return [];
245
+ }
246
+ const filterItemIds = items.flatMap(item => isEffectsItem(item) ? [item.id] : isFrameItem(item) ? [item.id, ...item.children] : []);
247
+ items.forEach(item => {
248
+ // 特效元素与画板元素以及画板元素中的子元素不可以被添加到画板
249
+ if (filterItemIds.includes(item.id)) {
250
+ return;
251
+ }
252
+ const box = this._pageDataUtils.getViewBoxById(item.id);
253
+ this.interactiveChildrenBoxes.set(item.id, box);
254
+ });
255
+ }
256
+ }