Адаптивный дизайн

Визуализация в CesiumJS строится вокруг HTML-контейнера, в который встраивается WebGL-канвас. Базовый принцип адаптивности заключается в синхронизации размеров рендера с размерами DOM-элемента, а также в корректной обработке изменений viewport при изменении окна, ориентации устройства и масштабирования интерфейса.

Ключевой элемент — объект Viewer, который автоматически создает сцену, камеру, канвас и набор стандартных UI-компонентов. Однако автоматическая адаптация ограничена контекстом браузера и требует контроля со стороны приложения при сложных интерфейсных сценариях.

Основные факторы, влияющие на адаптивность:

  • изменение размеров окна браузера;
  • динамическое изменение layout (sidebar, панели инструментов);
  • мобильная ориентация (portrait/landscape);
  • изменение devicePixelRatio;
  • встраивание в flex/grid контейнеры;
  • режимы split-view и multi-view.

Синхронизация размеров Viewer и DOM-контейнера

Рендер-канвас Cesium жестко связан с размером родительского элемента. При изменении размеров контейнера требуется обновление сцены.

Базовая механика:

  • viewer.resize() — пересчитывает размер канваса;
  • viewer.scene.requestRender() — инициирует перерисовку в режиме demand rendering;
  • viewer.scene.canvas — прямой доступ к DOM canvas.

Ключевой момент — Cesium не всегда автоматически отслеживает изменение размеров при сложных layout-сценариях (например, когда контейнер изменяется через CSS transition или flex-раскладку).


Использование ResizeObserver

Современный подход к адаптивности основан на ResizeObserver, который отслеживает изменения геометрии контейнера без опроса окна.

Типовой сценарий:

  • наблюдение за контейнером viewer;
  • при изменении размеров — вызов resize();
  • последующая перерисовка сцены.

Особенность Cesium заключается в том, что изменение размеров canvas должно сопровождаться обновлением сцены, иначе возможны артефакты растяжения или неправильное соотношение сторон.


Обработка window resize и debounce-стратегия

Событие window.resize остается критическим, но требует фильтрации частоты вызовов.

Причины:

  • браузеры генерируют серию событий при изменении размера;
  • перерасчет сцены WebGL является затратной операцией;
  • частые вызовы приводят к падению FPS.

Применяется стратегия:

  • debounce (задержка выполнения);
  • requestAnimationFrame как синхронизатор;
  • объединение resize + layout recalculation в один цикл.

Device Pixel Ratio и четкость изображения

Высокоплотные дисплеи требуют корректного учета window.devicePixelRatio.

CesiumJS автоматически учитывает DPI, но при кастомных контейнерах и ограничении производительности возможна ручная настройка:

  • уменьшение pixel ratio для мобильных устройств;
  • фиксирование значения для стабилизации FPS;
  • динамическое изменение качества в зависимости от нагрузки.

Параметр viewer.resolutionScale влияет на внутреннее разрешение рендера, позволяя отделить физический размер canvas от вычислительной нагрузки.


Адаптация камеры под изменение аспектного соотношения

Изменение размеров контейнера напрямую влияет на aspect ratio камеры. Cesium использует перспективную камеру, где пересчет фрустума происходит автоматически при resize, однако в нестандартных сценариях требуется контроль:

  • фиксированные камеры (например, для 3D-аналитики);
  • синхронизация нескольких viewer;
  • overlay-интерфейсы с независимым масштабированием.

Камера должна сохранять визуальную стабильность сцены при изменении ширины боковых панелей или появления UI-оверлеев.


CSS-архитектура контейнера

Правильная адаптивность невозможна без корректной CSS-структуры.

Критические требования:

  • контейнер Cesium должен иметь position: relative или absolute;
  • обязательное растяжение width: 100%; height: 100%;
  • отсутствие конфликтующих overflow у родительских элементов;
  • контроль flex-grow/shrink в flex-layout.

Частая проблема — нулевые высоты контейнера при вложенных flex-схемах, из-за чего WebGL canvas получает некорректные размеры.


Работа в flex и grid layout

Cesium часто встраивается в сложные интерфейсы с панелями инструментов, деревьями слоев и инспекторами объектов.

В таких случаях:

  • изменение ширины sidebar должно триггерить resize сцены;
  • grid-template-columns влияет на пересчет viewport;
  • transition-анимации требуют отложенного resize после завершения анимации.

