Skip to content

Instantly share code, notes, and snippets.

@AnatoliyKhaulin
Created March 2, 2018 11:09
Show Gist options
  • Select an option

  • Save AnatoliyKhaulin/bc88c77c082ef764340a22b584fa0ed3 to your computer and use it in GitHub Desktop.

Select an option

Save AnatoliyKhaulin/bc88c77c082ef764340a22b584fa0ed3 to your computer and use it in GitHub Desktop.
Yandex Map geoObjects custom balloon and pin
Display the source blob
Display the rendered blob
Raw
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"id": 0,
"geometry": {
"type": "Point",
"coordinates": [56.839526, 35.915296]
},
"properties": {
"balloonHeader": "Заголовок",
"balloonCell1Title": "Заголовок ячейки",
"balloonCell1Val": "Значение",
"balloonCell2Title": "Заголовок ячейки",
"balloonCell2Val": "Значение",
"balloonCell3Title": "Заголовок ячейки",
"balloonCell3Val": "Значение",
"balloonFooter": "Футер",
"hintContent": ""
}
},
]
}
// Создание макета балуна
MyBalloonLayout = ymaps.templateLayoutFactory.createClass(
'<div id="balloonPopover" class="popover top">' +
'<a class="close" href="#">&times;</a>' +
'<div class="arrow"></div>' +
'<div class="popover-inner">' +
'$[[options.contentLayout observeSize minWidth=320 maxWidth=320 maxHeight=165]]' +
'</div>' +
'</div>', {
/**
* Строит экземпляр макета на основе шаблона и добавляет его в родительский HTML-элемент.
* @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/layout.templateBased.Base.xml#build
* @function
* @name build
*/
build: function () {
this.constructor.superclass.build.call(this);
this._$element = $('.popover', this.getParentElement());
this.applyElementOffset();
this._$element.find('.close')
.on('click', $.proxy(this.onCloseClick, this));
},
/**
* Удаляет содержимое макета из DOM.
* @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/layout.templateBased.Base.xml#clear
* @function
* @name clear
*/
clear: function () {
this._$element.find('.close')
.off('click');
this.constructor.superclass.clear.call(this);
},
/**
* Метод будет вызван системой шаблонов АПИ при изменении размеров вложенного макета.
* @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/IBalloonLayout.xml#event-userclose
* @function
* @name onSublayoutSizeChange
*/
onSublayoutSizeChange: function () {
MyBalloonLayout.superclass.onSublayoutSizeChange.apply(this, arguments);
if(!this._isElement(this._$element)) {
return;
}
this.applyElementOffset();
this.events.fire('shapechange');
},
/**
* Сдвигаем балун, чтобы "хвостик" указывал на точку привязки.
* @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/IBalloonLayout.xml#event-userclose
* @function
* @name applyElementOffset
*/
applyElementOffset: function () {
this._$element.css({
left: -(this._$element[0].offsetWidth / 2),
top: -(this._$element[0].offsetHeight + this._$element.find('.arrow')[0].offsetHeight + 20)
});
},
/**
* Закрывает балун при клике на крестик, кидая событие "userclose" на макете.
* @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/IBalloonLayout.xml#event-userclose
* @function
* @name onCloseClick
*/
onCloseClick: function (e) {
e.preventDefault();
this.events.fire('userclose');
},
/**
* Используется для автопозиционирования (balloonAutoPan).
* @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/ILayout.xml#getClientBounds
* @function
* @name getClientBounds
* @returns {Number[][]} Координаты левого верхнего и правого нижнего углов шаблона относительно точки привязки.
*/
getShape: function () {
if(!this._isElement(this._$element)) {
return MyBalloonLayout.superclass.getShape.call(this);
}
var position = this._$element.position();
return new ymaps.shape.Rectangle(new ymaps.geometry.pixel.Rectangle([
[position.left, position.top], [
position.left + this._$element[0].offsetWidth,
position.top + this._$element[0].offsetHeight + this._$element.find('.arrow')[0].offsetHeight
]
]));
},
/**
* Проверяем наличие элемента (в ИЕ и Опере его еще может не быть).
* @function
* @private
* @name _isElement
* @param {jQuery} [element] Элемент.
* @returns {Boolean} Флаг наличия.
*/
_isElement: function (element) {
return element && element[0] && element.find('.arrow')[0];
}
}),
// Создание вложенного макета содержимого балуна.
MyBalloonContentLayout = ymaps.templateLayoutFactory.createClass(
'<h5 class="popover-title">$[properties.balloonHeader]</h5>' +
'<div class="row">' +
'<div class="cell">' +
'<span>$[properties.balloonCell1Title]</span>' +
'<span class="strong">$[properties.balloonCell1Val]</span>' +
'</div>' +
'<div class="cell">' +
'<span>$[properties.balloonCell2Title]</span>' +
'<span class="strong">$[properties.balloonCell2Val]</span>' +
'</div>' +
'<div class="cell">' +
'<span>$[properties.balloonCell3Title]</span>' +
'<span class="strong">$[properties.balloonCell3Val]</span>' +
'</div>' +
'</div>' +
'<div class="popover-footer">$[properties.balloonFooter]</div>'
),
objectManager = new ymaps.ObjectManager({
// Чтобы метки начали кластеризоваться, выставляем опцию.
clusterize: false,
// ObjectManager принимает те же опции, что и кластеризатор.
gridSize: 32,
clusterDisableClickZoom: false,
});
objectManager.objects.options.set({
balloonLayout: MyBalloonLayout,
balloonContentLayout: MyBalloonContentLayout,
balloonPanelMaxMapArea: 0,
iconLayout: 'default#image',
iconImageHref: './images/contacts/map_marker.svg',
iconImageSize: [30, 37],
iconImageOffset: [-20, -33],
});
myMap.geoObjects.add(objectManager);
$.ajax({
url: "./geo.json"
}).done(function(data) {
objectManager.add(data);
});
// show balloon hover
objectManager.objects.events.add('mouseenter', function (e) {
var objectId = e.get('objectId');
objectManager.objects.balloon.open(objectId);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment