feat(tgu-ops-ui): OSM tiles, editor layout fixes, map resizer

Карта:
- Заменить схематичные контуры континентов на тайлы CartoDB Dark
  (dark_nolabels, CC BY 3.0, без API-ключа) через модульный кеш
  tileLoader.ts + отрисовщик drawTiles.ts на существующей Web Mercator
  проекции — без новых зависимостей
- Сохранить сетку lat/lon 30° поверх тайлов (полезна для орбитального
  анализа), убрать нарисованные контуры и градиент океана
- Обновить атрибуцию: © OpenStreetMap contributors · © CARTO

Вкладка Редактор — раскладка:
- Исправить цепочку высот: workspace переведён с display:grid на
  display:flex + flex-direction:column; layout получает flex:1 — единственный
  надёжный способ пробросить definite height через несколько вложенных
  grid-контейнеров в Chrome
- Обернуть условные notice/applyError в постоянный div.tgu-editor-notices,
  чтобы .tgu-editor-layout всегда был третьим flex-ребёнком (раньше при
  отсутствии уведомлений попадал во вторую auto-строку grid и схлопывался)

Вкладка Редактор — карта:
- Добавить перетаскиваемый разделитель между картой и таймлайном:
  mapRatio state (по умолчанию 50/50), drag-хендлер через document events,
  ограничение 15–80%, визуальный индикатор .tgu-editor-map-resizer
- Ограничить окно наземной трассы 24ч (720 точек, шаг 2 мин) независимо
  от зума таймлайна — при широком диапазоне (7 суток) шаг был 38 мин,
  трасса выглядела как хаотическая сетка через весь глобус

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Дмитрий Соловьев
2026-05-30 16:30:53 +03:00
parent f084775cbb
commit 82eddedc92
6 changed files with 207 additions and 61 deletions
@@ -1,8 +1,11 @@
.tgu-editor-workspace {
display: grid;
grid-template-rows: auto auto minmax(0, 1fr);
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
overflow: hidden;
background: #121516;
}
@@ -95,12 +98,21 @@
color: #ffe7b5;
}
.tgu-editor-notices:empty {
display: none;
}
.tgu-editor-workspace > .tgu-empty {
flex: 1;
}
.tgu-editor-notice {
margin: 0.55rem 0.8rem 0;
}
.tgu-editor-layout {
display: grid;
flex: 1;
min-width: 0;
min-height: 0;
}
@@ -210,7 +222,7 @@
.tgu-editor-center {
display: grid;
grid-template-rows: 42% minmax(0, 1fr);
/* grid-template-rows is set via inline style to support drag-resize */
min-width: 0;
min-height: 0;
border-right: 1px solid var(--line);
@@ -218,14 +230,41 @@
.tgu-editor-map-stage {
position: relative;
min-height: 13rem;
min-height: 6rem;
overflow: hidden;
border-bottom: 1px solid var(--line);
background: #0b0d0e;
}
.tgu-editor-map-stage .tgu-2d-map {
min-height: 13rem;
min-height: 6rem;
}
.tgu-editor-map-resizer {
position: absolute;
bottom: -4px;
left: 0;
right: 0;
height: 8px;
cursor: row-resize;
z-index: 10;
}
.tgu-editor-map-resizer::after {
content: "";
position: absolute;
top: 3px;
left: 50%;
width: 3rem;
height: 2px;
border-radius: 1px;
background: var(--line-soft);
transform: translateX(-50%);
transition: background 0.15s;
}
.tgu-editor-map-resizer:hover::after {
background: var(--accent);
}
.tgu-2d-map.is-picking {