@sequent-org/moodboard 1.4.48 → 1.4.51
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/package.json +1 -1
- package/src/core/commands/ApplyCropCommand.js +90 -0
- package/src/core/commands/UpdateFramePropertiesCommand.js +9 -2
- package/src/core/events/Events.js +2 -0
- package/src/core/flows/ClipboardFlow.js +13 -0
- package/src/core/flows/ObjectLifecycleFlow.js +25 -6
- package/src/moodboard/bootstrap/MoodBoardUiFactory.js +1 -1
- package/src/objects/FrameObject.js +90 -8
- package/src/objects/ImageObject.js +25 -4
- package/src/services/CropController.js +242 -0
- package/src/services/FrameService.js +32 -0
- package/src/tools/manager/ToolManagerLifecycle.js +4 -0
- package/src/tools/object-tools/DrawingTool.js +1 -0
- package/src/tools/object-tools/selection/TransformInteractionController.js +50 -0
- package/src/ui/CropOverlay.js +654 -0
- package/src/ui/FramePropertiesPanel.js +1061 -407
- package/src/ui/HtmlHandlesLayer.js +2 -0
- package/src/ui/ImagePropertiesPanel.js +1509 -4
- package/src/ui/comments/CommentThreadPopover.js +68 -0
- package/src/ui/connectors/ConnectionAnchorsLayer.js +12 -1
- package/src/ui/handles/HandlesDomRenderer.js +9 -2
- package/src/ui/handles/HandlesEventBridge.js +1 -0
- package/src/ui/styles/panels.css +750 -28
- package/src/ui/styles/workspace.css +21 -1
- package/src/utils/applyCrop.js +92 -0
- package/src/utils/applyRoundedMask.js +39 -0
|
@@ -71,6 +71,24 @@ export class FrameService {
|
|
|
71
71
|
};
|
|
72
72
|
this.eventBus.on(Events.Object.Created, this._onObjectCreated);
|
|
73
73
|
|
|
74
|
+
this._onStateChanged = (data) => {
|
|
75
|
+
if (!data || !data.updates || !data.updates.properties) return;
|
|
76
|
+
if (data.updates.properties.hidden !== undefined) {
|
|
77
|
+
const obj = this.state.state.objects.find(o => o.id === data.objectId);
|
|
78
|
+
if (obj && obj.type === 'frame') {
|
|
79
|
+
const isHidden = data.updates.properties.hidden;
|
|
80
|
+
const children = this._getFrameChildren(obj.id);
|
|
81
|
+
for (const childId of children) {
|
|
82
|
+
const pixi = this.pixi.objects.get(childId);
|
|
83
|
+
if (pixi) {
|
|
84
|
+
pixi.visible = !isHidden;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
this.eventBus.on(Events.Object.StateChanged, this._onStateChanged);
|
|
91
|
+
|
|
74
92
|
this._onDragStart = (data) => {
|
|
75
93
|
const moved = this.state.state.objects.find(o => o.id === data.object);
|
|
76
94
|
if (moved && moved.type === 'frame') {
|
|
@@ -256,6 +274,20 @@ export class FrameService {
|
|
|
256
274
|
this._forceFramesBelow();
|
|
257
275
|
this.eventBus.emit(Events.Object.Reordered, { reason: 'recompute_frame_attachment' });
|
|
258
276
|
}
|
|
277
|
+
|
|
278
|
+
// Обновляем видимость в зависимости от скрытости фрейма
|
|
279
|
+
const pixi = this.pixi.objects.get(objectId);
|
|
280
|
+
if (pixi) {
|
|
281
|
+
let isHidden = false;
|
|
282
|
+
const targetFrameId = obj.properties?.frameId;
|
|
283
|
+
if (targetFrameId) {
|
|
284
|
+
const frameObj = this.state.state.objects.find(o => o.id === targetFrameId);
|
|
285
|
+
if (frameObj && frameObj.properties?.hidden) {
|
|
286
|
+
isHidden = true;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
pixi.visible = !isHidden;
|
|
290
|
+
}
|
|
259
291
|
}
|
|
260
292
|
}
|
|
261
293
|
|
|
@@ -29,6 +29,10 @@ export class ToolManagerLifecycle {
|
|
|
29
29
|
manager._onContextMenu = (e) => {
|
|
30
30
|
e.preventDefault();
|
|
31
31
|
if (!manager.activeTool) return;
|
|
32
|
+
if (manager.activeTool.name === 'draw') {
|
|
33
|
+
manager.activateDefaultTool();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
32
36
|
const rect = manager.container.getBoundingClientRect();
|
|
33
37
|
const toolEvent = {
|
|
34
38
|
x: e.clientX - rect.left,
|
|
@@ -25,6 +25,12 @@ export function handleObjectSelect(objectId, event) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export function startDrag(objectId, event) {
|
|
28
|
+
const req = { objectId, pixiObject: null };
|
|
29
|
+
this.emit('tool:get:object:pixi', req);
|
|
30
|
+
if (req.pixiObject?._mb?.properties?.locked) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
28
34
|
this.isDragging = true;
|
|
29
35
|
this.dragTarget = objectId;
|
|
30
36
|
// Сообщаем HtmlHandlesLayer о начале перетаскивания одиночного объекта
|
|
@@ -91,6 +97,23 @@ export function endDrag() {
|
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
export function startResize(handle, objectId) {
|
|
100
|
+
const isLocked = (() => {
|
|
101
|
+
if (objectId === this.groupId) {
|
|
102
|
+
return this.selection.toArray().some(id => {
|
|
103
|
+
const req = { objectId: id, pixiObject: null };
|
|
104
|
+
this.emit('tool:get:object:pixi', req);
|
|
105
|
+
return !!req.pixiObject?._mb?.properties?.locked;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const req = { objectId, pixiObject: null };
|
|
109
|
+
this.emit('tool:get:object:pixi', req);
|
|
110
|
+
return !!req.pixiObject?._mb?.properties?.locked;
|
|
111
|
+
})();
|
|
112
|
+
|
|
113
|
+
if (isLocked) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
94
117
|
// Групповой resize
|
|
95
118
|
if (objectId === this.groupId && this.selection.size() > 1) {
|
|
96
119
|
this.isGroupResizing = true;
|
|
@@ -169,6 +192,23 @@ export function endResize() {
|
|
|
169
192
|
}
|
|
170
193
|
|
|
171
194
|
export function startRotate(objectId) {
|
|
195
|
+
const isLocked = (() => {
|
|
196
|
+
if (objectId === this.groupId) {
|
|
197
|
+
return this.selection.toArray().some(id => {
|
|
198
|
+
const req = { objectId: id, pixiObject: null };
|
|
199
|
+
this.emit('tool:get:object:pixi', req);
|
|
200
|
+
return !!req.pixiObject?._mb?.properties?.locked;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
const req = { objectId, pixiObject: null };
|
|
204
|
+
this.emit('tool:get:object:pixi', req);
|
|
205
|
+
return !!req.pixiObject?._mb?.properties?.locked;
|
|
206
|
+
})();
|
|
207
|
+
|
|
208
|
+
if (isLocked) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
172
212
|
// Групповой поворот
|
|
173
213
|
if (objectId === this.groupId && this.selection.size() > 1) {
|
|
174
214
|
this.isGroupRotating = true;
|
|
@@ -276,6 +316,16 @@ export function endBoxSelect() {
|
|
|
276
316
|
}
|
|
277
317
|
|
|
278
318
|
export function startGroupDrag(event) {
|
|
319
|
+
const isLocked = this.selection.toArray().some(id => {
|
|
320
|
+
const req = { objectId: id, pixiObject: null };
|
|
321
|
+
this.emit('tool:get:object:pixi', req);
|
|
322
|
+
return !!req.pixiObject?._mb?.properties?.locked;
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
if (isLocked) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
|
|
279
329
|
const gb = this.computeGroupBounds();
|
|
280
330
|
this.groupStartBounds = gb;
|
|
281
331
|
this.isGroupDragging = true;
|