@sequent-org/moodboard 1.2.54 → 1.2.56

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/ui/Topbar.js +61 -21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequent-org/moodboard",
3
- "version": "1.2.54",
3
+ "version": "1.2.56",
4
4
  "type": "module",
5
5
  "description": "Interactive moodboard",
6
6
  "main": "./src/index.js",
package/src/ui/Topbar.js CHANGED
@@ -11,6 +11,7 @@ export class Topbar {
11
11
  this.theme = theme;
12
12
  this.element = null;
13
13
  this._paintPopover = null;
14
+ this._currentBoardHex = null; // фактический цвет фона доски (#rrggbb)
14
15
  // Загружаем иконки
15
16
  this.iconLoader = new TopbarIconLoader();
16
17
  this.icons = this.iconLoader.icons;
@@ -42,18 +43,31 @@ export class Topbar {
42
43
  this.setActive(type);
43
44
  });
44
45
 
45
- // Обновляем цвет кнопки "краски" при выборе цвета фона
46
- this.eventBus.on(Events.UI.PaintPick, ({ btnHex }) => {
47
- if (!btnHex) return;
48
- this.setPaintButtonHex(btnHex);
46
+ // Обновляем цвет кнопки "краски" и текущий board-hex при выборе цвета фона
47
+ this.eventBus.on(Events.UI.PaintPick, ({ btnHex, color }) => {
48
+ // color — фактический цвет фона доски (может быть #rrggbb или number)
49
+ const normalizeHex = (v) => {
50
+ if (!v) return null;
51
+ if (typeof v === 'number') {
52
+ return `#${v.toString(16).padStart(6,'0')}`.toLowerCase();
53
+ }
54
+ if (typeof v === 'string') {
55
+ const s = v.startsWith('#') ? v : `#${v}`;
56
+ return s.toLowerCase();
57
+ }
58
+ return null;
59
+ };
60
+ const boardHex = normalizeHex(color);
61
+ if (boardHex) this._currentBoardHex = boardHex;
62
+ const mapped = btnHex || this.mapBoardToBtnHex(boardHex);
63
+ if (mapped) this.setPaintButtonHex(mapped);
49
64
  });
50
65
 
51
66
  // Инициализация цвета кнопки "краска" из текущего фона доски, если доступен
52
67
  try {
53
68
  const bgHex = this._getCurrentBoardBackgroundHex();
54
69
  if (bgHex) {
55
- const mapped = this.mapBoardToBtnHex(bgHex);
56
- this.setPaintButtonHex(mapped);
70
+ this.setCurrentBoardHex(bgHex);
57
71
  }
58
72
  } catch (_) {}
59
73
  }
@@ -201,6 +215,15 @@ export class Topbar {
201
215
  }
202
216
  }
203
217
 
218
+ /** Задать текущий фактический цвет фона и синхронизировать кнопку */
219
+ setCurrentBoardHex(boardHex) {
220
+ if (!boardHex) return;
221
+ const v = String(boardHex).toLowerCase();
222
+ this._currentBoardHex = v.startsWith('#') ? v : `#${v}`;
223
+ const mapped = this.mapBoardToBtnHex(this._currentBoardHex) || this._currentBoardHex;
224
+ this.setPaintButtonHex(mapped);
225
+ }
226
+
204
227
  setActive(type) {
205
228
  const buttons = this.element.querySelectorAll('.moodboard-topbar__button');
206
229
  buttons.forEach((b) => b.classList.remove('moodboard-topbar__button--active'));
@@ -253,8 +276,9 @@ export class Topbar {
253
276
  b.style.borderColor = darken(c.hex, 0.35);
254
277
  // Цвет галочки — чёрный для максимальной видимости
255
278
  b.style.color = '#111';
256
- // Для надёжного сравнения — сохраняем исходный hex в dataset
257
- b.dataset.hex = String(c.hex).toLowerCase();
279
+ // Для надёжного сравнения — сохраняем оба значения в dataset
280
+ b.dataset.hex = String(c.hex).toLowerCase(); // цвет кружка-кнопки
281
+ b.dataset.board = String(c.board).toLowerCase(); // фактический цвет фона доски
258
282
  // Галочка по центру
259
283
  const tick = document.createElement('i');
260
284
  tick.className = 'moodboard-topbar__paint-tick';
@@ -277,21 +301,37 @@ export class Topbar {
277
301
  });
278
302
  pop.appendChild(grid);
279
303
 
280
- // Выделяем активный цвет галочкой (надежно — по data-hex)
304
+ // Выделяем активный цвет галочкой (надежно — по data-board, с fallback ближайшего)
281
305
  try {
282
- // 1) Пытаемся получить текущий цвет фона канваса
283
- const boardHex = this._getCurrentBoardBackgroundHex();
284
- // 2) Маппим к hex кнопки палитры
285
- let targetHex = this.mapBoardToBtnHex(boardHex || '') || '';
286
- // 3) Если не удалосьпробуем взять цвет с кнопки (custom prop)
287
- if (!targetHex && this._paintBtn) {
288
- const prop = getComputedStyle(this._paintBtn).getPropertyValue('--paint-btn-color') || '';
289
- targetHex = prop.trim();
306
+ // Текущий цвет фона доски (#rrggbb)
307
+ const currentBoardHex = (this._currentBoardHex || this._getCurrentBoardBackgroundHex() || '').toLowerCase();
308
+ // Пытаемся найти точное совпадение по data-board
309
+ let match = currentBoardHex ? grid.querySelector(`[data-board="${currentBoardHex}"]`) : null;
310
+ // Если точного совпадения нет выбираем ближайший по евклидовой дистанции в RGB
311
+ if (!match) {
312
+ const hexToRgb = (hex) => {
313
+ try {
314
+ const h = hex.replace('#','');
315
+ return {
316
+ r: parseInt(h.substring(0,2), 16),
317
+ g: parseInt(h.substring(2,4), 16),
318
+ b: parseInt(h.substring(4,6), 16)
319
+ };
320
+ } catch (_) { return { r: 0, g: 0, b: 0 }; }
321
+ };
322
+ const dist2 = (a, b) => {
323
+ const dr = a.r - b.r, dg = a.g - b.g, db = a.b - b.b;
324
+ return dr*dr + dg*dg + db*db;
325
+ };
326
+ const target = hexToRgb(currentBoardHex || '#f7fbff');
327
+ let best = null, bestD = Infinity;
328
+ Array.from(grid.children).forEach((el) => {
329
+ const boardHex = el.dataset.board || '';
330
+ const d = dist2(target, hexToRgb(boardHex));
331
+ if (d < bestD) { bestD = d; best = el; }
332
+ });
333
+ match = best;
290
334
  }
291
- // 4) Фолбэк — первый цвет из палитры
292
- if (!targetHex) targetHex = '#B3E5FC';
293
- const normalized = String(targetHex).trim().toLowerCase();
294
- const match = grid.querySelector(`[data-hex="${normalized}"]`);
295
335
  if (match) match.classList.add('is-active');
296
336
  } catch (_) {}
297
337