FullscreenControl

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

Основная задача FullscreenControl заключается в изменении размера контейнера карты до размеров экрана устройства с последующей синхронизацией состояния карты, чтобы визуализация тайлов, слоёв и взаимодействий оставалась корректной при изменении viewport.


Архитектура и принцип работы

FullscreenControl реализуется как объект, соответствующий интерфейсу IControl, используемому в Mapbox GL JS. При добавлении на карту он:

  • создаёт DOM-элемент кнопки
  • отслеживает состояние fullscreen через document.fullscreenElement
  • вызывает методы requestFullscreen() и exitFullscreen()
  • обновляет визуальное состояние кнопки

Контрол не управляет рендерингом карты напрямую. Он лишь изменяет контейнер, после чего карта автоматически реагирует на изменение размеров через внутренние механизмы resize().


Инициализация и подключение

FullscreenControl добавляется через метод addControl экземпляра карты.

import mapboxgl from 'mapbox-gl';

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  center: [30.5, 50.5],
  zoom: 9
});

map.addControl(new mapboxgl.FullscreenControl());

По умолчанию контрол размещается в правом верхнем углу интерфейса карты.


Конфигурация параметров

FullscreenControl принимает объект настроек, позволяющий адаптировать поведение под требования интерфейса.

Контейнер fullscreen

map.addControl(new mapboxgl.FullscreenControl({
  container: document.querySelector('#map-wrapper')
}));

Параметр container определяет элемент DOM, который будет переводиться в полноэкранный режим. Если не указан, используется контейнер карты.


Поведение в различных браузерах

FullscreenControl опирается на Fullscreen API, поведение которого отличается в зависимости от реализации браузера:

  • Chrome и Edge: полная поддержка requestFullscreen
  • Firefox: поддержка с префиксами в старых версиях
  • Safari: ограниченная поддержка, особенно на iOS

В контексте Mapbox GL JS контроль состояния fullscreen может сопровождаться дополнительными событиями перерасчёта размера карты.


Внутренние события и синхронизация

При переходе в полноэкранный режим карта обязана пересчитать свой viewport. FullscreenControl косвенно инициирует этот процесс.

Ключевые моменты:

  • изменение fullscreenchange отслеживается через document
  • после изменения состояния вызывается map.resize()
  • перерасчёт тайлов происходит автоматически
document.addEventListener('fullscreenchange', () => {
  map.resize();
});

Хотя библиотека часто обрабатывает это самостоятельно, ручной вызов используется при кастомных интеграциях.


Позиционирование на карте

FullscreenControl реализует стандартную систему позиционирования контролов:

  • top-right (по умолчанию)
  • top-left
  • bottom-right
  • bottom-left
map.addControl(new mapboxgl.FullscreenControl(), 'bottom-left');

Позиция влияет только на DOM-размещение кнопки и не изменяет функциональность.


Состояния и UI-индикация

Контрол автоматически переключает иконку в зависимости от состояния:

  • режим обычного отображения → иконка “войти в fullscreen”
  • режим fullscreen → иконка “выйти из fullscreen”

Состояние определяется через:

document.fullscreenElement

Изменение UI происходит без перерисовки карты, только через DOM-манипуляции.


Работа с контейнерами и вложенными структурами

При использовании кастомных layout-структур важно учитывать, что fullscreen применяется к конкретному DOM-элементу.

Типичные сценарии:

  • карта внутри flex-контейнера
  • карта внутри modal-окна
  • карта внутри tab-компонента

FullscreenControl не изменяет CSS окружения, а лишь переводит указанный контейнер в fullscreen.

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

  • position: fixed применяется браузером автоматически
  • z-index может игнорироваться
  • overflow контейнеров перестаёт действовать

Интеграция с другими контролами

FullscreenControl может использоваться совместно с другими стандартными контролами Mapbox GL JS:

  • ZoomControl
  • NavigationControl
  • ScaleControl

Порядок добавления влияет только на визуальную последовательность в UI:

map.addControl(new mapboxgl.NavigationControl());
map.addControl(new mapboxgl.FullscreenControl());
map.addControl(new mapboxgl.ScaleControl());

Кастомизация поведения

FullscreenControl можно заменить пользовательской реализацией, если требуется расширенное управление состоянием.

Пример логики кастомного поведения:

class CustomFullscreen {
  onAdd(map) {
    this.map = map;
    this.container = document.createElement('button');

    this.container.oncl ick = () => {
      if (!document.fullscreenElement) {
        map.getContainer().requestFullscreen();
      } else {
        document.exitFullscreen();
      }
    };

    return this.container;
  }

  onRemove() {
    this.container.remove();
  }
}

Такой подход используется при необходимости интеграции с нестандартными UI-фреймворками.


Производительность и особенности рендеринга

FullscreenControl сам по себе не влияет на производительность, однако переход в fullscreen вызывает:

  • перерасчёт viewport
  • повторную компоновку WebGL контекста
  • обновление тайлового буфера

В Mapbox GL JS это сопровождается автоматическим вызовом resize, что предотвращает визуальные артефакты.


Ограничения и типичные проблемы

  • iOS Safari не поддерживает полноценный fullscreen для произвольных элементов
  • некоторые браузеры требуют пользовательского жеста для активации
  • при наличии iframe fullscreen может быть ограничен политиками sandbox
  • в модальных окнах fullscreen может конфликтовать с overlay-логикой

FullscreenControl не обходит эти ограничения, а лишь использует доступный API браузера.


Поведение при динамическом изменении DOM

Если контейнер карты удаляется или заменяется в DOM во время fullscreen-сессии:

  • fullscreen режим автоматически завершается
  • состояние контроллера сбрасывается
  • карта требует повторной инициализации при повторном добавлении

Это важно при использовании SPA-фреймворков, где DOM может пересоздаваться без перезагрузки страницы.