@aliver13

Как запустить функцию при клике на маркер Yandex Map v3 с использованием кластеризации?

Подскажите пожалуйста.
Ситуация: есть карта с точками. Есть функция showInfo, которая двигает "прицел" карты, меняет Zoom, и информацию по активному поинту в инфо-блок.

Я хочу, чтобы при клике на определенный point запускалась эта функция.
Ума не приложу, куда эту функцию пихать, так как не понимаю (и уже не хочу понимать), как работает yandex map api.

У меня надежда только на доброго человека, потому что я так запарился, что уже мозг отключается

initMap();

async function initMap() {
    // Промис `ymaps3.ready` будет зарезолвлен, когда загрузятся все компоненты основного модуля API
    await ymaps3.ready;

    const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapMarker, YMapControls, YMapLayer, YMapFeatureDataSource} = ymaps3;

    const {YMapZoomControl} = await ymaps3.import('@yandex/ymaps3-controls@0.0.1');

    // Добавляем кластеризатор
    const {YMapClusterer, clusterByGrid} = await ymaps3.import('@yandex/ymaps3-clusterer@0.0.1');

    // Иницилизируем карту
    const map = new YMap(
        // Передаём ссылку на HTMLElement контейнера
        document.getElementById('map'),

        // Передаём параметры инициализации карты
        {
            location: {
                // Координаты центра карты
                center: [37.588144, 55.733842],

                // Уровень масштабирования
                zoom: 10
            }
        }
    );

    // Добавляем слой для отображения схематической карты
    map.addChild(new YMapDefaultSchemeLayer({ customization: mapCustomizationJSON }));

    // Добавляем к карте ресурс
    map.addChild(new YMapFeatureDataSource({id:'my-source'}));
    // Добавляем ресурс на карту
    map.addChild(new YMapLayer({source: 'my-source', type: 'markers', zIndex:1800}));

    // Пин
    const contentPin = document.createElement('div');
    contentPin.innerHTML = '<img style="width:20px;" src="https://www.freepnglogos.com/uploads/pin-png/pin-transparent-png-pictures-icons-and-png-backgrounds-36.png" />';

    // Функция создания маркера (или че это)
    function marker(feature) {
        const yMapMarker = new ymaps3.YMapMarker(
            {
                coordinates: feature.geometry.coordinates,
                source: 'my-source'
            },
            contentPin.cloneNode(true)
        );

        // yMapMarker.events.add('click', () => {
        //     showInfo(feature);
        // });

        return yMapMarker;
    }

    const cluster = (coordinates, features) =>
    new ymaps3.YMapMarker(
        {
            coordinates,
            source: 'my-source'
        },
        circle(features.length).cloneNode(true)
    );

    function circle(count) {
        const circle = document.createElement('div');
        circle.classList.add('circle');
        circle.innerHTML = `
        <div class="circle-content"><span class="circle-text">${count}</span></div>`;
        return circle;
    }

    const points = pointsData.map((point, i) => ({
        type: 'Feature',
        id: i,
        geometry: {coordinates: [point.acf_fields.coordinates.y, point.acf_fields.coordinates.x]},
        properties: {
            name: point.acf_fields.point_name,
            // другие свойства
        }
    }))

    const clusterer = new YMapClusterer({
        method: clusterByGrid({gridSize: 64}),
        features: points,
        marker,
        cluster
    });

    map.addChild(clusterer);

    //   Пытаюсь добавить кнопку Зума
    map.addChild(
        // Using YMapControls you can change the position of the control
        new YMapControls({position: 'right'})
        // Add the zoom control to the map
        .addChild(new YMapZoomControl({}))
    );

    map.addChild(new YMapDefaultFeaturesLayer());

    // Функция отображения информации
    function showInfo(feature) {
        const infoElement = document.getElementById('point-info-container');
        
        // Вставляем в элемент inf-block данные, которые мы получим из переменной point
        document.getElementById('point-info__name').innerText = 'Info';
        document.getElementById('point-info__address').innerText = 'text';
        infoElement.style.display = 'block';

        map.update({
            location: {
                center: feature.geometry.coordinates,
                zoom: 14,
                duration: 1000,
            }
        });
        
    }

}


P.s
Я так понял, это можно сделать через marker(feature). Я пытался это сделать так
function marker(feature) {
        const yMapMarker = new ymaps3.YMapMarker(
            {
                coordinates: feature.geometry.coordinates,
                source: 'my-source'
            },
            contentPin.cloneNode(true)
        );

        yMapMarker.events.add('click', () => {
            showInfo(feature);
        });

        return yMapMarker;
    }


Но получил ошибку.
test:55 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'add')
    at Object.marker (test:55:27)
    at c._getEntity (clusterer.js:1:1093)
    at clusterer.js:1:1228
    at Array.forEach (<anonymous>)
    at c._getVisibleEntities (clusterer.js:1:1202)
    at c._render (clusterer.js:1:1916)
    at c._onAttach (clusterer.js:1:2319)
    at c.AEC__implAttach (main.js:1:58810)
    at c.C57__implAttachTo (main.js:1:58391)
    at d._addDirectChild (main.js:1:61583)
  • Вопрос задан
  • 151 просмотр
Решения вопроса 1
@aliver13 Автор вопроса
Благодарю ребят из Яндекс.
Получил ответ непосредственно от них. Спасибо, Виктор А.

Нужно использовать onClick. Он работает и на YMapMarker, и на YMapFeature.


Как выглядит моё решение:
function marker(feature) {
        const yMapMarker = new ymaps3.YMapMarker(
            {
                coordinates: feature.geometry.coordinates,
                source: 'my-source',
                onClick() {
                     // Всё что вам нужно
                     // В моём случае это showInfo, в которую я предаю свой объект
                     showInfo(feature);
                }
            },
            contentPin.cloneNode(true)
        );

        return yMapMarker;
    }
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы