---
metadata:
  - name: generator
    content: Diplodoc Platform v5.39.1
alternate:
  - https://yandex.com/dev/jsapi-v2-1/doc/en/v2-1/examples/cases/panorama_in_balloon.md
  - https://yandex.com/dev/jsapi-v2-1/doc/ru/v2-1/examples/cases/panorama_in_balloon.md
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.com/dev/jsapi-v2-1/doc/ru/llms.txt

# Отображение панорамы в балуне

<iframe id="LIVE-EXAMPLE" style="width:100%;height: 400px;border-radius: 8px;border: 1px solid rgba(92, 94, 102, 0.14);" frameBorder="0" src="https://yastatic.net/s3/front-maps-static/maps-front-jsapi-v2-1/examples/2/out/s3-cases/ru/panorama_in_balloon/index.html" allow="fullscreen"></iframe>

<a target="_blank" rel="noopener noreferrer" style="display: inline-block;margin-top: 10px;cursor: pointer;border-radius: 4px;padding: 9px 12px;background: #151515;color: white;text-decoration: none;font-weight: 500" href="https://codesandbox.io/p/sandbox/z4c3g8?file=index.html">Open in CodeSandbox</a>

<div id="references">
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/panorama.isSupported">panorama.isSupported</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/panorama.locate">panorama.locate</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/panorama.Player">panorama.Player</a>,
    <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/templateLayoutFactory">templateLayoutFactory</a>
</div>
<p>
    Данный пример демонстрирует, как отобразить панораму в балуне.
</p>
<p>
    В примере при открытии балуна метки выполняется проверка
    на наличие панорамы в текущей точке. Если панорама найдена, с помощью фабрики <a href="https://yandex.ru/dev/jsapi-v2-1/doc/ru/v2-1/ref/reference/templateLayoutFactory">templateLayoutFactory</a>
    создается макет балуна с этой панорамой. Если панорамы в точке не нашлось, то для балуна задается
    простое текстовое содержимое.
</p>

{% list tabs %}

-   index.html

    ```html
    <!DOCTYPE html>
    <html lang="ru">
        <head>
            <title>Отображение панорамы в балуне</title>
            <meta charset="utf-8" />

            
            <!--
            Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
            Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
        -->
            
            
        </head>
        <body>
            <div id="map" class="map"></div>
        </body>
    </html>
    ```

