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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
// Создание макета балуна
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