Skip to content

Instantly share code, notes, and snippets.

@newbornfrontender
Last active January 7, 2023 06:35
Show Gist options
  • Save newbornfrontender/c58a15251f0293c490f3f5bdc0e5dc64 to your computer and use it in GitHub Desktop.
Save newbornfrontender/c58a15251f0293c490f3f5bdc0e5dc64 to your computer and use it in GitHub Desktop.
yandex map custom cluster and placemark
import $ from 'jquery';
// $(document).ready(() => {
// // Создание кластеризатора с произвольным HTML-макетом иконки кластера
// class CustomCluster {
// // Зададаем макет метки кластера
// createCluster() {
// return ymaps.templateLayoutFactory.createClass(
// '<div class="ymap-cluster-icon">{{ properties.geoObjects.length }}</div>',
// );
// }
// // Зададаем активную область иконки кластера
// createIconShape() {
// return {
// type: 'Circle',
// coordinates: [0, 0],
// radius: 25,
// };
// }
// }
// const init = () => {
// const clusterer = new CustomCluster;
// const map = new ymaps.Map(
// 'map',
// {
// center: [55.76, 37.64],
// zoom: 10,
// },
// {
// searchControlProvider: 'yandex#search',
// },
// );
// const objectManager = new ymaps.ObjectManager({
// // Включает кластеризацию
// clusterize: true,
// // Устанавливает размер ячейки кластеризации в пикселях
// gridSize: 32,
// });
// objectManager.objects.options.set({
// // Указываем тип макета
// iconLayout: 'default#imageWithContent',
// // Добавляем своё изображение иконки метки
// iconImageHref: 'img/marker.svg',
// // Указываем размеры метки
// iconImageSize: [50, 50],
// // Изменяем положение левого верхнего угла иконки относительно её точки привязки
// iconImageOffset: [-25, -25],
// // Не скрывать метку при открытии балуна
// hideIconOnBalloonOpen: false,
// });
// objectManager.clusters.options.set({
// clusterIconLayout: clusterer.createCluster(),
// clusterIconShape: clusterer.createIconShape(),
// });
// map.geoObjects.add(objectManager);
// $.ajax({
// url: 'data.json',
// }).done((data) => {
// objectManager.add(data);
// });
// };
// ymaps.ready(init);
// });
// =============================================================================
// =============================================================================
// =============================================================================
$(document).ready(() => {
// Создание кластеризатора с произвольным HTML-макетом иконки кластера
class CustomCluster {
// Зададаем макет метки кластера
createCluster() {
return ymaps.templateLayoutFactory.createClass(
'<div class="ymap-cluster-icon">{{ properties.geoObjects.length }}</div>',
);
}
// Зададаем активную область иконки кластера
createIconShape() {
return {
type: 'Circle',
coordinates: [0, 0],
radius: 25,
};
}
}
const init = () => {
const coords = [
[56.023, 36.988],
[56.025, 36.981],
[56.02, 36.981],
[56.021, 36.983],
[56.027, 36.987],
];
const geoObjects = [];
const map = new ymaps.Map(
'map',
{
center: [55.76, 37.64],
zoom: 10,
},
{
searchControlProvider: 'yandex#search',
},
);
const cluster = new CustomCluster();
const CustomBalloonLayout = ymaps.templateLayoutFactory.createClass(
`
<div class="ymap-popover">
<a class="ymap-popover-close" href="/">&times;</a>
<div class="ymap-popover-arrow"></div>
<div class="popover-inner">
$[[options.contentLayout observeSize minWidth=235 maxWidth=235 maxHeight=350]]
</div>
</div>
`,
{
// Строим экземпляр макета на основе шаблона и добавляем его в родительский HTML-элемент
build() {
this.constructor.superclass.build.call(this);
this._$element = $('.ymap-popover', this.getParentElement());
this.applyElementOffset();
this._$element.find('.ymap-popover-close').on('click', $.proxy(this.onCloseClick, this));
},
// Удаляем содержимое макета из DOM
clear() {
this._$element.find('.ymap-popover-close').off('click');
this.constructor.superclass.clear.call(this);
},
// Метод будет вызван системой шаблонов API при изменении размеров вложенного макета
onSublayoutSizeChange() {
CustomBalloonLayout.superclass.onSublayoutSizeChange.apply(this, arguments);
if (!this._isElement(this._$element)) {
return;
}
this.applyElementOffset();
this.events.fire('shapechange');
},
// Сдвигаем балун, чтобы "хвостик" указывал на точку привязки
applyElementOffset() {
this._$element.css({
left: -(this._$element[0].offsetWidth / 2),
// По какой-то причине prettier и stylelint считают строку ниже за CSS
// stylelint-disable
top: -(
this._$element[0].offsetHeight +
this._$element.find('.ymap-popover-arrow')[0].offsetHeight
),
});
},
// Закрываем балун при клике на крестик, кидая событие "userclose" на макете
onCloseClick(e) {
e.preventDefault();
this.events.fire('userclose');
},
// Используется для автопозиционирования (balloonAutoPan)
getShape() {
if (!this._isElement(this._$element)) {
return CustomBalloonLayout.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('.ymap-popover-arrow')[0].offsetHeight,
],
]),
);
},
_isElement(element) {
return element && element[0] && element.find('.ymap-popover-arrow')[0];
},
},
);
const CustomBalloonContentLayout = ymaps.templateLayoutFactory.createClass(
'<h3 class="popover-title">$[properties.balloonHeader]</h3>' +
'<div class="popover-content">$[properties.balloonContent]</div>',
);
coords.forEach((item, i) => {
geoObjects[i] = new ymaps.GeoObject(
{
geometry: {
type: 'Point',
coordinates: coords[i],
},
properties: {
balloonHeader: 'Заголовок балуна',
balloonContent: 'Контент балуна',
},
},
{
// Указываем тип макета
iconLayout: 'default#imageWithContent',
// Добавляем своё изображение иконки метки
iconImageHref: 'img/marker.svg',
// Указываем размеры метки
iconImageSize: [50, 50],
// Изменяем положение левого верхнего угла иконки относительно её точки привязки
iconImageOffset: [-25, -25],
// Не скрывать метку при открытии балуна
hideIconOnBalloonOpen: false,
balloonShadow: false,
balloonLayout: CustomBalloonLayout,
balloonContentLayout: CustomBalloonContentLayout,
balloonPanelMaxMapArea: 0,
},
);
});
const clusterer = new ymaps.Clusterer({
gridSize: 32,
clusterIconLayout: cluster.createCluster(),
clusterIconShape: cluster.createIconShape(),
});
clusterer.add(geoObjects);
map.geoObjects.add(clusterer);
};
ymaps.ready(init);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment