@sequent-org/moodboard 1.4.52 → 1.4.53

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.4.52",
3
+ "version": "1.4.53",
4
4
  "type": "module",
5
5
  "description": "Interactive moodboard",
6
6
  "main": "./src/index.js",
package/src/core/index.js CHANGED
@@ -39,7 +39,7 @@ export class CoreMoodBoard {
39
39
  autoSave: false,
40
40
  width: this.container.clientWidth || 800,
41
41
  height: this.container.clientHeight || 600,
42
- backgroundColor: 0xF5F5F5,
42
+ backgroundColor: 0xFFFFFF,
43
43
  ...options
44
44
  };
45
45
 
@@ -624,7 +624,7 @@ export class CoreMoodBoard {
624
624
  const app = this.pixi?.app;
625
625
  const rendererBg = app?.renderer?.background?.color ?? app?.renderer?.backgroundColor;
626
626
  const toHex = (num) => {
627
- try { return '#' + Number(num >>> 0).toString(16).padStart(6, '0'); } catch (_) { return '#F5F5F5'; }
627
+ try { return '#' + Number(num >>> 0).toString(16).padStart(6, '0'); } catch (_) { return '#FFFFFF'; }
628
628
  };
629
629
  const world = this.pixi?.worldLayer || app?.stage;
630
630
  const currentZoom = Math.max(0.02, Math.min(5, world?.scale?.x || 1));
@@ -653,7 +653,7 @@ export class CoreMoodBoard {
653
653
  })();
654
654
 
