FullScreen

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

Контрол FullScreen и его назначение

FullScreen относится к стандартным контролам библиотеки и находится в модуле ol/control/FullScreen. Его задача — переключать отображение контейнера карты между обычным и полноэкранным режимом.

Ключевая особенность реализации заключается в том, что контрол не управляет самой картой напрямую, а работает с DOM-элементом, который передаётся или определяется автоматически как контейнер карты.

Основные функции:

  • переход в полноэкранный режим для контейнера карты
  • выход из полноэкранного режима
  • отслеживание текущего состояния
  • синхронизация состояния кнопки с API браузера

Подключение и базовая инициализация

Контрол добавляется в карту через массив controls при создании экземпляра ol/Map.

import Map from 'ol/Map';
import View from 'ol/View';
import FullScreen from 'ol/control/FullScreen';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';

const map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM()
    })
  ],
  view: new View({
    center: [0, 0],
    zoom: 2
  }),
  controls: [
    new FullScreen()
  ]
});

В этом случае OpenLayers автоматически применяет полноэкранный режим к контейнеру карты, указанному в target.

Поведение в браузере и Fullscreen API

Контрол опирается на стандартный Fullscreen API:

  • Element.requestFullscreen()
  • document.exitFullscreen()
  • document.fullscreenElement

OpenLayers абстрагирует различия между браузерами и использует совместимые префиксы там, где это необходимо (в старых окружениях).

При активации режима происходит:

  • запрос полноэкранного режима для DOM-элемента
  • обновление состояния контрола
  • изменение CSS-классов состояния

При выходе:

  • вызов exitFullscreen
  • синхронизация состояния кнопки
  • возврат интерфейса к исходному виду

Параметры конфигурации FullScreen

Контрол поддерживает набор опций, позволяющих адаптировать поведение и внешний вид.

className

Определяет CSS-класс для кнопки.

new FullScreen({
  className: 'ol-full-screen-custom'
})

Позволяет переопределять стили кнопки через CSS.

label и labelActive

Используются для отображения символов на кнопке.

  • label — иконка или текст в обычном состоянии
  • labelActive — отображение в активном полноэкранном режиме

Пример:

new FullScreen({
  label: '⛶',
  labelActive: '⛶'
})

В реальных проектах чаще заменяются на иконки через CSS.

tipLabel

Подсказка при наведении:

new FullScreen({
  tipLabel: 'Полноэкранный режим'
})

Используется для доступности и улучшения UX.

source (цель полноэкранного режима)

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

new FullScreen({
  source: document.getElementById('map-container')
})

Это важно, когда карта находится внутри сложной верстки и требуется разворачивать не сам target, а внешний контейнер.

Встраивание в сложную DOM-структуру

В реальных интерфейсах карта часто находится внутри вложенных контейнеров:

<div class="layout">
  <header></header>
  <div class="content">
    <div id="map-wrapper">
      <div id="map"></div>
    </div>
  </div>
</div>

В таких случаях fullscreen-контейнером должен выступать map-wrapper, иначе при переходе в полноэкранный режим могут обрезаться элементы интерфейса или ломаться стили.

new FullScreen({
  source: document.getElementById('map-wrapper')
})

Состояние и события

Контрол является наследником базового Control и поддерживает стандартные события OpenLayers.

change:active

Основное событие, отражающее изменение состояния:

const fullScreen = new FullScreen();

fullScreen.on('change:active', function (event) {
  console.log(event.target.getActive());
});

Событие срабатывает при переключении режима.

синхронизация с fullscreenchange

Браузер также генерирует событие:

  • fullscreenchange

OpenLayers использует его для синхронизации состояния контрола с фактическим состоянием DOM.

document.addEventListener('fullscreenchange', () => {
  console.log(document.fullscreenElement);
});

Это важно в ситуациях, когда fullscreen был изменён не через контрол, а программно или через системные действия.

Программное управление режимом

Хотя контрол предназначен для пользовательского взаимодействия, состояние можно изменять программно через DOM API.

const element = document.getElementById('map');

if (!document.fullscreenElement) {
  element.requestFullscreen();
} else {
  document.exitFullscreen();
}

OpenLayers автоматически синхронизирует свой контрол при изменении состояния.

Особенности стилизации

Контрол FullScreen использует стандартные CSS-классы OpenLayers:

  • .ol-full-screen
  • .ol-control
  • .ol-control button

Пример переопределения внешнего вида:

.ol-full-screen {
  top: 4em;
  left: .5em;
}

.ol-full-screen button {
  background-color: #1f1f1f;
  color: #ffffff;
  border-radius: 4px;
}

При активном состоянии браузеры часто добавляют псевдоклассы и системные стили, поэтому важно учитывать:

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

Ограничения и особенности браузеров

Полноэкранный режим имеет ряд ограничений, накладываемых браузерами:

  • активация возможна только по пользовательскому действию (click, keydown)
  • некоторые мобильные браузеры ограничивают API
  • Safari может требовать vendor-prefixed реализацию
  • вложенный fullscreen (iframe) может быть запрещён политиками безопасности

Также важно учитывать, что:

  • в fullscreen режиме элементы outside target могут исчезать
  • события resize карты могут не всегда срабатывать автоматически

OpenLayers обычно вызывает перерасчёт размера карты при входе/выходе из fullscreen, но в сложных интерфейсах может потребоваться ручной вызов:

map.updateSize();

Использование в связке с другими контролами

FullScreen часто используется вместе с:

  • Zoom
  • Rotate
  • ScaleLine
  • OverviewMap

Проблема заключается в перекрытии элементов интерфейса при переходе в fullscreen.

Рекомендуется группировать контролы в единый контейнер:

import {defaults as defaultControls} from 'ol/control';

const map = new Map({
  controls: defaultControls().extend([
    new FullScreen()
  ])
});

И управлять их позиционированием через CSS.

Поведение внутри SPA и фреймворков

В приложениях на React, Vue или Angular fullscreen-контрол требует аккуратного обращения с жизненным циклом DOM.

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

  • элемент source должен существовать в DOM к моменту инициализации
  • при размонтировании компонента fullscreen должен быть принудительно закрыт
  • повторная инициализация карты без выхода из fullscreen может привести к неконсистентному состоянию

Пример принудительного выхода:

if (document.fullscreenElement) {
  document.exitFullscreen();
}

Влияние на рендеринг карты

При переходе в полноэкранный режим происходит изменение размеров контейнера, что влияет на:

  • тайловую загрузку
  • пересчёт viewport
  • центрирование карты
  • уровни детализации (LOD)

OpenLayers автоматически реагирует на изменение размера, но в нестандартных сценариях (анимированные контейнеры, CSS transitions) может возникнуть рассинхронизация, требующая ручного обновления состояния карты.

setTimeout(() => {
  map.updateSize();
}, 300);

Типичные ошибки интеграции

Одной из распространённых проблем является использование fullscreen на неправильном DOM-уровне. Например, если fullscreen применяется к внутреннему div, а не к контейнеру карты, интерфейс может обрезаться.

Другие ошибки:

  • отсутствие пользовательского события при вызове fullscreen
  • попытка программного входа без user gesture
  • конфликт z-index с модальными окнами
  • неучтённый resize карты

Правильная архитектура DOM для карты с fullscreen обычно предполагает выделенный контейнер верхнего уровня, управляемый через source.