@sequent-org/moodboard 1.2.85 → 1.2.86

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.85",
3
+ "version": "1.2.86",
4
4
  "type": "module",
5
5
  "description": "Interactive moodboard",
6
6
  "main": "./src/index.js",
@@ -1,21 +1,4 @@
1
1
  import { BaseTool } from '../BaseTool.js';
2
- import iCursorSvg from '../../assets/icons/i-cursor.svg?raw';
3
-
4
- // Масштабируем I-курсор в 2 раза меньше (примерно 16x32 с сохранением пропорций 1:2)
5
- const _scaledICursorSvg = (() => {
6
- try {
7
- if (!/\bwidth="/i.test(iCursorSvg)) {
8
- return iCursorSvg.replace('<svg ', '<svg width="16px" height="32px" ');
9
- }
10
- return iCursorSvg
11
- .replace(/width="[^"]+"/i, 'width="16px"')
12
- .replace(/height="[^"]+"/i, 'height="32px"');
13
- } catch (_) {
14
- return iCursorSvg;
15
- }
16
- })();
17
-
18
- const TEXT_CURSOR = `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(_scaledICursorSvg)}") 0 0, text`;
19
2
 
20
3
  /**
21
4
  * Инструмент для создания и редактирования текстовых объектов
@@ -23,7 +6,7 @@ const TEXT_CURSOR = `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(
23
6
  export class TextTool extends BaseTool {
24
7
  constructor(eventBus) {
25
8
  super('text', eventBus);
26
- this.cursor = 'text';
9
+ this.cursor = 'text';
27
10
  this.hotkey = 't';
28
11
  this.container = null;
29
12
 
@@ -49,13 +32,16 @@ export class TextTool extends BaseTool {
49
32
  onMouseDown(event) {
50
33
  super.onMouseDown(event);
51
34
 
35
+ // Преобразуем экранные координаты в мировые координаты PIXI
36
+ const worldPoint = this._toWorld(event.x, event.y);
37
+
52
38
  // Проверяем, кликнули ли на существующий текстовый объект
53
39
  const hitObject = this.getTextObjectAt(event.x, event.y);
54
40
 
55
41
  if (hitObject) {
56
42
  this.startEditing(hitObject, event);
57
43
  } else {
58
- this.createNewText(event.x, event.y);
44
+ this.createNewText(worldPoint.x, worldPoint.y);
59
45
  }
60
46
  }
61
47
 
@@ -132,10 +118,13 @@ export class TextTool extends BaseTool {
132
118
  /**
133
119
  * Создание HTML input для редактирования текста
134
120
  */
135
- createTextInput(x, y, initialText) {
121
+ createTextInput(worldX, worldY, initialText) {
136
122
  // Удаляем предыдущий input если есть
137
123
  this.removeTextInput();
138
124
 
125
+ // Преобразуем мировые координаты в экранные для HTML элемента
126
+ const screenPos = this._toScreen(worldX, worldY);
127
+
139
128
  // Создаем новый input
140
129
  this.textInput = document.createElement('textarea');
141
130
  this.textInput.value = initialText;
@@ -144,8 +133,8 @@ export class TextTool extends BaseTool {
144
133
  // Стили input
145
134
  Object.assign(this.textInput.style, {
146
135
  position: 'absolute',
147
- left: `${x}px`,
148
- top: `${y}px`,
136
+ left: `${screenPos.x}px`,
137
+ top: `${screenPos.y}px`,
149
138
  border: '2px solid #007bff',
150
139
  borderRadius: '4px',
151
140
  padding: '4px 8px',
@@ -401,14 +390,15 @@ export class TextTool extends BaseTool {
401
390
  */
402
391
  activate(pixiApp) {
403
392
  super.activate();
393
+ this.pixiApp = pixiApp;
404
394
 
405
395
  // Устанавливаем контейнер для размещения input
406
396
  if (pixiApp && pixiApp.view && pixiApp.view.parentElement) {
407
397
  this.setContainer(pixiApp.view.parentElement);
408
398
  }
409
- // Устанавливаем кастомный курсор на холст
399
+ // Устанавливаем стандартный текстовый курсор
410
400
  if (pixiApp && pixiApp.view) {
411
- pixiApp.view.style.cursor = (this.cursor && this.cursor !== 'default') ? this.cursor : '';
401
+ pixiApp.view.style.cursor = 'text';
412
402
  }
413
403
  }
414
404
 
@@ -421,6 +411,30 @@ export class TextTool extends BaseTool {
421
411
  }
422
412
  }
423
413
 
414
+ /**
415
+ * Преобразование экранных координат в мировые (worldLayer)
416
+ */
417
+ _toWorld(x, y) {
418
+ if (!this.pixiApp || !this.pixiApp.stage) return { x, y };
419
+ const world = this.pixiApp.stage.getChildByName && this.pixiApp.stage.getChildByName('worldLayer');
420
+ if (!world || !world.toLocal) return { x, y };
421
+ const p = new PIXI.Point(x, y);
422
+ const local = world.toLocal(p);
423
+ return { x: local.x, y: local.y };
424
+ }
425
+
426
+ /**
427
+ * Преобразование мировых координат в экранные для HTML элементов
428
+ */
429
+ _toScreen(worldX, worldY) {
430
+ if (!this.pixiApp || !this.pixiApp.stage) return { x: worldX, y: worldY };
431
+ const world = this.pixiApp.stage.getChildByName && this.pixiApp.stage.getChildByName('worldLayer');
432
+ if (!world || !world.toGlobal) return { x: worldX, y: worldY };
433
+ const p = new PIXI.Point(worldX, worldY);
434
+ const global = world.toGlobal(p);
435
+ return { x: global.x, y: global.y };
436
+ }
437
+
424
438
  /**
425
439
  * Установка настроек текста по умолчанию
426
440
  */