@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 +1 -1
- package/src/core/index.js +3 -3
- package/src/initNoBundler.js +1 -1
- package/src/moodboard/integration/MoodBoardLoadApi.js +1 -1
- package/src/ui/ConnectorPropertiesPanel.js +11 -7
- package/src/ui/Topbar.js +24 -10
- package/src/ui/connector-properties/ConnectorPropertiesPanelMapper.js +39 -0
- package/src/ui/styles/workspace.css +1 -1
package/package.json
CHANGED
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:
|
|
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 '#
|
|
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 ??
|
|
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,
|
package/src/initNoBundler.js
CHANGED
|
@@ -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
|
|
66
|
-
if (!
|
|
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 =
|
|
71
|
+
const GAP = 20;
|
|
71
72
|
|
|
72
|
-
let px =
|
|
73
|
-
let py =
|
|
73
|
+
let px = top.x - Math.round(panelW / 2);
|
|
74
|
+
let py = top.topY - panelH - GAP;
|
|
74
75
|
|
|
75
|
-
// Если уходит вверх за контейнер — переносим ниже
|
|
76
|
-
if (py < 0)
|
|
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
|
|
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
|
-
|
|
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
|
|
292
|
-
|
|
293
|
-
this.
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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
|
-
|
|
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
|
*/
|