-   panorama_in_balloon.js

    ```js
    ymaps.ready(function () {
        // Для начала проверим, поддерживает ли плеер браузер пользователя.
        if (!ymaps.panorama.isSupported()) {
            // Если нет, то просто ничего не будем делать.
            return;
        }

        var myMap = new ymaps.Map("map", {
                center: [59.938557, 30.316198],
                zoom: 10,
                controls: [],
            }),
            // При клике на метке будет открываться балун,
            // содержащий Яндекс.Панораму в текущей географической точке.
            myPlacemark1 = new ymaps.Placemark(
                [59.938557, 30.316198],
                {
                    // Для данной метки нужно будет открыть воздушную панораму.
                    panoLayer: "yandex#airPanorama",
                },
                {
                    preset: "islands#redIcon",
                    openEmptyBalloon: true,
                    balloonPanelMaxMapArea: 0,
                }
            ),
            myPlacemark2 = new ymaps.Placemark(
                [59.900557, 30.44319],
                {
                    // Для этой метки будем запрашивать наземную панораму.
                    panoLayer: "yandex#panorama",
                },
                {
                    preset: "islands#nightIcon",
                    openEmptyBalloon: true,
                    balloonPanelMaxMapArea: 0,
                }
            );

        // Функция, устанавливающая для метки макет содержимого ее балуна.
        function setBalloonContentLayout(placemark, panorama) {
            // Создание макета содержимого балуна.
            var BalloonContentLayout = ymaps.templateLayoutFactory.createClass(
                '<div id="panorama" style="width:256px;height:156px"/>',
                {
                    // Переопределяем функцию build, чтобы при формировании макета
                    // создавать в нем плеер панорам.
                    build: function () {
                        // Сначала вызываем метод build родительского класса.
                        BalloonContentLayout.superclass.build.call(this);
                        // Добавляем плеер панорам в содержимое балуна.
                        this._openPanorama();
                    },
                    // Аналогично переопределяем функцию clear, чтобы удалять
                    // плеер панорам при удалении макета с карты.
                    clear: function () {
                        this._destroyPanoramaPlayer();
                        BalloonContentLayout.superclass.clear.call(this);
                    },
                    // Добавление плеера панорам.
                    _openPanorama: function () {
                        if (!this._panoramaPlayer) {
                            // Получаем контейнер, в котором будет размещаться наша панорама.
                            var el =
                                this.getParentElement().querySelector(
                                    "#panorama"
                                );
                            this._panoramaPlayer = new ymaps.panorama.Player(
                                el,
                                panorama,
                                {
                                    controls: ["panoramaName"],
                                }
                            );
                        }
                    },
                    // Удаление плеера панорамы.
                    _destroyPanoramaPlayer: function () {
                        if (this._panoramaPlayer) {
                            this._panoramaPlayer.destroy();
                            this._panoramaPlayer = null;
                        }
                    },
                }
            );
            // Устанавливаем созданный макет в опции метки.
            placemark.options.set("balloonContentLayout", BalloonContentLayout);
        }

        // В этой функции выполняем проверку на наличие панорамы в данной точке.
        // Если панорама нашлась, то устанавливаем для балуна макет с этой панорамой,
        // в противном случае задаем для балуна простое текстовое содержимое.
        function requestForPanorama(e) {
            var placemark = e.get("target"),
                // Координаты точки, для которой будем запрашивать панораму.
                coords = placemark.geometry.getCoordinates(),
                // Тип панорамы (воздушная или наземная).
                panoLayer = placemark.properties.get("panoLayer");

            placemark.properties.set(
                "balloonContent",
                "Идет проверка на наличие панорамы..."
            );

            // Запрашиваем объект панорамы.
            ymaps.panorama
                .locate(coords, {
                    layer: panoLayer,
                })
                .then(
                    function (panoramas) {
                        if (panoramas.length) {
                            // Устанавливаем для балуна макет, содержащий найденную панораму.
                            setBalloonContentLayout(placemark, panoramas[0]);
                        } else {
                            // Если панорам не нашлось, задаем
                            // в содержимом балуна простой текст.
                            placemark.properties.set(
                                "balloonContent",
                                "Для данной точки панорамы нет."
                            );
                        }
                    },
                    function (err) {
                        placemark.properties.set(
                            "balloonContent",
                            "При попытке открыть панораму произошла ошибка: " +
                                err.toString()
                        );
                    }
                );
        }

        // Слушаем на метках событие 'balloonopen': как только балун будет впервые открыт,
        // выполняем проверку на наличие панорамы в данной точке и в случае успеха создаем
        // макет с найденной панорамой.
        // Событие открытия балуна будем слушать только один раз.
        myPlacemark1.events.once("balloonopen", requestForPanorama);
        myPlacemark2.events.once("balloonopen", requestForPanorama);

        myMap.geoObjects.add(myPlacemark1);
        myMap.geoObjects.add(myPlacemark2);

        // Если для меток будет включена опция 'draggable', то чтобы при перетаскивании
        // метки в балуне отображалась панорама для новой точки, раскомментируйте код ниже:

        /*
         function onDragEnd (e) {
             var placemark = e.get('target');
             // Как только пользователь передвинул метку в другую точку,
             // удаляем заданный ранее макет балуна.
             placemark.options.unset('balloonContentLayout');
             // Также удалим текстовое содержимое балуна.
             placemark.properties.unset('balloonContent');
    
             // Снова подписываемся на событие открытия балуна.
             // Это событие будем слушать только один раз.
             placemark.events.once('balloonopen', requestForPanorama);
         }
    
         // Слушаем на метках событие 'dragend'. При наступлении этого события
         // будем удалять макет балуна со старой панорамой, после чего выполнять
         // проверку на наличие панорамы в новой точке.
         myPlacemark1.events.add('dragend', onDragEnd);
         myPlacemark2.events.add('dragend', onDragEnd);
         */
    });
    ```

{% endlist %}