При непрерывных изменениях layout возможны промежуточные состояния с искажением геометрии сцены, что устраняется синхронизацией через requestAnimationFrame.


Адаптация под мобильные устройства

Мобильные браузеры вводят дополнительные ограничения:

  • нестабильный viewport при появлении адресной строки;
  • резкие изменения высоты окна при прокрутке;
  • ограниченный GPU;
  • touch-first взаимодействие.

Для стабильной работы:

  • фиксируется управление камерой под touch events;
  • снижается resolutionScale;
  • уменьшается количество тайлов в кадре;
  • ограничивается максимальная сложность 3D Tiles.

Cesium использует WebGL напрямую, поэтому перегрузка GPU на мобильных устройствах приводит к деградации FPS без явных ошибок.


Управление качеством рендеринга при изменении размеров

Адаптивность включает не только геометрию, но и производительность.

Основные параметры:

  • scene.globe.maximumScreenSpaceError — баланс детализации террейна;
  • tileset.maximumScreenSpaceError — детализация 3D Tiles;
  • scene.requestRenderMode — режим рендера по запросу;
  • scene.maximumRenderTimeChange — контроль частоты обновлений.

При уменьшении окна возможно повышение детализации, при увеличении — снижение нагрузки.


Контекст WebGL и его восстановление

При изменении размеров окна и переключении вкладок возможна потеря WebGL контекста.

Поведение системы:

  • canvas уничтожается на уровне GPU;
  • сцена требует пересоздания ресурсов;
  • текстуры и буферы перезагружаются.

Адаптивная архитектура должна учитывать:

  • восстановление состояния Viewer;
  • повторную загрузку imagery layers;
  • сохранение позиции камеры.

Fullscreen и динамическое масштабирование

Режим полноэкранного отображения изменяет геометрию контейнера без изменения логической структуры DOM.

Особенности:

  • событие fullscreenchange требует повторного resize;
  • aspect ratio может резко измениться;
  • возможны скачки уровня детализации.

CesiumJS в fullscreen-режиме полностью пересчитывает сцену, но внешние UI-слои должны синхронизироваться отдельно.


Многооконные и split-view конфигурации

При создании нескольких независимых сцен на одной странице возникают дополнительные требования к адаптивности:

  • изоляция WebGL контекстов;
  • независимые resize-обработчики;
  • контроль общей GPU-нагрузки;
  • синхронизация камер при сравнительном анализе.

Split-view требует строгого контроля размеров каждого контейнера, так как изменение одного блока влияет на перераспределение ресурсов браузера.


Интеграция с SPA-фреймворками

В архитектурах React, Vue и аналогичных системах адаптивность зависит от жизненного цикла компонентов:

  • инициализация Viewer после mount DOM;
  • пересоздание или обновление при изменении props layout;
  • очистка WebGL контекста при unmount.

Критическим моментом становится предотвращение многократной инициализации сцены при повторных рендерах виртуального DOM.


Управление слоями интерфейса поверх сцены

Адаптивный дизайн включает не только сам canvas, но и HTML-оверлеи:

  • тулбары;
  • popover-информацию;
  • canvas-based labels;
  • HUD-интерфейсы.

Overlay должен масштабироваться синхронно с картой, иначе возникает расхождение координат экран/мир.

Особое значение имеет привязка экранных координат через scene.cartesianToCanvasCoordinates.


Производительные стратегии при частых изменениях размера

При интенсивной динамике интерфейса используются следующие подходы:

  • временное отключение рендера (scene.requestRenderMode);
  • батчинг resize-событий;
  • отложенная синхронизация камеры;
  • снижение resolutionScale в момент трансформации layout;
  • восстановление качества после стабилизации размеров.

Такая схема предотвращает деградацию FPS при drag-resize панелей и анимациях интерфейса.


Ограничения и поведение при нестабильных размерах

Некоторые сценарии приводят к нестабильному поведению сцены:

  • контейнер с нулевой высотой;
  • постоянные изменения размеров в течение одного кадра;
  • пересечение CSS transform и WebGL canvas;
  • некорректные значения aspect ratio.

В этих условиях Cesium может временно отображать искаженные проекции или «растянутую» географию до следующего корректного resize-цикла.