@sequent-org/moodboard 1.2.97 → 1.2.99

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequent-org/moodboard",
3
- "version": "1.2.97",
3
+ "version": "1.2.99",
4
4
  "type": "module",
5
5
  "description": "Interactive moodboard",
6
6
  "main": "./src/index.js",
@@ -2690,29 +2690,27 @@ export class SelectTool extends BaseTool {
2690
2690
  const worldLayerRef = this.textEditor.world || (this.app?.stage);
2691
2691
  const cssLeft = this.textEditor._cssLeftPx;
2692
2692
  const cssTop = this.textEditor._cssTopPx;
2693
- if (isFinite(cssLeft) && isFinite(cssTop) && worldLayerRef && view && view.parentElement) {
2693
+ if (view && view.parentElement && isFinite(cssLeft) && isFinite(cssTop) && worldLayerRef) {
2694
2694
  // Ждем один тик, чтобы HtmlTextLayer успел обновить DOM
2695
2695
  setTimeout(() => {
2696
2696
  try {
2697
- // Используем тот же подход что в toScreen, но в обратном направлении
2697
+ // Инвертируем ту же трансформацию, что использует HtmlHandlesLayer/HtmlTextLayer:
2698
+ // world → toGlobal → offset → CSS px
2698
2699
  const containerRect = view.parentElement.getBoundingClientRect();
2699
2700
  const viewRect = view.getBoundingClientRect();
2700
2701
  const offsetLeft = viewRect.left - containerRect.left;
2701
2702
  const offsetTop = viewRect.top - containerRect.top;
2702
-
2703
- // Преобразуем CSS координаты в экранные (учитывая offset)
2703
+ // CSS → экранные координаты внутри canvas
2704
2704
  const screenX = cssLeft - offsetLeft;
2705
2705
  const screenY = cssTop - offsetTop;
2706
-
2707
- // Преобразуем экранные координаты в мировые
2706
+ // Экранные → мировые координаты через toLocal
2708
2707
  const desiredWorld = worldLayerRef.toLocal(new PIXI.Point(screenX, screenY));
2709
2708
  const newPos = { x: Math.round(desiredWorld.x), y: Math.round(desiredWorld.y) };
2710
-
2711
2709
  this.eventBus.emit(Events.Object.StateChanged, {
2712
2710
  objectId,
2713
2711
  updates: { position: newPos }
2714
2712
  });
2715
- console.log('🧭 Text post-show align', { objectId, cssLeft, cssTop, screenX, screenY, newPos });
2713
+ console.log('🧭 Text post-show align', { objectId, cssLeft, cssTop, newPos });
2716
2714
  } catch (_) {}
2717
2715
  }, 0);
2718
2716
  }
@@ -1,4 +1,5 @@
1
1
  import { Events } from '../core/events/Events.js';
2
+ import * as PIXI from 'pixi.js';
2
3
 
3
4
  /**
4
5
  * HtmlTextLayer — рисует текст как HTML-элементы поверх PIXI для максимальной чёткости
@@ -258,7 +259,7 @@ export class HtmlTextLayer {
258
259
  if (!el || !this.core) return;
259
260
 
260
261
  console.log(`🔍 HtmlTextLayer: обновляю позицию для текста ${objectId}`);
261
-
262
+
262
263
  const world = this.core.pixi.worldLayer || this.core.pixi.app.stage;
263
264
  const s = world?.scale?.x || 1;
264
265
  const tx = world?.x || 0;
@@ -308,7 +309,12 @@ export class HtmlTextLayer {
308
309
  // Позиция и габариты в CSS координатах - используем тот же подход что в HtmlHandlesLayer
309
310
  const worldLayer = this.core.pixi.worldLayer || this.core.pixi.app.stage;
310
311
  const view = this.core.pixi.app.view;
311
-
312
+ // Эти переменные нужны и для лога ниже, поэтому задаём их тут
313
+ let logLeft = 0;
314
+ let logTop = 0;
315
+ let logWidth = 0;
316
+ let logHeight = 0;
317
+
312
318
  if (worldLayer && view && view.parentElement) {
313
319
  const containerRect = view.parentElement.getBoundingClientRect();
314
320
  const viewRect = view.getBoundingClientRect();
@@ -324,13 +330,20 @@ export class HtmlTextLayer {
324
330
  const top = offsetTop + tl.y;
325
331
  const width = Math.max(1, br.x - tl.x);
326
332
  const height = Math.max(1, br.y - tl.y);
327
-
333
+
334
+ // Применяем к элементу
328
335
  el.style.left = `${left}px`;
329
336
  el.style.top = `${top}px`;
330
337
  if (w && h) {
331
338
  el.style.width = `${width}px`;
332
339
  el.style.height = `${height}px`;
333
340
  }
341
+
342
+ // Значения для лога
343
+ logLeft = left;
344
+ logTop = top;
345
+ logWidth = width;
346
+ logHeight = height;
334
347
  } else {
335
348
  // Fallback к старому методу
336
349
  const left = (tx + s * x) / res;
@@ -338,9 +351,15 @@ export class HtmlTextLayer {
338
351
  el.style.left = `${left}px`;
339
352
  el.style.top = `${top}px`;
340
353
  if (w && h) {
341
- el.style.width = `${Math.max(1, (w * s) / res)}px`;
342
- el.style.height = `${Math.max(1, (h * s) / res)}px`;
354
+ const cssW = Math.max(1, (w * s) / res);
355
+ const cssH = Math.max(1, (h * s) / res);
356
+ el.style.width = `${cssW}px`;
357
+ el.style.height = `${cssH}px`;
358
+ logWidth = cssW;
359
+ logHeight = cssH;
343
360
  }
361
+ logLeft = left;
362
+ logTop = top;
344
363
  }
345
364
  // Поворот вокруг центра (как у PIXI и HTML-ручек)
346
365
  el.style.transformOrigin = 'center center';
@@ -356,15 +375,19 @@ export class HtmlTextLayer {
356
375
  try {
357
376
  el.style.height = 'auto';
358
377
  // Добавим небольшой нижний отступ для хвостов букв, чтобы не отсекались (например, у «з»)
359
- const h = Math.max(1, Math.round(el.scrollHeight + 2));
360
- el.style.height = `${h}px`;
378
+ const hCss = Math.max(1, Math.round(el.scrollHeight + 2));
379
+ el.style.height = `${hCss}px`;
380
+ // Обновим высоту для лога, если её ещё не устанавливали
381
+ if (!logHeight) {
382
+ logHeight = hCss;
383
+ }
361
384
  } catch (_) {}
362
385
 
363
386
  console.log(`🔍 HtmlTextLayer: позиция обновлена для ${objectId}:`, {
364
- left: `${left}px`,
365
- top: `${top}px`,
366
- width: `${Math.max(1, (w * s) / res)}px`,
367
- height: `${Math.max(1, (h * s) / res)}px`,
387
+ left: `${logLeft}px`,
388
+ top: `${logTop}px`,
389
+ width: `${logWidth}px`,
390
+ height: `${logHeight}px`,
368
391
  fontSize: `${fontSizePx}px`,
369
392
  content: content,
370
393
  visibility: el.style.visibility,