@sequent-org/moodboard 1.2.30 → 1.2.35
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/ApiClient.js +0 -16
- package/src/core/SaveManager.js +0 -35
- package/src/core/index.js +113 -85
- package/src/moodboard/DataManager.js +2 -23
- package/src/moodboard/MoodBoard.js +3 -18
package/package.json
CHANGED
package/src/core/ApiClient.js
CHANGED
|
@@ -45,22 +45,6 @@ export class ApiClient {
|
|
|
45
45
|
// Фильтруем объекты изображений и файлов - убираем избыточные данные
|
|
46
46
|
const cleanedData = this._cleanObjectData(boardData);
|
|
47
47
|
|
|
48
|
-
// Диагностика размеров изображений перед отправкой
|
|
49
|
-
try {
|
|
50
|
-
const images = Array.isArray(cleanedData?.objects)
|
|
51
|
-
? cleanedData.objects.filter(o => o && o.type === 'image')
|
|
52
|
-
: [];
|
|
53
|
-
images.forEach((o) => {
|
|
54
|
-
console.log('🧪 SAVE image size', {
|
|
55
|
-
id: o.id,
|
|
56
|
-
width: o.width,
|
|
57
|
-
height: o.height,
|
|
58
|
-
propWidth: o.properties?.width,
|
|
59
|
-
propHeight: o.properties?.height
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
} catch (_) {}
|
|
63
|
-
|
|
64
48
|
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
|
65
49
|
|
|
66
50
|
const response = await fetch('/api/moodboard/save', {
|
package/src/core/SaveManager.js
CHANGED
|
@@ -157,41 +157,6 @@ export class SaveManager {
|
|
|
157
157
|
data: saveData,
|
|
158
158
|
timestamp: new Date().toISOString()
|
|
159
159
|
});
|
|
160
|
-
|
|
161
|
-
// Диагностика: по флагу проверяем, что сервер отдает те же размеры на чтение
|
|
162
|
-
try {
|
|
163
|
-
if (typeof window !== 'undefined' && window.MOODBOARD_DEBUG_VERIFY_LOAD === true) {
|
|
164
|
-
const boardId = saveData?.id;
|
|
165
|
-
if (boardId) {
|
|
166
|
-
const verifyUrl = `${this.options.loadEndpoint}/${boardId}`;
|
|
167
|
-
const resp = await fetch(verifyUrl, {
|
|
168
|
-
method: 'GET',
|
|
169
|
-
headers: {
|
|
170
|
-
'Accept': 'application/json',
|
|
171
|
-
'X-Requested-With': 'XMLHttpRequest'
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
if (resp.ok) {
|
|
175
|
-
const result = await resp.json();
|
|
176
|
-
const data = result?.data || result;
|
|
177
|
-
const imgs = Array.isArray(data?.objects) ? data.objects.filter(o => o && o.type === 'image') : [];
|
|
178
|
-
imgs.forEach((o) => {
|
|
179
|
-
console.log('🧪 VERIFY LOAD after save image size', {
|
|
180
|
-
id: o.id,
|
|
181
|
-
width: o.width,
|
|
182
|
-
height: o.height,
|
|
183
|
-
propWidth: o.properties?.width,
|
|
184
|
-
propHeight: o.properties?.height
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
} else {
|
|
188
|
-
console.warn('⚠️ VERIFY LOAD failed:', resp.status, resp.statusText);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
} catch (e) {
|
|
193
|
-
console.warn('⚠️ VERIFY LOAD exception:', e?.message || e);
|
|
194
|
-
}
|
|
195
160
|
} else {
|
|
196
161
|
throw new Error(response.message || 'Ошибка сохранения');
|
|
197
162
|
}
|
package/src/core/index.js
CHANGED
|
@@ -1067,80 +1067,84 @@ export class CoreMoodBoard {
|
|
|
1067
1067
|
const object = objects.find(obj => obj.id === data.object);
|
|
1068
1068
|
const objectType = object ? object.type : null;
|
|
1069
1069
|
|
|
1070
|
-
// Сохраняем
|
|
1071
|
-
|
|
1072
|
-
|
|
1070
|
+
// Сохраняем пропорции:
|
|
1071
|
+
// - всегда для изображений (включая эмоджи-иконки, которые квадратные)
|
|
1072
|
+
// - для фреймов только если lockedAspect=true
|
|
1073
|
+
if (data.size && (objectType === 'image' || objectType === 'frame')) {
|
|
1073
1074
|
const isEmoji = (objectType === 'image' && object?.properties?.isEmojiIcon);
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1075
|
+
const isImage = (objectType === 'image');
|
|
1076
|
+
const lockedAspect = objectType === 'frame'
|
|
1077
|
+
? !!(object?.properties && object.properties.lockedAspect === true)
|
|
1078
|
+
: true; // для изображений всегда держим аспект
|
|
1079
|
+
|
|
1080
|
+
if (lockedAspect || isImage || isEmoji) {
|
|
1081
|
+
const start = this._activeResize?.startSize || { width: object.width, height: object.height };
|
|
1082
|
+
const startW = Math.max(1, start.width);
|
|
1083
|
+
const startH = Math.max(1, start.height);
|
|
1084
|
+
const aspect = isEmoji ? 1 : (startW / startH);
|
|
1085
|
+
|
|
1086
|
+
let w = Math.max(1, data.size.width);
|
|
1087
|
+
let h = Math.max(1, data.size.height);
|
|
1088
|
+
const hndl = (this._activeResize?.handle || '').toLowerCase();
|
|
1089
|
+
|
|
1090
|
+
if (isEmoji) {
|
|
1091
|
+
// Квадрат
|
|
1092
|
+
const s = Math.max(w, h);
|
|
1093
|
+
if (!data.position && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1094
|
+
const startPos = this._activeResize.startPosition;
|
|
1095
|
+
const sw = this._activeResize.startSize.width;
|
|
1096
|
+
const sh = this._activeResize.startSize.height;
|
|
1097
|
+
let x = startPos.x;
|
|
1098
|
+
let y = startPos.y;
|
|
1099
|
+
if (hndl.includes('w')) { x = startPos.x + (sw - s); }
|
|
1100
|
+
if (hndl.includes('n')) { y = startPos.y + (sh - s); }
|
|
1101
|
+
const isEdge = ['n','s','e','w'].includes(hndl);
|
|
1102
|
+
if (isEdge) {
|
|
1103
|
+
if (hndl === 'n' || hndl === 's') x = startPos.x + Math.round((sw - s) / 2);
|
|
1104
|
+
if (hndl === 'e' || hndl === 'w') y = startPos.y + Math.round((sh - s) / 2);
|
|
1105
|
+
}
|
|
1106
|
+
data.position = { x: Math.round(x), y: Math.round(y) };
|
|
1107
|
+
}
|
|
1108
|
+
w = s; h = s;
|
|
1109
|
+
} else {
|
|
1110
|
+
// Поддержка аспекта (для images всегда; для frames — если lockedAspect)
|
|
1111
|
+
const dw = Math.abs(w - startW);
|
|
1112
|
+
const dh = Math.abs(h - startH);
|
|
1113
|
+
if (dw >= dh) { h = Math.round(w / aspect); } else { w = Math.round(h * aspect); }
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// Минимальная площадь — только для фреймов (как раньше)
|
|
1117
|
+
if (objectType === 'frame') {
|
|
1118
|
+
const minArea = 1800;
|
|
1119
|
+
const area = Math.max(1, w * h);
|
|
1120
|
+
if (area < minArea) {
|
|
1121
|
+
const scale = Math.sqrt(minArea / area);
|
|
1122
|
+
w = Math.round(w * scale);
|
|
1123
|
+
h = Math.round(h * scale);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
data.size = { width: w, height: h };
|
|
1128
|
+
|
|
1129
|
+
// Компенсация позиции по зафиксированной стороне
|
|
1086
1130
|
if (!data.position && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1087
1131
|
const startPos = this._activeResize.startPosition;
|
|
1088
1132
|
const sw = this._activeResize.startSize.width;
|
|
1089
1133
|
const sh = this._activeResize.startSize.height;
|
|
1090
1134
|
let x = startPos.x;
|
|
1091
1135
|
let y = startPos.y;
|
|
1092
|
-
if (hndl.includes('w')) { x = startPos.x + (sw -
|
|
1093
|
-
if (hndl.includes('n')) { y = startPos.y + (sh -
|
|
1136
|
+
if (hndl.includes('w')) { x = startPos.x + (sw - data.size.width); }
|
|
1137
|
+
if (hndl.includes('n')) { y = startPos.y + (sh - data.size.height); }
|
|
1094
1138
|
const isEdge = ['n','s','e','w'].includes(hndl);
|
|
1095
1139
|
if (isEdge) {
|
|
1096
|
-
if (hndl === 'n' || hndl === 's')
|
|
1097
|
-
|
|
1140
|
+
if (hndl === 'n' || hndl === 's') {
|
|
1141
|
+
x = startPos.x + Math.round((sw - data.size.width) / 2);
|
|
1142
|
+
} else if (hndl === 'e' || hndl === 'w') {
|
|
1143
|
+
y = startPos.y + Math.round((sh - data.size.height) / 2);
|
|
1144
|
+
}
|
|
1098
1145
|
}
|
|
1099
1146
|
data.position = { x: Math.round(x), y: Math.round(y) };
|
|
1100
1147
|
}
|
|
1101
|
-
w = s; h = s;
|
|
1102
|
-
} else {
|
|
1103
|
-
// Обычная поддержка аспекта для фреймов
|
|
1104
|
-
const dw = Math.abs(w - start.width);
|
|
1105
|
-
const dh = Math.abs(h - start.height);
|
|
1106
|
-
if (dw >= dh) { h = Math.round(w / aspect); } else { w = Math.round(h * aspect); }
|
|
1107
|
-
}
|
|
1108
|
-
// Минимальная площадь — только для фреймов
|
|
1109
|
-
if (!isEmoji) {
|
|
1110
|
-
const minArea = 1800;
|
|
1111
|
-
const area = Math.max(1, w * h);
|
|
1112
|
-
if (area < minArea) {
|
|
1113
|
-
const scale = Math.sqrt(minArea / area);
|
|
1114
|
-
w = Math.round(w * scale);
|
|
1115
|
-
h = Math.round(h * scale);
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
data.size = { width: w, height: h };
|
|
1119
|
-
|
|
1120
|
-
// Если позиция известна (фиксированная противоположная сторона) — откорректируем её
|
|
1121
|
-
if (!data.position && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1122
|
-
const hndl = (this._activeResize.handle || '').toLowerCase();
|
|
1123
|
-
const startPos = this._activeResize.startPosition;
|
|
1124
|
-
const sw = this._activeResize.startSize.width;
|
|
1125
|
-
const sh = this._activeResize.startSize.height;
|
|
1126
|
-
let x = startPos.x;
|
|
1127
|
-
let y = startPos.y;
|
|
1128
|
-
// Базовая привязка противоположной стороны
|
|
1129
|
-
if (hndl.includes('w')) { x = startPos.x + (sw - w); }
|
|
1130
|
-
if (hndl.includes('n')) { y = startPos.y + (sh - h); }
|
|
1131
|
-
// Симметрическая компенсация по перпендикулярной оси для edge-хэндлов
|
|
1132
|
-
const isEdge = ['n','s','e','w'].includes(hndl);
|
|
1133
|
-
if (isEdge) {
|
|
1134
|
-
if (hndl === 'n' || hndl === 's') {
|
|
1135
|
-
// Вверх/вниз: верх или низ фиксируется, ширина меняется симметрично относительно центра
|
|
1136
|
-
x = startPos.x + Math.round((sw - w) / 2);
|
|
1137
|
-
} else if (hndl === 'e' || hndl === 'w') {
|
|
1138
|
-
// Вправо/влево: левая или правая фиксируется, высота меняется симметрично относительно центра
|
|
1139
|
-
y = startPos.y + Math.round((sh - h) / 2);
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
data.position = { x: Math.round(x), y: Math.round(y) };
|
|
1143
|
-
}
|
|
1144
1148
|
}
|
|
1145
1149
|
}
|
|
1146
1150
|
|
|
@@ -1185,8 +1189,8 @@ export class CoreMoodBoard {
|
|
|
1185
1189
|
// Принудительно сохраняем пропорции для фреймов (если lockedAspect=true)
|
|
1186
1190
|
const objects = this.state.getObjects();
|
|
1187
1191
|
const object = objects.find(obj => obj.id === data.object);
|
|
1188
|
-
const objectType = object ? object
|
|
1189
|
-
if (
|
|
1192
|
+
const objectType = object ? object : null;
|
|
1193
|
+
if (object && object.type === 'frame' && object.properties && object.properties.lockedAspect === true) {
|
|
1190
1194
|
const start = this._activeResize?.startSize || { width: object.width, height: object.height };
|
|
1191
1195
|
const aspect = (start.width > 0 && start.height > 0) ? (start.width / start.height) : (object.width / Math.max(1, object.height));
|
|
1192
1196
|
let w = Math.max(1, data.newSize.width);
|
|
@@ -1194,7 +1198,7 @@ export class CoreMoodBoard {
|
|
|
1194
1198
|
const dw = Math.abs(w - start.width);
|
|
1195
1199
|
const dh = Math.abs(h - start.height);
|
|
1196
1200
|
if (dw >= dh) { h = Math.round(w / aspect); } else { w = Math.round(h * aspect); }
|
|
1197
|
-
// Минимальная площадь фрейма
|
|
1201
|
+
// Минимальная площадь фрейма ~х2 по сторонам
|
|
1198
1202
|
const minArea = 1800;
|
|
1199
1203
|
const area = Math.max(1, w * h);
|
|
1200
1204
|
if (area < minArea) {
|
|
@@ -1204,7 +1208,7 @@ export class CoreMoodBoard {
|
|
|
1204
1208
|
}
|
|
1205
1209
|
data.newSize = { width: w, height: h };
|
|
1206
1210
|
if (!data.newPosition && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1207
|
-
const hndl = (this._activeResize.handle || '').toLowerCase();
|
|
1211
|
+
const hndl = (this._activeResize?.full || this._activeResize?.handle || '').toLowerCase();
|
|
1208
1212
|
const startPos = this._activeResize.startPosition;
|
|
1209
1213
|
const sw = this._activeResize.startSize.width;
|
|
1210
1214
|
const sh = this._activeResize.startSize.height;
|
|
@@ -1212,19 +1216,45 @@ export class CoreMoodBoard {
|
|
|
1212
1216
|
let y = startPos.y;
|
|
1213
1217
|
if (hndl.includes('w')) { x = startPos.x + (sw - w); }
|
|
1214
1218
|
if (hndl.includes('n')) { y = startPos.y + (sh - h); }
|
|
1215
|
-
const isEdge = ['n','s','e','w'].includes(
|
|
1219
|
+
const isEdge = ['n','s','e','w'].includes(hndl);
|
|
1216
1220
|
if (isEdge) {
|
|
1217
|
-
if (
|
|
1218
|
-
|
|
1219
|
-
} else if (hnl === 'e' || hnl === 'w') {
|
|
1220
|
-
y = startPos.y + Math.round((sh - h) / 2);
|
|
1221
|
-
}
|
|
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);
|
|
1222
1223
|
}
|
|
1223
1224
|
data.newPosition = { x: Math.round(x), y: Math.round(y) };
|
|
1224
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
|
+
}
|
|
1225
1255
|
}
|
|
1226
1256
|
// Для произвольных фреймов также обеспечим минимальную площадь
|
|
1227
|
-
if (
|
|
1257
|
+
if (object && object.type === 'frame' && data.newSize && !(object.properties && object.properties === true)) {
|
|
1228
1258
|
const minArea = 1800;
|
|
1229
1259
|
const w0 = Math.max(1, data.newSize.width);
|
|
1230
1260
|
const h0 = Math.max(1, data.newSize.height);
|
|
@@ -1235,22 +1265,20 @@ export class CoreMoodBoard {
|
|
|
1235
1265
|
const h = Math.round(h0 * scale);
|
|
1236
1266
|
data.newSize = { width: w, height: h };
|
|
1237
1267
|
if (!data.newPosition && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1238
|
-
const
|
|
1239
|
-
const
|
|
1268
|
+
const h2 = (this._activeResize?.handle || '').toLowerCase();
|
|
1269
|
+
const sPos2 = this._activeResize.startPosition;
|
|
1240
1270
|
const sw2 = this._activeResize.startSize.width;
|
|
1241
1271
|
const sh2 = this._activeResize.startSize.height;
|
|
1242
|
-
let x2 =
|
|
1243
|
-
let y2 =
|
|
1244
|
-
if (
|
|
1245
|
-
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); }
|
|
1246
1276
|
data.newPosition = { x: Math.round(x2), y: Math.round(y2) };
|
|
1247
1277
|
}
|
|
1248
1278
|
}
|
|
1249
1279
|
}
|
|
1250
1280
|
// Создаем команду только если размер действительно изменился
|
|
1251
|
-
if (data.oldSize.width !== data.newSize.width ||
|
|
1252
|
-
data.oldSize.height !== data.newSize.height) {
|
|
1253
|
-
|
|
1281
|
+
if (data.oldSize.width !== data.newSize.width || data.oldSize.height !== data.newSize.height) {
|
|
1254
1282
|
console.log(`📝 Создаем ResizeObjectCommand:`, {
|
|
1255
1283
|
object: data.object,
|
|
1256
1284
|
oldSize: data.oldSize,
|
|
@@ -1258,14 +1286,13 @@ export class CoreMoodBoard {
|
|
|
1258
1286
|
oldPosition: data.oldPosition,
|
|
1259
1287
|
newPosition: data.newPosition
|
|
1260
1288
|
});
|
|
1261
|
-
|
|
1262
1289
|
// Гарантируем согласованность позиции: если UI не передал, вычислим
|
|
1263
1290
|
let oldPos = data.oldPosition;
|
|
1264
1291
|
let newPos = data.newPosition;
|
|
1265
1292
|
if ((!oldPos || !newPos) && this._activeResize && this._activeResize.objectId === data.object) {
|
|
1266
|
-
const h = (this._activeResize
|
|
1293
|
+
const h = (this._activeResize?.handle || '').toLowerCase();
|
|
1267
1294
|
const start = this._activeResize.startPosition;
|
|
1268
|
-
const startSize = this._activeResize.startSize;
|
|
1295
|
+
const startSize = this.optimization?.startSize || this._activeResize.startSize;
|
|
1269
1296
|
const dw = (data.newSize?.width || startSize.width) - startSize.width;
|
|
1270
1297
|
const dh = (data.newSize?.height || startSize.height) - startSize.height;
|
|
1271
1298
|
const calcNew = { x: start.x + (h.includes('w') ? dw : 0), y: start.y + (h.includes('n') ? dh : 0) };
|
|
@@ -1273,6 +1300,7 @@ export class CoreMoodBoard {
|
|
|
1273
1300
|
if (!newPos) newPos = calcNew;
|
|
1274
1301
|
}
|
|
1275
1302
|
const command = new ResizeObjectCommand(
|
|
1303
|
+
this,
|
|
1276
1304
|
this,
|
|
1277
1305
|
data.object,
|
|
1278
1306
|
data.oldSize,
|
|
@@ -9,18 +9,10 @@ export class DataManager {
|
|
|
9
9
|
/**
|
|
10
10
|
* Загружает данные в MoodBoard
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
loadData(data) {
|
|
13
13
|
if (!data) return;
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const apiClient = this.coreMoodboard?.apiClient;
|
|
18
|
-
if (apiClient && typeof apiClient.restoreObjectUrls === 'function') {
|
|
19
|
-
data = await apiClient.restoreObjectUrls(data);
|
|
20
|
-
}
|
|
21
|
-
} catch (e) {
|
|
22
|
-
console.warn('⚠️ Не удалось восстановить URL изображений по imageId:', e?.message || e);
|
|
23
|
-
}
|
|
15
|
+
|
|
24
16
|
|
|
25
17
|
// Очищаем доску перед загрузкой
|
|
26
18
|
this.clearBoard();
|
|
@@ -31,19 +23,6 @@ export class DataManager {
|
|
|
31
23
|
|
|
32
24
|
data.objects.forEach((objectData, index) => {
|
|
33
25
|
try {
|
|
34
|
-
// Диагностика размеров изображений на загрузке до создания
|
|
35
|
-
if (objectData && objectData.type === 'image') {
|
|
36
|
-
try {
|
|
37
|
-
console.log('🧪 LOAD image size (before create)', {
|
|
38
|
-
id: objectData.id,
|
|
39
|
-
width: objectData.width,
|
|
40
|
-
height: objectData.height,
|
|
41
|
-
propWidth: objectData.properties?.width,
|
|
42
|
-
propHeight: objectData.properties?.height
|
|
43
|
-
});
|
|
44
|
-
} catch (_) {}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
26
|
// Используем полные данные объекта, включая ID
|
|
48
27
|
const createdObject = this.coreMoodboard.createObjectFromData(objectData);
|
|
49
28
|
|
|
@@ -344,7 +344,7 @@ export class MoodBoard {
|
|
|
344
344
|
|
|
345
345
|
if (!boardId || !this.options.apiUrl) {
|
|
346
346
|
console.log('📦 MoodBoard: нет boardId или apiUrl, загружаем пустую доску');
|
|
347
|
-
|
|
347
|
+
this.dataManager.loadData(this.data || { objects: [] });
|
|
348
348
|
|
|
349
349
|
// Вызываем коллбек onLoad
|
|
350
350
|
if (typeof this.options.onLoad === 'function') {
|
|
@@ -374,25 +374,10 @@ export class MoodBoard {
|
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
const boardData = await response.json();
|
|
377
|
-
|
|
378
|
-
// Диагностика: лог размеров изображений прямо из ответа API до любой обработки
|
|
379
|
-
try {
|
|
380
|
-
const objects = (boardData && boardData.data && Array.isArray(boardData.data.objects)) ? boardData.data.objects : [];
|
|
381
|
-
const images = objects.filter(o => o && o.type === 'image');
|
|
382
|
-
images.forEach((o) => {
|
|
383
|
-
console.log('🧪 API LOAD payload image size', {
|
|
384
|
-
id: o.id,
|
|
385
|
-
width: o.width,
|
|
386
|
-
height: o.height,
|
|
387
|
-
propWidth: o.properties?.width,
|
|
388
|
-
propHeight: o.properties?.height
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
} catch (_) {}
|
|
392
377
|
|
|
393
378
|
if (boardData && boardData.data) {
|
|
394
379
|
console.log('✅ MoodBoard: данные загружены с сервера', boardData.data);
|
|
395
|
-
|
|
380
|
+
this.dataManager.loadData(boardData.data);
|
|
396
381
|
|
|
397
382
|
// Вызываем коллбек onLoad
|
|
398
383
|
if (typeof this.options.onLoad === 'function') {
|
|
@@ -400,7 +385,7 @@ export class MoodBoard {
|
|
|
400
385
|
}
|
|
401
386
|
} else {
|
|
402
387
|
console.log('📦 MoodBoard: нет данных с сервера, загружаем пустую доску');
|
|
403
|
-
|
|
388
|
+
this.dataManager.loadData(this.data || { objects: [] });
|
|
404
389
|
|
|
405
390
|
// Вызываем коллбек onLoad
|
|
406
391
|
if (typeof this.options.onLoad === 'function') {
|