655
655
  const settings = {
656
- backgroundColor: toHex(rendererBg ?? 0xF5F5F5),
656
+ backgroundColor: toHex(rendererBg ?? 0xFFFFFF),
657
657
  grid: gridSettings || undefined,
658
658
  zoom: { min: 0.1, max: 5.0, default: 1.0, current: currentZoom },
659
659
  pan: currentPan,
@@ -59,7 +59,7 @@ export function injectCriticalStyles() {
59
59
  width: 100%;
60
60
  height: 100%;
61
61
  overflow: hidden;
62
- background: #f0f6fc;
62
+ background: #ffffff;
63
63
  }
64
64
 
65
65
  .moodboard-workspace__toolbar {
@@ -1,7 +1,7 @@
1
1
  import { Events } from '../../core/events/Events.js';
2
2
 
3
3
  const BOARD_DEFAULTS = {
4
- backgroundColor: '#daeefb',
4
+ backgroundColor: '#ffffff',
5
5
  grid: { type: 'cross' },
6
6
  };
7
7
 
@@ -10,6 +10,7 @@ import {
10
10
  getSelectedConnectorId,
11
11
  getConnectorData,
12
12
  getConnectorMidpointScreen,
13
+ getConnectorTopScreen,
13
14
  getConnectorStyle,
14
15
  buildStyleUpdate,
15
16
  } from './connector-properties/ConnectorPropertiesPanelMapper.js';
@@ -62,18 +63,21 @@ export class ConnectorPropertiesPanel {
62
63
  const stillSelected = getSelectedConnectorId(this.core) === this.currentId;
63
64
  if (!stillSelected) { this.hide(); return; }
64
65
 
65
- const mid = getConnectorMidpointScreen(this.core, this.currentId);
66
- if (!mid) return;
66
+ const top = getConnectorTopScreen(this.core, this.currentId);
67
+ if (!top) return;
67
68
 
68
69
  const panelW = this.panel.offsetWidth || 480;
69
70
  const panelH = this.panel.offsetHeight || 40;
70
- const GAP = 18;
71
+ const GAP = 20;
71
72
 
72
- let px = mid.x - Math.round(panelW / 2);
73
- let py = mid.y - panelH - GAP;
73
+ let px = top.x - Math.round(panelW / 2);
74
+ let py = top.topY - panelH - GAP;
74
75
 
75
- // Если уходит вверх за контейнер — переносим ниже середины
76
- if (py < 0) py = mid.y + GAP;
76
+ // Если уходит вверх за контейнер — переносим ниже наивысшей точки
77
+ if (py < 0) {
78
+ const mid = getConnectorMidpointScreen(this.core, this.currentId);
79
+ py = (mid?.y ?? top.topY) + GAP;
80
+ }
77
81
 
78
82
  // Clamp по ширине контейнера
79
83
  const cw = this.container.offsetWidth || window.innerWidth;
package/src/ui/Topbar.js CHANGED
@@ -176,10 +176,18 @@ export class Topbar {
176
176
  _getCurrentBoardBackgroundHex() {
177
177
  try {
178
178
  const app = window?.moodboard?.coreMoodboard?.pixi?.app || window?.moodboard?.core?.pixi?.app;
179
- const colorInt = app?.renderer?.background?.color ?? app?.renderer?.backgroundColor;
179
+ const renderer = app?.renderer;
180
+ if (!renderer) return null;
181
+ const bg = renderer.background;
182
+ // PIXI v7+: bg.color — экземпляр Color с методом toHex()
183
+ if (bg?.color && typeof bg.color.toHex === 'function') {
184
+ return String(bg.color.toHex()).toLowerCase();
185
+ }
186
+ const colorInt = (typeof bg?.color === 'number')
187
+ ? bg.color
188
+ : (typeof renderer.backgroundColor === 'number' ? renderer.backgroundColor : null);
180
189
  if (typeof colorInt !== 'number') return null;
181
- const hex = `#${colorInt.toString(16).padStart(6, '0')}`;
182
- return hex.toLowerCase();
190
+ return `#${colorInt.toString(16).padStart(6, '0')}`.toLowerCase();
183
191
  } catch (_) { return null; }
184
192
  }
185
193
 
@@ -288,14 +296,20 @@ export class Topbar {
288
296
  // Выделяем активный цвет галочкой по фактическому boardHex
289
297
  try {
290
298
  const ap = window?.moodboard?.coreMoodboard?.settingsApplier;
291
- const boardHex = (
292
- (ap && ap.get && ap.get().backgroundColor) ||
293
- this._currentBoardHex ||
294
- this._getCurrentBoardBackgroundHex() ||
295
- ''
296
- ).toLowerCase();
299
+ const raw = (ap && ap.get && ap.get().backgroundColor)
300
+ || this._currentBoardHex
301
+ || this._getCurrentBoardBackgroundHex()
302
+ || '';
303
+ let boardHex = '';
304
+ if (typeof raw === 'number') {
305
+ boardHex = `#${raw.toString(16).padStart(6, '0')}`;
306
+ } else if (typeof raw === 'string') {
307
+ boardHex = raw;
308
+ }
309
+ boardHex = boardHex.toLowerCase();
297
310
  const match = boardHex ? grid.querySelector(`[data-board="${boardHex}"]`) : null;
298
- if (match) match.classList.add('is-active');
311
+ const toActivate = match || grid.querySelector('[data-board="#ffffff"]');
312
+ if (toActivate) toActivate.classList.add('is-active');
299
313
  } catch (_) {}
300
314
 
301
315
  // позиционируем поповер
@@ -119,6 +119,45 @@ export function getConnectorMidpointScreen(core, connectorId) {
119
119
  };
120
120
  }
121
121
 
122
+ /**
123
+ * Возвращает наивысшую экранную точку коннектора (минимальный y) и горизонтальный центр.
124
+ * Координаты — целые числа (screen-space integer contract).
125
+ * @returns {{ x: number, topY: number } | null}
126
+ */
127
+ export function getConnectorTopScreen(core, connectorId) {
128
+ const segments = core?.connectorLayer?._lastSegments;
129
+ if (!segments) return null;
130
+ const seg = segments.find(s => s.id === connectorId);
131
+ if (!seg) return null;
132
+
133
+ const worldLayer = core?.pixi?.worldLayer;
134
+ const scale = worldLayer?.scale?.x ?? 1;
135
+ const worldX = worldLayer?.x ?? 0;
136
+ const worldY = worldLayer?.y ?? 0;
137
+
138
+ let pts;
139
+ if (seg.points && seg.points.length >= 2) {
140
+ pts = seg.points;
141
+ } else if (seg.start && seg.end) {
142
+ pts = [seg.start, seg.end];
143
+ } else {
144
+ return null;
145
+ }
146
+
147
+ let minWorldY = Infinity;
148
+ let sumWorldX = 0;
149
+ for (const p of pts) {
150
+ if (p.y < minWorldY) minWorldY = p.y;
151
+ sumWorldX += p.x;
152
+ }
153
+ const avgWorldX = sumWorldX / pts.length;
154
+
155
+ return {
156
+ x: Math.round(avgWorldX * scale + worldX),
157
+ topY: Math.round(minWorldY * scale + worldY),
158
+ };
159
+ }
160
+
122
161
  /**
123
162
  * Формирует updates.properties.style для StateChanged-эмита.
124
163
  */
@@ -731,7 +731,7 @@
731
731
 
732
732
  /* Light Theme */
733
733
  .moodboard-workspace--light {
734
- background: #f8f9fa;
734
+ background: #ffffff;
735
735
  color: #333;
736
736
  }
737
737