kingkont 0.7.83 → 0.7.84

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": "kingkont",
3
- "version": "0.7.83",
3
+ "version": "0.7.84",
4
4
  "description": "KingKont · Chatium — нод-редактор сцен с AI-генерацией (картинки/видео/голос/SFX/музыка/текст)",
5
5
  "main": "main.js",
6
6
  "bin": {
package/renderer/board.js CHANGED
@@ -1638,8 +1638,14 @@ async function createNodeEl(node) {
1638
1638
  el.dataset.id = node.id;
1639
1639
  el.style.left = node.x + 'px';
1640
1640
  el.style.top = node.y + 'px';
1641
- if (node.width) el.style.width = node.width + 'px';
1642
- if (node.height) el.style.height = node.height + 'px';
1641
+ // Label-ноды всегда auto-размер (по тексту) фиксированный width/height
1642
+ // создавал «невидимые боксы» вокруг текста, что ломало hit-testing когда
1643
+ // несколько label оказывались рядом (клик попадал в перекрывающий, а не
1644
+ // в видимый текст). Игнорируем сохранённые width/height для label-нод.
1645
+ if (node.type !== 'label') {
1646
+ if (node.width) el.style.width = node.width + 'px';
1647
+ if (node.height) el.style.height = node.height + 'px';
1648
+ }
1643
1649
 
1644
1650
  const header = document.createElement('div');
1645
1651
  header.className = 'node-header';
@@ -213,7 +213,8 @@ async function addLabelAt(pos) {
213
213
  text: '',
214
214
  textStyle: { fontSize: 32, italic: false, fontFamily: 'handwritten' },
215
215
  x, y,
216
- width: 260, height: 90,
216
+ // width/height не задаём — label всегда auto-размер по тексту
217
+ // (см. createNodeEl: для type='label' inline-style не применяется).
217
218
  };
218
219
  state.currentBoard.metadata.nodes.push(node);
219
220
  const el = await createNodeEl(node);
@@ -415,48 +415,72 @@
415
415
  }
416
416
 
417
417
  /* === Label-node — плавающая текст-аннотация поверх холста ===
418
- Без фона / рамки / тени выглядит как «написанный» прямо на сцене текст.
419
- Header / footer / resize / anchor скрыты по умолчанию, появляются на
420
- hover чтобы можно было перетаскивать, удалять, ресайзить. */
418
+ Auto-размер по тексту: .node автоматически сжимается до контента,
419
+ никаких «невидимых боксов» вокруг текста. Header / toolbar /
420
+ resize / anchor вынесены за пределы видимой области (absolute) и
421
+ показываются на hover. */
421
422
  .node.label-node {
422
423
  background: transparent;
423
424
  border: none; box-shadow: none;
424
425
  padding: 0;
426
+ overflow: visible; /* absolute-дети могут выйти за рамки */
427
+ width: auto !important; /* override любого inline-width из старых сцен */
428
+ height: auto !important;
429
+ min-width: 30px;
430
+ max-width: 800px; /* лимит чтобы не получить однострочного монстра */
431
+ display: block; /* отключаем flex-column — нам не нужно */
432
+ contain: none; /* отменяем content-visibility-оптимизацию */
433
+ contain-intrinsic-size: auto;
425
434
  }
426
435
  .node.label-node.selected {
427
436
  outline: 1px dashed rgba(90,168,255,0.8);
428
437
  outline-offset: 2px;
429
438
  }
430
- .node.label-node .node-header,
431
- .node.label-node .node-footer,
432
- .node.label-node .resize-handle,
433
- .node.label-node .anchor,
434
- .node.label-node .label-toolbar {
435
- opacity: 0; transition: opacity 0.15s;
436
- }
437
- .node.label-node:hover .node-header,
438
- .node.label-node:hover .node-footer,
439
- .node.label-node:hover .resize-handle,
440
- .node.label-node:hover .anchor,
441
- .node.label-node:hover .label-toolbar,
442
- .node.label-node:focus-within .label-toolbar { opacity: 1; }
439
+
440
+ /* Header (drag-handle + имя + ×) — absolute над текстом, hover-only. */
443
441
  .node.label-node .node-header {
444
- background: rgba(20,20,20,0.85);
445
- border-radius: 6px 6px 0 0;
442
+ position: absolute;
443
+ bottom: 100%; /* над label, без занятия layout */
444
+ left: 0; right: 0;
445
+ background: rgba(20,20,20,0.92);
446
+ border-radius: 4px 4px 0 0;
447
+ margin-bottom: 2px;
448
+ opacity: 0; transition: opacity 0.15s;
449
+ pointer-events: none; /* hover-only включаем ниже */
446
450
  }
451
+ /* Footer для label не используется (нет сгенерированной информации) — скрываем. */
452
+ .node.label-node .node-footer { display: none; }
453
+ /* Resize и anchor для label не нужны — текст auto-размером, ссылок нет. */
454
+ .node.label-node .resize-handle,
455
+ .node.label-node .anchor { display: none; }
456
+
457
+ /* Body — wrapper без визуального вклада. */
447
458
  .node.label-node .node-body {
448
459
  padding: 0; background: transparent;
449
- display: flex; flex-direction: column; min-height: 0;
460
+ display: block; min-height: 0;
461
+ position: relative;
450
462
  }
451
463
 
452
- /* Тулбар форматирования label поверх текста, на hover. */
464
+ /* Тулбар форматирования — absolute под текстом, hover-only. */
453
465
  .node.label-node .label-toolbar {
466
+ position: absolute;
467
+ top: 100%; /* под label */
468
+ left: 0;
469
+ margin-top: 4px;
454
470
  display: flex; align-items: center; gap: 4px;
455
471
  padding: 3px 6px; background: rgba(20,20,20,0.92);
456
- border-radius: 4px; margin: 4px;
472
+ border-radius: 4px;
457
473
  font-size: 11px; flex-shrink: 0;
458
- align-self: flex-start;
459
- pointer-events: auto;
474
+ opacity: 0; transition: opacity 0.15s;
475
+ pointer-events: none;
476
+ white-space: nowrap;
477
+ z-index: 10;
478
+ }
479
+ .node.label-node:hover .node-header,
480
+ .node.label-node:hover .label-toolbar,
481
+ .node.label-node:focus-within .node-header,
482
+ .node.label-node:focus-within .label-toolbar {
483
+ opacity: 1; pointer-events: auto;
460
484
  }
461
485
  .node.label-node .label-toolbar select,
462
486
  .node.label-node .label-toolbar button {
@@ -471,15 +495,17 @@
471
495
  }
472
496
  .node.label-node .label-toolbar .tt-italic { font-style: italic; min-width: 22px; }
473
497
 
474
- /* Сам текст. flex:1 занимает оставшееся тело, поэтому drag-area
475
- совпадает с визуальной областью. */
498
+ /* Сам текстauto-ширина по контенту, до max-width. */
476
499
  .node.label-node .label-text {
477
- flex: 1; padding: 8px 12px;
500
+ display: inline-block;
501
+ padding: 4px 8px;
478
502
  color: #eaeaea; line-height: 1.2;
479
503
  word-break: break-word; white-space: pre-wrap;
480
504
  outline: none; cursor: text;
481
505
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
482
506
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
507
+ min-width: 30px;
508
+ max-width: 100%;
483
509
  }
484
510
  .node.label-node .label-text:empty::before {
485
511
  content: attr(data-placeholder);