@sequent-org/moodboard 1.2.19 → 1.2.21
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 +16 -3
- package/src/moodboard/DataManager.js +14 -1
package/package.json
CHANGED
package/src/core/index.js
CHANGED
|
@@ -2062,13 +2062,26 @@ export class CoreMoodBoard {
|
|
|
2062
2062
|
* Создание объекта из полных данных (для загрузки с сервера)
|
|
2063
2063
|
*/
|
|
2064
2064
|
createObjectFromData(objectData) {
|
|
2065
|
-
//
|
|
2066
|
-
|
|
2065
|
+
// Защита от двойной загрузки одного и того же объекта (дубликаты при повторном вызове loadData)
|
|
2066
|
+
try {
|
|
2067
|
+
const id = objectData && objectData.id;
|
|
2068
|
+
const alreadyInPixi = !!(id && this.pixi && this.pixi.objects && this.pixi.objects.has(id));
|
|
2069
|
+
const alreadyInState = !!(id && Array.isArray(this.state?.state?.objects) && this.state.state.objects.some(o => o && o.id === id));
|
|
2070
|
+
if (alreadyInPixi || alreadyInState) {
|
|
2071
|
+
// Объект уже создан ранее в этой сессии — не добавляем повторно ни в state, ни в PIXI
|
|
2072
|
+
return objectData;
|
|
2073
|
+
}
|
|
2074
|
+
} catch (_) { /* no-op */ }
|
|
2075
|
+
|
|
2076
|
+
// Инициализируем флаг компенсации пивота для загруженных объектов.
|
|
2077
|
+
// В state координаты хранятся как левый-верх. PIXI позиционирует по центру (anchor/pivot по центру),
|
|
2078
|
+
// поэтому при создании нужно ДОБАВИТЬ половину ширины/высоты (т.е. pivotCompensated должен быть false),
|
|
2079
|
+
// чтобы PixiEngine выполнил компенсацию.
|
|
2067
2080
|
if (!objectData.transform) {
|
|
2068
2081
|
objectData.transform = {};
|
|
2069
2082
|
}
|
|
2070
2083
|
if (objectData.transform.pivotCompensated === undefined) {
|
|
2071
|
-
objectData.transform.pivotCompensated =
|
|
2084
|
+
objectData.transform.pivotCompensated = false;
|
|
2072
2085
|
}
|
|
2073
2086
|
|
|
2074
2087
|
// Используем существующие данные объекта (с его ID, размерами и т.д.)
|
|
@@ -73,9 +73,22 @@ export class DataManager {
|
|
|
73
73
|
clearBoard() {
|
|
74
74
|
if (!this.coreMoodboard) return;
|
|
75
75
|
|
|
76
|
+
// 1) Удаляем все объекты, известные состоянию
|
|
76
77
|
const objects = this.coreMoodboard.objects || [];
|
|
77
78
|
objects.forEach(obj => this.coreMoodboard.deleteObject(obj.id));
|
|
78
|
-
|
|
79
|
+
|
|
80
|
+
// 2) Страховка: удаляем «висячие» PIXI-объекты, которые не попали в state
|
|
81
|
+
try {
|
|
82
|
+
const pixi = this.coreMoodboard.pixi;
|
|
83
|
+
const stateIds = new Set((this.coreMoodboard.state?.state?.objects || []).map(o => o && o.id));
|
|
84
|
+
if (pixi && pixi.objects && pixi.objects.size > 0) {
|
|
85
|
+
for (const [objectId] of pixi.objects) {
|
|
86
|
+
if (!stateIds.has(objectId)) {
|
|
87
|
+
pixi.removeObject(objectId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
} catch (_) { /* no-op */ }
|
|
79
92
|
|
|
80
93
|
return objects.length;
|
|
81
94
|
}
|