Snap-соединения: группы панелей — построй мини-дашборд во вкладке одним перетаскиванием
Четыре типа окон (CSS pane, JS pane, JS Console, Output Console) + панели действий + плавающая кнопка — это шесть разных вещей, которые JustZix может рендерить во вкладке. Каждая отдельна, каждая подвижна, у каждой своё постоянное состояние. Без snap-соединений (с v2.13.42) тебе пришлось бы позиционировать каждый элемент вручную после каждого F5 и каждого изменения размера окна. Snap-соединения делают их единой группой.
Что такое snap-соединения?
Snap = «магнитное притяжение». Когда ты перетаскиваешь панель/полосу/кнопку рядом с другой (порог ~20px), JustZix защёлкивает её край к краю с другой, и обе стороны регистрируются как «группа». Последующее перетаскивание любого элемента группы → двигает всю группу как одно целое.
Все 6 типов элементов живут в общем пространстве ID:
| Элемент | Префикс ID | Позиционирование |
|---|---|---|
| Панель действий | ab_* | Абсолютное (x, y) |
| Плавающая кнопка | (фикс.) | Абсолютное (x, y) |
| CSS pane | cp_* | Якорное (x, y, anchor: TL/TR/BL/BR) |
| JS pane | jp_* | Якорное (как выше) |
| JS Console | jc_* | Якорное |
| Output Console | oc_* | Якорное |
Пространство ID единообразно — saveGroupPositions(groupIds) классифицирует каждый ID по префиксу и выбирает подходящее хранилище (chrome.storage.local для панелей действий и panes, chrome.storage.sync для плавающей кнопки).
Якорное позиционирование — почему это важно
Панели действий используют абсолютные координаты: x=200, y=400 от верхнего левого угла. Измени размер окна с 1920px на 1280px, и панель действий может оказаться вне вьюпорта. Panes (CSS/JS/JS Console/Output Console) используют якорное позиционирование:
{ x: 100, y: 50, anchor: 'TR' }
// ^^ Верхний правый угол
// Элемент рендерится как: right: 100px; top: 50px;
4 возможных якоря: TL (сверху слева), TR (сверху справа), BL (снизу слева), BR (снизу справа). После каждого окончания перетаскивания absToAnchorPosition выбирает якорь, дающий самый короткий отступ — элемент защёлкивается к ближайшему углу вьюпорта. Изменение размера окна → элемент остаётся рядом со «своим» углом, не вылетает за экран.
Первый мини-дашборд: 30 секунд
Скажем, ты строишь QA-тулбар для себя. Ты хочешь в правом верхнем углу:
- Панель действий с 3 кнопками («Reset cart» / «Skip cookie» / «Fill demo data»)
- JS pane для «🔥 деструктивного потока»
- Output Console для мониторинга логов
Воркфлоу:
- Загрузи страницу. Панель действий появляется где-то (по умолчанию или последняя позиция).
- Перетащи панель в правый верхний угол, ~20px от краёв. Якорь определяется как
TR. - Перетащи JS pane под панель — в пределах ~20px от нижнего края панели. Snap. Pane + панель = группа.
- Перетащи Output Console под JS pane — ещё один snap. Группа из трёх элементов.
- F5 → всё рендерится вместе, в том же layout; snap-соединения держатся. Якорь TR → layout остаётся приклеенным к правому верхнему углу даже после изменения размера окна.
Это твой личный QA-тулбар. Работает только для домена, scope которого совпадает. Другие сайты — другой тулбар (или никакого).
Что именно делает определение snap
Алгоритм по окончании перетаскивания (упрощённо):
// 1. Получить bounds перетаскиваемого элемента (left, top, w, h)
// 2. Для каждого другого перетаскиваемого элемента в DOM (.jz-pane-*, .jz-actions-bar, #justzix-floating-btn):
// a. Получить bounds другого
// b. Вычислить расстояние: минимум из (top-bottom, bottom-top, left-right, right-left)
// c. Если расстояние < 20px → snap (выровнять перетаскиваемый элемент край к краю с другим)
// 3. После snap сохранить все позиции группы (хелпер saveGroupPositions(groupIds))
// 4. Принадлежность к группе = всё, что имеет начальную позицию рядом с перетаскиваемым элементом в начале перетаскивания
Порог 20px намеренный — достаточно «широкий», чтобы snap случался без точного прицеливания, но не настолько большой, чтобы по ошибке связывать отдельные вещи. На трекпаде / тач-экране ощущается интуитивно.
Перетаскивание со скрытыми panes — фикс v2.13.54
Баг, о котором сообщил пользователь после v2.13.53: плавающая кнопка, перетащенная в группу со скрытым CSS pane → панель корректно следует за плавающей кнопкой, но CSS pane (тоже скрытый) остаётся на старом месте.
Корневая причина: у скрытых panes нет DOM-элемента, но они всё равно в группе. v2.13.53 пропускала их в хелпере «получить начальную позицию». Фикс (v2.13.54): новый cssPanesCache (синхронный доступ к позиции+размеру каждого pane, заполняемый вместе с другими данными) + хелпер paneAnchorToAbs(pane), вычисляющий абсолютные bounds из якоря + вьюпорта без необходимости в DOM. Теперь скрытый pane — полноправный член группы, даже когда он не виден.
Сценарий 1 — «нижний док» в мобильном стиле
Приклей к нижнему краю (якорь BL) широкую панель действий с 8 кнопками + 2 SLIDER. Сложи JS Console + Output Console как 2 pane над панелью — перетащи каждую под другую, snap. После перезагрузки у тебя «нижний док» как на мобильном. Измени размер окна с 1920 до 1280 → вся группа остаётся рядом с нижним краем (якорь BL держит).
Сценарий 2 — мини-IDE в углу
CSS pane + JS pane + Output Console защёлкнуты вертикально сверху справа. CSS pane вверху, правишь вживую → видишь эффект. JS pane ниже, клик ▶ → запускаешь кастомный скрипт. Output Console внизу, мониторишь console.log страницы и свой JUSTZIX.log. Три «окна» в одном вертикальном потоке — это буквально мини-IDE.
Сценарий 3 — плавающая кнопка как якорь для группы
Плавающая кнопка обычно — меню-лаунчер снизу справа (BR). Приклей к ней панель действий + Output Console — перетащи их к плавающей кнопке → snap. Теперь все 3 сгруппированы. Перетащи плавающую кнопку куда угодно → панель + Output Console следуют за ней. Плавающая кнопка становится «якорной ручкой» для всей группы.
Ловушки
- Snap не пересекает сайты / домены. У каждого домена свой layout. Snap-группы сохраняются в chrome.storage.local по элементам, но рендерятся только когда scope совпадает с текущим доменом. Переход с shop.com → google.com = другой layout (если вообще виден).
- Минимальная визуальная обратная связь при snap. Элемент плавно «защёлкивается» к краю после отпускания мыши — нет оверлея «индикатора snap» как в Figma. Может запутать первые 2-3 раза.
- У группы нет явного UX «покинуть группу». Чтобы отсоединить, перетащи элемент на >20px от группы. Нужно явно отвести его; небольшие корректировки позиции не ломают snap.
- Изменение размера окна запускает пересчёт якоря. После большого изменения вьюпорта (например, полный экран F11) якорь может выбрать другой угол. Лучшая практика: располагай вещи в своём обычном размере рабочего пространства, не в F11.
- 4 типа panes = 4 индивидуальных префикса ID. Snap делается по ID, не по типу. У тебя может быть 3 JS pane, все защёлкнутые к одному CSS pane — никаких проблем.
Что делать дальше
Snap-соединения превращают JustZix из «нескольких отдельных инструментов» в «настраиваемый дашборд». Это последний кусок пазла для мини-IDE во вкладке: CSS pane + JS Console + JS pane + Output Console + действия (TOGGLE3, SLIDER) — расположенные как ты хочешь, одним перетаскиванием.
Установи JustZix и построй свой первый мини-дашборд — 30 секунд, ноль конфигурационного кода.
Оцени эту статью
Оценок пока нет — оцени первым.