@sequent-org/moodboard 1.2.103 → 1.2.105
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
CHANGED
|
@@ -252,17 +252,35 @@ export class PlacementTool extends BaseTool {
|
|
|
252
252
|
};
|
|
253
253
|
|
|
254
254
|
if (isTextWithEditing) {
|
|
255
|
-
// Для текста позиция должна совпадать с точкой клика без
|
|
256
|
-
//
|
|
255
|
+
// Для текста позиция должна совпадать с точкой клика без смещений.
|
|
256
|
+
// Используем ту же систему координат, что HtmlTextLayer/HtmlHandlesLayer:
|
|
257
|
+
// CSS ←→ world через toGlobal/toLocal БЕЗ дополнительных поправок на resolution.
|
|
258
|
+
let worldForText = worldPoint;
|
|
257
259
|
try {
|
|
260
|
+
const app = this.app;
|
|
261
|
+
const view = app?.view;
|
|
262
|
+
const worldLayer = this.world || this._getWorldLayer();
|
|
263
|
+
if (view && view.parentElement && worldLayer && worldLayer.toLocal) {
|
|
264
|
+
const containerRect = view.parentElement.getBoundingClientRect();
|
|
265
|
+
const viewRect = view.getBoundingClientRect();
|
|
266
|
+
const offsetLeft = viewRect.left - containerRect.left;
|
|
267
|
+
const offsetTop = viewRect.top - containerRect.top;
|
|
268
|
+
// event.x / event.y заданы в координатах контейнера ToolManager,
|
|
269
|
+
// поэтому приводим их к экранным координатам относительно view
|
|
270
|
+
const screenX = event.x - offsetLeft;
|
|
271
|
+
const screenY = event.y - offsetTop;
|
|
272
|
+
const globalPoint = new PIXI.Point(screenX, screenY);
|
|
273
|
+
const local = worldLayer.toLocal(globalPoint);
|
|
274
|
+
worldForText = { x: local.x, y: local.y };
|
|
275
|
+
}
|
|
258
276
|
console.log('🧭 Text click', {
|
|
259
277
|
cursor: { x: event.x, y: event.y },
|
|
260
|
-
world: { x: Math.round(
|
|
278
|
+
world: { x: Math.round(worldForText.x), y: Math.round(worldForText.y) }
|
|
261
279
|
});
|
|
262
280
|
} catch (_) {}
|
|
263
281
|
position = {
|
|
264
|
-
x: Math.round(
|
|
265
|
-
y: Math.round(
|
|
282
|
+
x: Math.round(worldForText.x),
|
|
283
|
+
y: Math.round(worldForText.y)
|
|
266
284
|
};
|
|
267
285
|
// Слушаем событие создания объекта, чтобы получить его ID
|
|
268
286
|
const handleObjectCreated = (objectData) => {
|
|
@@ -2067,23 +2067,49 @@ export class SelectTool extends BaseTool {
|
|
|
2067
2067
|
} catch (_) {}
|
|
2068
2068
|
|
|
2069
2069
|
// Для новых текстов: синхронизируем мировую позицию объекта с фактической позицией wrapper,
|
|
2070
|
-
// чтобы после закрытия редактора статичный текст встал ровно туда же без
|
|
2070
|
+
// чтобы после закрытия редактора статичный текст встал ровно туда же без сдвига.
|
|
2071
|
+
// Используем ту же систему координат, что и HtmlTextLayer/HtmlHandlesLayer:
|
|
2072
|
+
// CSS ←→ world через toGlobal/toLocal БЕЗ умножения/деления на resolution.
|
|
2071
2073
|
try {
|
|
2072
2074
|
if (create && objectId) {
|
|
2073
2075
|
const worldLayerRef = this.textEditor.world || (this.app?.stage);
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2076
|
+
const viewEl = this.app?.view;
|
|
2077
|
+
if (worldLayerRef && viewEl && viewEl.parentElement) {
|
|
2078
|
+
const containerRect = viewEl.parentElement.getBoundingClientRect();
|
|
2079
|
+
const viewRect = viewEl.getBoundingClientRect();
|
|
2080
|
+
const offsetLeft = viewRect.left - containerRect.left;
|
|
2081
|
+
const offsetTop = viewRect.top - containerRect.top;
|
|
2082
|
+
|
|
2083
|
+
// Статичный HTML-текст не имеет верхнего внутреннего отступа (HtmlTextLayer ставит padding: 0),
|
|
2084
|
+
// поэтому добавляем padTop к topPx при расчёте мировой позиции верхнего края текста.
|
|
2085
|
+
const yCssStaticTop = Math.round(topPx + padTop);
|
|
2086
|
+
// Переводим CSS-координаты wrapper в экранные координаты относительно view
|
|
2087
|
+
const screenX = Math.round(leftPx - offsetLeft);
|
|
2088
|
+
const screenY = Math.round(yCssStaticTop - offsetTop);
|
|
2089
|
+
const globalPoint = new PIXI.Point(screenX, screenY);
|
|
2090
|
+
const worldPoint = worldLayerRef.toLocal
|
|
2091
|
+
? worldLayerRef.toLocal(globalPoint)
|
|
2092
|
+
: { x: position.x, y: position.y };
|
|
2093
|
+
const newWorldPos = {
|
|
2094
|
+
x: Math.round(worldPoint.x),
|
|
2095
|
+
y: Math.round(worldPoint.y)
|
|
2096
|
+
};
|
|
2097
|
+
this.eventBus.emit(Events.Object.StateChanged, {
|
|
2098
|
+
objectId: objectId,
|
|
2099
|
+
updates: { position: newWorldPos }
|
|
2100
|
+
});
|
|
2101
|
+
// Диагностика
|
|
2102
|
+
console.log('🧭 Text position sync', {
|
|
2103
|
+
objectId,
|
|
2104
|
+
newWorldPos,
|
|
2105
|
+
leftPx,
|
|
2106
|
+
topPx,
|
|
2107
|
+
yCssStaticTop,
|
|
2108
|
+
padTop,
|
|
2109
|
+
offsetLeft,
|
|
2110
|
+
offsetTop
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2087
2113
|
}
|
|
2088
2114
|
} catch (_) {}
|
|
2089
2115
|
}
|