SHA256
Скорректировать main к базе 553a1f1 и UI из Pixel
This commit is contained in:
@@ -45,12 +45,10 @@
|
||||
- **Обычные линии:** SVG `<path> Q` (квадратичные Безье) — тонкие матовые дуги (`stroke-width ~1.0–1.2`),
|
||||
градиент с глубоким уходом в прозрачность: неон-центр `0.42` → цвет роли `0.07` у аватарки (растворяются
|
||||
в фоне, не спорят с сияющими). Изгиб реагирует на скорость.
|
||||
- **Сияющие связи (плазменный композитинг):** один центральный S-путь (cubic Bézier) и три наложенных
|
||||
слоя с одинаковым `d`: `.fg-plasma-flare` (16px, `#00bfff`, blur6), `.fg-plasma-tube` (6px, `#00e5ff`,
|
||||
blur2) и `.fg-plasma-core` (2px, `#dffaff`). Поле и трубка идут в `mix-blend-mode: screen`, поэтому
|
||||
свечение складывается аддитивно с тёмным фоном и ярче проявляется в пересечениях у центра.
|
||||
- **Обычные связи:** теперь это мягкое цветное свечение по типу связи (семья/друзья/бизнес/контакт) —
|
||||
широкая полупрозрачная подложка плюс тонкое ядро, без SVG-blur.
|
||||
- **Сияющие связи (двухслойный «световод», Neon Layering):** два пути на одну связь — широкий размытый
|
||||
GLOW (`stroke-width 4`, неон, `filter: blur(2px)`, `opacity 0.4`) + тонкий чёткий CORE (`1.5px`,
|
||||
`#e0f7fc`). Линия остаётся изящной, но обретает объёмное OLED-свечение; растут оба синхронно (общий
|
||||
dashoffset). Никаких бегущих импульсов.
|
||||
- **Жесты:** свайп-pan с инерцией (новое касание прерывает); короткий тап — центрирование + нижний
|
||||
сниппет; долгий тап — контекстное меню (в `#modal-root`, позиция по `getBoundingClientRect`); тап
|
||||
по центру — профиль. Нажатия на чипы фильтров гасят `pointerdown` (stopPropagation), чтобы сцена не
|
||||
@@ -63,7 +61,7 @@
|
||||
(`hue-rotate`). На компоновщике (GPU), не будит rAF; подписи имён остаются контрастными.
|
||||
- **Стеклянные чипы фильтров (frosted glass):** `background: rgba(255,255,255,0.03)`,
|
||||
`backdrop-filter: blur(12px)`, граница `0.5px solid rgba(255,255,255,0.1)`; активный — подсвечен сине-голубым.
|
||||
- **Поллиш:** «прицел» в центре (+пульс при захвате фокуса); «дыхание» фокуса (бесконечная CSS-анимация
|
||||
- **Поллиш:** «дыхание» фокуса (бесконечная CSS-анимация
|
||||
размера, GPU, не будит rAF); свечение «сияющих» узлов — мягкая медленная пульсация (3.6с) многослойной
|
||||
`box-shadow` + размытый ореол через SVG-фильтр `#fg-shine-glow`; тестовые фото-аватарки (`NETWORK_PHOTOS`);
|
||||
хард-лимит ~90 DOM-аватарок (остальное — SVG-точки).
|
||||
@@ -90,6 +88,94 @@
|
||||
тап по узлам переключает сети.
|
||||
- Реальный путь (`/network-view`) требует живого `wss://shineup.me/ws` (локально — `ws_open_error`, это норма).
|
||||
|
||||
## Режим «Интерактивная паутина» (ветка `pixel-web`, эксперимент, только лаборатория)
|
||||
Включается чипом «🌌 Вселенная». Дальние уровни (2-3) по умолчанию скрыты и раскрываются локально:
|
||||
- **Hover-превью (наведение):** навёл мышь/палец на узел — его ветка временно выплывает; убрал —
|
||||
втягивается. Реализация: `pointerover/out` (мышь) и `pointerdown/up` (палец) → `onNodeHover` →
|
||||
`graph.setHover(node|null)`; узел получает флаг `hovered`.
|
||||
- **Фиксация кликом (pin):** тап/клик по узлу → `graph.toggleExpand` ставит флаг `pinned` — ветка
|
||||
остаётся раскрытой и после ухода курсора. Повторный клик по раскрытому узлу **сворачивает** его
|
||||
(надёжный toggle: `isOpen = pinned || expandP>0.5` → сброс `pinned`+`hovered`).
|
||||
- Эффективное раскрытие = `pinned || hovered` (см. `expandTargetOf`), прогресс `expandP` (~400мс).
|
||||
- **Spotlight-затемнение:** пока есть закреплённая ветка, остальные тускнеют до `SPOTLIGHT_DIM=0.25`
|
||||
(узлы и их линии), фокус и закреплённая/наведённая ветка — 100%. Плавно через `spotCur` (lerp).
|
||||
- **Узлы 2-го уровня — полноценные аватарки:** фото-лицо (pravatar) + имя, `DEEP2_SCALE=0.62`
|
||||
(≈radius 16px), `DEEP2_OPACITY=0.85`. Не «пустые кружки», а видимые друзья друзей.
|
||||
- **Глобальный сброс:** тап по корню (Иван) → `collapseAll()` снимает `pinned`/`hovered` → 100% яркость.
|
||||
- **Адаптивное расталкивание (collision):** раскрытая ветка усиливает отталкивание соседних узлов
|
||||
1-го уровня пропорционально `expandP` (`EXPAND_REPULSION=2.4`) — кластеры разъезжаются, не накладываясь.
|
||||
- **Камера-доводчик:** при фиксации ветки, если её «веер» упирается в край экрана, камера мягко
|
||||
дотягивается (`glideCameraTo` → `camTargetX/Y`, lerp `CAM_GLIDE_K` в tick). Любой жест отменяет доводчик.
|
||||
- **Свободный зум:** колесо мыши (`onWheel`) и щипок двумя пальцами (`activePointers`/`pinching`) —
|
||||
масштаб `zoom` (0.55–2.6), «к точке» под курсором/центром щипка; мир масштабируется CSS-`scale`,
|
||||
линии (отдельный SVG) пересчитываются в экранных координатах (× `zoom`).
|
||||
- **Синхро-пульс линий:** сияющие/трековые «световоды» (`.fg-edge-glow`/`.fg-edge-core`) «дышат»
|
||||
толщиной/размытием 3.6с — в такт ободку сияющего узла (в покое SVG не перерисовывается → синхронно).
|
||||
- Мерцающие микрозвёзды 3-го уровня (`fg-star-twinkle`), хаптика (`navigator.vibrate`) на нажатие/раскрытие/натяжение.
|
||||
|
||||
### Умный фокус (Smart Zoom / «аквариум») — ветка `pixel-aquarium`
|
||||
**Наведение** (hover/палец) на узел — лёгкое превью ветки (раскрытие на месте, без камеры).
|
||||
**Клик/тап по ЛЮБОМУ узлу** — **погружение (dive)** с кинематографичным наездом:
|
||||
- **Камера-полёт + зум** (`diveTo` → `diveTargetId`/`diveZoom=1.7`, лёт в `tick` с `DIVE_FLY_K` ≈600мс):
|
||||
узел плавно центрируется (offset ~0) и **вырастает до единого видимого размера** `HERO_VISUAL=1.4`
|
||||
независимо от уровня (`depthScale = HERO_VISUAL / baseScaleOf`); его прямые дети — до `DIVE_CHILD_VISUAL`.
|
||||
- **Адаптивный радиус орбиты (фикс слипания):** дети раскладываются на кольце
|
||||
`ringR = max(baseR + радиус_родителя, число_детей × 13)` — НЕ лезут на (увеличенный зумом) родитель
|
||||
и друг на друга (проверено: мин. дистанция 125px, 0 наложений). Радиус растёт вместе с зумом родителя.
|
||||
- **Глубина «аквариума»** (`contextTargetOf` → `depthScale`/`depthBlur`/`spotCur`, лерп): Иван и боковые
|
||||
ветки **уменьшаются** (root ×0.55, фон ×0.55) + уходят в **blur 3px** + тускнеют до 0.25 → задний план.
|
||||
- **Железный Spotlight (единый активный путь):** `diveTo` сначала гасит ВСЕ прежние pin/hover, затем
|
||||
раскрывает только путь к новой цели. Открыто → путь Иван→…→узел = 1.0, остальное = 0.25; переключение
|
||||
веток сбрасывает прежнюю; **выход/`exitDive`/тап по Ивану → ВСЕ узлы гарантированно 1.0 + камера отъезжает**.
|
||||
- **Нить-крошка**: путь (`divePathSet`/`onPath`) горит ярким «световодом» — виден путь назад к Ивану.
|
||||
- **Pinch-to-Zoom + LOD**: щипок/колесо меняют `zoom`; при `zoom ≥ LOD_ZOOM (1.55)` видимые точки 3-го
|
||||
уровня **дорисовываются как аватарки** (`updateLod`/`setNodeLod`), при отдалении — обратно в точки.
|
||||
- Глубина — фейк-3D через масштаб + CSS-`blur` (GPU), без WebGL.
|
||||
|
||||
**Полиш (партия 1):** веер детей раскрывается **полукругом «наружу»** (от пути назад, `DEEP_FAN`,
|
||||
по `sibIndex`) — не перекрывает нить-крошку; **LOD с гистерезисом** (`LOD_ZOOM_UP=1.6`/`DOWN=1.4` — без
|
||||
мигания у порога); **двойной тап по фону** и **сильный pinch-out на мин. зуме** = быстрый выход;
|
||||
**префетч аватарок** детей при наведении/нырке.
|
||||
|
||||
**Фишки (партия 2, лаборатория):**
|
||||
- **Поиск + телепорт** — строка `.fg-search`; Enter → `graph.findNode(имя)` → камера летит к узлу (dive в
|
||||
«Вселенной», иначе перецентр).
|
||||
- **Хлебные крошки** — `.fg-breadcrumb` «Иван › Нина › Ада» (движок шлёт `onDiveChange(path)`,
|
||||
API `getDivePath()`); клик по корню — полный сброс, по предку — навигация на тот уровень.
|
||||
- **Бейдж числа связей** — `.fg-node-badge` (число из `degreeById`, обновляется в `updateBadges`).
|
||||
- **Цветовые кластеры** — мягкая аура узла по типу связи (CSS `is-family/friend/business/contact`).
|
||||
|
||||
**Линии-«жгуты» (партия 4, по референсу — плазменный композитинг):**
|
||||
- **Сияющие** — ОДИН центральный S-путь (cubic Bézier) + ТРИ наложенных слоя с ОДИНАКОВЫМ `d` (объём
|
||||
из толщины+размытия, НЕ из геометрии — никаких расходящихся линий):
|
||||
Настоящий НЕОН (видимый ореол вокруг яркого ядра; поле/трубка в `mix-blend-mode: screen` — свет
|
||||
складывается аддитивно с тёмным фоном, а в пересечениях у центра ярче — энергохаб):
|
||||
- `.fg-plasma-flare` — плазменное облако: 16px, `#00bfff`, opacity 0.42, **`feGaussianBlur` stdDev=6**, screen (+ «дыхание» 3.6с);
|
||||
- `.fg-plasma-tube` — направляющий свет: 6px, `#00e5ff`, opacity 0.85, **`feGaussianBlur` stdDev=2**, screen;
|
||||
- `.fg-plasma-core` — ядро: 2px, `#dffaff` (светло-голубо-белое), opacity 1, без размытия.
|
||||
Толщина/насыщенность подогнаны под референс (толстая яркая голубая плазма, гладкие края).
|
||||
S-волна спокойная/изящная (amp до 13px). Размытие — именно SVG-фильтры (`#fg-plasma-blur6/2`), т.к.
|
||||
CSS-`filter` на `<path>` в части мобильных WebView не применяется (отсюда был «плоский»/«канатный» вид).
|
||||
⚠️ Это НЕ Canvas-движок (не библиотека force-graph): связи — реальные SVG `<path>`, фильтры применяются.
|
||||
Прозрачность слоёв inline (× spotlight/глубину). Тяжёлый blur только у сияющих (их мало) — перф.
|
||||
- **Не-сияущие** — мягкое свечение **в цвете связи** (семья/друзья/бизнес/контакт): широкая
|
||||
полупрозрачная подложка + тонкое ядро, без SVG-blur (дёшево). «Похоже, но тише».
|
||||
|
||||
**Фишки (партия 3, лаборатория):**
|
||||
- **Общие связи** — среди друзей человека один помечен как «общий» (он и твой друг тоже): золотой
|
||||
ободок + ★ (CSS `is-common`; в лаб-генерации `addDeepLevels` подставляет узнаваемого друга Ивана).
|
||||
- **Доступность** — визуально скрытый (`sr-only`) текстовый список графа `.fg-a11y` (центр + связи
|
||||
1-го уровня) для скринридеров; обновляется в `updateA11y` при перестроении. Полезно и для реального пути.
|
||||
|
||||
**Автопроверки (`?fgtest`):** `js/pages/network/selftest.js` автозапускается в лаборатории при `?fgtest`,
|
||||
прогоняет 17 ассертов (центровка/collision/полукруг/spotlight/переключение/LOD/поиск/крошки/бейдж/выход) через
|
||||
детерминированные dev-хелперы движка `graph.debugState()` и `graph.pumpForTest()` (синхронно докручивают кадры
|
||||
до покоя — не зависят от троттлинга rAF). Результат → консоль и `window.__fgTestResults`. В обычной работе не активны.
|
||||
|
||||
> ⚠️ Эксперименты на ветках `pixel-web` (паутина) и `pixel-aquarium` (Smart Zoom) — для отката.
|
||||
> Реальный путь `/network-view` не затронут: deep-код под `tier ≥ 2` / `hasDeep`, dive — только tier≥2
|
||||
> (в реальном пути их нет), depthScale/Blur по умолчанию нейтральны, `updateLod` выходит при `!hasDeep`.
|
||||
|
||||
## Ограничения / на будущее
|
||||
- Многоуровневая глубина (друзья друзей мельче, 3-й уровень — точки), кластеры, «общие связи»
|
||||
упираются в API (отдаёт только прямые связи) — требуют доработки сервера.
|
||||
|
||||
Reference in New Issue
Block a user