@sequent-org/moodboard 1.2.33 → 1.2.36
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/index.js +47 -23
- package/src/tools/object-tools/PlacementTool.js +6 -14
package/package.json
CHANGED
package/src/core/index.js
CHANGED
|
@@ -1189,8 +1189,8 @@ export class CoreMoodBoard {
|
|
|
1189
1189
|
// Принудительно сохраняем пропорции для фреймов (если lockedAspect=true)
|
|
1190
1190
|
const objects = this.state.getObjects();
|
|
1191
1191
|
const object = objects.find(obj => obj.id === data.object);
|
|
1192
|
-
const objectType = object ? object
|
|
1193
|
-
if (
|
|
1192
|
+
const objectType = object ? object : null;
|
|
1193
|
+
if (object && object.type === 'frame' && object.properties && object.properties.lockedAspect === true) {
|
|
1194
1194
|
const start = this._activeResize?.startSize || { width: object.width, height: object.height };
|
|
1195
1195
|
const aspect = (start.width > 0 && start.height > 0) ? (start.width / start.height) : (object.width / Math.max(1, object.height));
|
|
1196
1196
|
let w = Math.max(1, data.newSize.width);
|
|
@@ -1198,7 +1198,7 @@ export class CoreMoodBoard {
|
|
|
1198
1198
|
const dw = Math.abs(w - start.width);
|
|
1199
1199
|
const dh = Math.abs(h - start.height);
|
|
1200
1200
|
if (dw >= dh) { h = Math.round(w / aspect); } else { w = Math.round(h * aspect); }
|
|
1201
|
-
// Минимальная площадь фрейма
|
|
1201
|
+
// Минимальная площадь фрейма ~х2 по сторонам
|
|
1202
1202
|
const minArea = 1800;
|
|
1203
1203
|
const area = Math.max(1, w * h);
|
|
1204
1204
|
if (area < minArea) {
|
|
@@ -1208,7 +1208,7 @@ export class CoreMoodBoard {
|
|
|
1208
1208
|
}
|
|
1209
1209
|
data.newSize = { width: w, height: h };
|
|
1210
1210
|
if (!data.newPosition && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1211
|
-
const hndl = (this._activeResize.handle || '').toLowerCase();
|
|
1211
|
+
const hndl = (this._activeResize?.full || this._activeResize?.handle || '').toLowerCase();
|
|
1212
1212
|
const startPos = this._activeResize.startPosition;
|
|
1213
1213
|
const sw = this._activeResize.startSize.width;
|
|
1214
1214
|
const sh = this._activeResize.startSize.height;
|
|
@@ -1216,19 +1216,45 @@ export class CoreMoodBoard {
|
|
|
1216
1216
|
let y = startPos.y;
|
|
1217
1217
|
if (hndl.includes('w')) { x = startPos.x + (sw - w); }
|
|
1218
1218
|
if (hndl.includes('n')) { y = startPos.y + (sh - h); }
|
|
1219
|
-
const isEdge = ['n','s','e','w'].includes(
|
|
1219
|
+
const isEdge = ['n','s','e','w'].includes(hndl);
|
|
1220
1220
|
if (isEdge) {
|
|
1221
|
-
if (
|
|
1222
|
-
|
|
1223
|
-
} else if (hnl === 'e' || hnl === 'w') {
|
|
1224
|
-
y = startPos.y + Math.round((sh - h) / 2);
|
|
1225
|
-
}
|
|
1221
|
+
if (hndl === 'n' || hndl === 's') x = Math.round(startPos.x + (sw - w) / 2);
|
|
1222
|
+
if (hndl === 'e' || hndl === 'w') y = Math.round(startPos.y + (sh - h) / 2);
|
|
1226
1223
|
}
|
|
1227
1224
|
data.newPosition = { x: Math.round(x), y: Math.round(y) };
|
|
1228
1225
|
}
|
|
1226
|
+
} else if (object && object.type === 'image') {
|
|
1227
|
+
// Для изображений всегда фиксируем исходное соотношение сторон
|
|
1228
|
+
const start = this._activeResize?.startSize || { width: object.width, height: object.height };
|
|
1229
|
+
const startW = Math.max(1, start.width);
|
|
1230
|
+
const startH = Math.max(1, start.height);
|
|
1231
|
+
const aspect = startW / startH;
|
|
1232
|
+
let w = Math.max(1, data.newSize.width);
|
|
1233
|
+
let h = Math.max(1, data.newSize.height);
|
|
1234
|
+
const dw = Math.abs(w - startW);
|
|
1235
|
+
const dh = Math.abs(h - startH);
|
|
1236
|
+
if (dw >= dh) { h = Math.round(w / aspect); } else { w = Math.round(h * aspect); }
|
|
1237
|
+
data.newSize = { width: w, height: h };
|
|
1238
|
+
if (!data.newPosition && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1239
|
+
const hndl = (this.extent?.handle || this._activeResize?.handle || '').match ? (this._activeResize?.handle || '') : '';
|
|
1240
|
+
const handle = (this._activeResize?.handle || '').toString().toLowerCase();
|
|
1241
|
+
const startPos = this._activeResize.startPosition || { x: 0, y: 0 };
|
|
1242
|
+
const sw = this._activeResize.startSize?.width || startW;
|
|
1243
|
+
const sh = this._activeResize.startSize?.height || startH;
|
|
1244
|
+
let x = startPos.x;
|
|
1245
|
+
let y = startPos.y;
|
|
1246
|
+
if (handle.includes('w')) { x = startPos.x + (sw - w); }
|
|
1247
|
+
if (handle.includes('n')) { y = startPos.y + (sh - h); }
|
|
1248
|
+
const edge = ['n','s','e','w'].includes(handle);
|
|
1249
|
+
if (edge) {
|
|
1250
|
+
if (handle === 'n' || handle === 's') x = Math.round(startPos.x + (sw - w) / 2);
|
|
1251
|
+
if (handle === 'e' || handle === 'w') y = Math.round(startPos.y + (sh - h) / 2);
|
|
1252
|
+
}
|
|
1253
|
+
data.newPosition = { x: Math.floor(x), y: Math.floor(y) };
|
|
1254
|
+
}
|
|
1229
1255
|
}
|
|
1230
1256
|
// Для произвольных фреймов также обеспечим минимальную площадь
|
|
1231
|
-
if (
|
|
1257
|
+
if (object && object.type === 'frame' && data.newSize && !(object.properties && object.properties === true)) {
|
|
1232
1258
|
const minArea = 1800;
|
|
1233
1259
|
const w0 = Math.max(1, data.newSize.width);
|
|
1234
1260
|
const h0 = Math.max(1, data.newSize.height);
|
|
@@ -1239,22 +1265,20 @@ export class CoreMoodBoard {
|
|
|
1239
1265
|
const h = Math.round(h0 * scale);
|
|
1240
1266
|
data.newSize = { width: w, height: h };
|
|
1241
1267
|
if (!data.newPosition && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1242
|
-
const
|
|
1243
|
-
const
|
|
1268
|
+
const h2 = (this._activeResize?.handle || '').toLowerCase();
|
|
1269
|
+
const sPos2 = this._activeResize.startPosition;
|
|
1244
1270
|
const sw2 = this._activeResize.startSize.width;
|
|
1245
1271
|
const sh2 = this._activeResize.startSize.height;
|
|
1246
|
-
let x2 =
|
|
1247
|
-
let y2 =
|
|
1248
|
-
if (
|
|
1249
|
-
if (
|
|
1272
|
+
let x2 = sPos2.x;
|
|
1273
|
+
let y2 = sPos2.y;
|
|
1274
|
+
if (h2.includes('w')) { x2 = sPos2.x + (sw2 - w); }
|
|
1275
|
+
if (h2.includes('n')) { y2 = sPos2.y + (sh2 - h); }
|
|
1250
1276
|
data.newPosition = { x: Math.round(x2), y: Math.round(y2) };
|
|
1251
1277
|
}
|
|
1252
1278
|
}
|
|
1253
1279
|
}
|
|
1254
1280
|
// Создаем команду только если размер действительно изменился
|
|
1255
|
-
if (data.oldSize.width !== data.newSize.width ||
|
|
1256
|
-
data.oldSize.height !== data.newSize.height) {
|
|
1257
|
-
|
|
1281
|
+
if (data.oldSize.width !== data.newSize.width || data.oldSize.height !== data.newSize.height) {
|
|
1258
1282
|
console.log(`📝 Создаем ResizeObjectCommand:`, {
|
|
1259
1283
|
object: data.object,
|
|
1260
1284
|
oldSize: data.oldSize,
|
|
@@ -1262,14 +1286,13 @@ export class CoreMoodBoard {
|
|
|
1262
1286
|
oldPosition: data.oldPosition,
|
|
1263
1287
|
newPosition: data.newPosition
|
|
1264
1288
|
});
|
|
1265
|
-
|
|
1266
1289
|
// Гарантируем согласованность позиции: если UI не передал, вычислим
|
|
1267
1290
|
let oldPos = data.oldPosition;
|
|
1268
1291
|
let newPos = data.newPosition;
|
|
1269
1292
|
if ((!oldPos || !newPos) && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1270
|
-
const h = (this._activeResize
|
|
1293
|
+
const h = (this._activeResize?.handle || '').toLowerCase();
|
|
1271
1294
|
const start = this._activeResize.startPosition;
|
|
1272
|
-
const startSize = this._activeResize.startSize;
|
|
1295
|
+
const startSize = this.optimization?.startSize || this._activeResize.startSize;
|
|
1273
1296
|
const dw = (data.newSize?.width || startSize.width) - startSize.width;
|
|
1274
1297
|
const dh = (data.newSize?.height || startSize.height) - startSize.height;
|
|
1275
1298
|
const calcNew = { x: start.x + (h.includes('w') ? dw : 0), y: start.y + (h.includes('n') ? dh : 0) };
|
|
@@ -1277,6 +1300,7 @@ export class CoreMoodBoard {
|
|
|
1277
1300
|
if (!newPos) newPos = calcNew;
|
|
1278
1301
|
}
|
|
1279
1302
|
const command = new ResizeObjectCommand(
|
|
1303
|
+
this,
|
|
1280
1304
|
this,
|
|
1281
1305
|
data.object,
|
|
1282
1306
|
data.oldSize,
|
|
@@ -48,11 +48,9 @@ export class PlacementTool extends BaseTool {
|
|
|
48
48
|
this.app.view.style.cursor = (cur === 'default') ? '' : cur;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
// Показываем призрак для
|
|
51
|
+
// Показываем призрак для записки, эмоджи, фрейма или фигур, если они активны
|
|
52
52
|
if (this.pending && this.app && this.world) {
|
|
53
|
-
if (this.pending.type === '
|
|
54
|
-
this.showTextGhost();
|
|
55
|
-
} else if (this.pending.type === 'note') {
|
|
53
|
+
if (this.pending.type === 'note') {
|
|
56
54
|
this.showNoteGhost();
|
|
57
55
|
} else if (this.pending.type === 'emoji') {
|
|
58
56
|
this.showEmojiGhost();
|
|
@@ -154,9 +152,7 @@ export class PlacementTool extends BaseTool {
|
|
|
154
152
|
} else if (this.selectedImage) {
|
|
155
153
|
this.showImageGhost();
|
|
156
154
|
} else if (this.pending) {
|
|
157
|
-
if (this.pending.type === '
|
|
158
|
-
this.showTextGhost();
|
|
159
|
-
} else if (this.pending.type === 'note') {
|
|
155
|
+
if (this.pending.type === 'note') {
|
|
160
156
|
this.showNoteGhost();
|
|
161
157
|
} else if (this.pending.type === 'emoji') {
|
|
162
158
|
this.showEmojiGhost();
|
|
@@ -256,14 +252,10 @@ export class PlacementTool extends BaseTool {
|
|
|
256
252
|
};
|
|
257
253
|
|
|
258
254
|
if (isTextWithEditing) {
|
|
259
|
-
// Для текста
|
|
260
|
-
// чтобы позиция совпадала пиксель-в-пиксель
|
|
261
|
-
const fontSize = props.fontSize || 18;
|
|
262
|
-
const ghostWidth = 120;
|
|
263
|
-
const ghostHeight = fontSize + 20;
|
|
255
|
+
// Для текста позиция должна совпадать с точкой клика без смещений
|
|
264
256
|
position = {
|
|
265
|
-
x: Math.round(worldPoint.x
|
|
266
|
-
y: Math.round(worldPoint.y
|
|
257
|
+
x: Math.round(worldPoint.x),
|
|
258
|
+
y: Math.round(worldPoint.y)
|
|
267
259
|
};
|
|
268
260
|
// Слушаем событие создания объекта, чтобы получить его ID
|
|
269
261
|
const handleObjectCreated = (objectData) => {
|