Клуб API Карт

Как создать HTML-метку с поведением обычной метки (с подсказкой и балуном)?

f-ph
2 апреля 2016, 10:15

Здравствуйте. Мне нужно создать на карте метку (ymaps.Placemark), которая задаётся HTML кодом (по ряду причин задать картинкой нельзя). Как следать это так, чтобы при этом работало стандартное поведение метки (курсор при наведении, подсказка и балун)?

Я пытался сделать так:

var customIcon = ymaps.templateLayoutFactory.createClass( '<div class="theme-border theme-background" style="width: 0.6em; height: 0.6em; border-style: solid; border-width: 0.4em; border-radius: 100%; margin: -0.7em;"></div>' );
var placemark = new ymaps.Placemark(
    [ 43, 56 ],
    { hintContent: 'Метка', balloonContent: 'Описание' },
    { iconLayout: customIcon }
);
myMap.geoObjects.add( placemark );

Но так исчезает вся интерактивность метки.

Ещё пытался сделать так:

var customIcon = ymaps.templateLayoutFactory.createClass( '<div class="theme-border theme-background" style="width: 0.6em; height: 0.6em; border-style: solid; border-width: 0.4em; border-radius: 100%; margin: -0.7em;"></div>' );
var placemark = new ymaps.Placemark(
    [ 43, 56 ],
    { hintContent: 'Метка', balloonContent: 'Описание' },
    {
        iconLayout: 'default#imageWithContent',
        iconImageHref: '',
        iconImageSize: [ 0, 0 ],
        iconImageOffset: [ 0, 0 ],
        iconContentLayout: customIcon
    }
);
myMap.geoObjects.add( placemark );

В таком случае поведение сохраняется, но активной областью метки становится квадрат 1х1 пиксель в центре, что не хорошо. А использование 'default#imageWithContent' выглядит как костыль.

3 комментария
Подписаться на комментарии к посту
нужно определить метод макета getShape
https://tech.yandex.ru/maps/doc/jsapi/2.1/ref/reference/layout.templateBased.Base-docpage/#getShape

см второй параметр в templateLayoutFactory.createClass

либо если рамер иконки всегда будет одинаковым – опцию iconShape
dimik,
Спасибо!

В итоге, получилось такое универсальное решение (форма иконки принимается за прямоугольник):
var customIcon = ymaps.templateLayoutFactory.createClass(
    '<div class="theme-border theme-background" style="width: 0.6em; height: 0.6em; border-style: solid; border-width: 0.4em; border-radius: 100%; margin: -0.7em;"></div>',
    {
        getShape: function()
        {
            var elem = this.getElement();
            if ( !elem )
                return null;

            var icon = elem.firstChild;

            return new ymaps.shape.Rectangle( new ymaps.geometry.pixel.Rectangle([
                [ icon.offsetLeft, icon.offsetTop ],
                [ icon.offsetLeft + icon.offsetWidth, icon.offsetTop + icon.offsetHeight ]
            ]));
        }
    }
);
var placemark = new ymaps.Placemark(
    [ 43, 56 ],
    { hintContent: 'Метка', balloonContent: 'Описание' },
    { iconLayout: customIcon }
);
myMap.geoObjects.add( placemark );
f-ph,
А вот так можно сделать для круглой иконки:

getShape: function() {
    var elem = this.getElement();
    if ( !elem )
        return null;

    var icon = elem.firstChild;

    return new ymaps.shape.Circle( new ymaps.geometry.pixel.Circle(
        [ icon.offsetLeft + icon.offsetWidth / 2, icon.offsetTop + icon.offsetHeight / 2 ],
        ( icon.offsetWidth + icon.offsetHeight ) / 4
    ));
}