Я.Карта с кластерами и карточками объектов

Модификация позволяет добавить карту с метками, которые открывают карточки объекта с фото, текстом и кнопкой
Инструкция по настройке
Шаблон страницы
Как добавить шаблон
64265195
Для корректной работы модификаций подключите библиотеку jQuery:
Настройки сайта -> Еще -> Подключить jQuery на страницах сайта
jQuery
1 шаг
  1. Создаем html-элемент
  2. Задаем ему ширину и высоту по 100%
  3. Задаем html-элементу позиционирование CONTAINER: WINDOW (X: LEFT, Y: TOP)
  4. Копируем в него код
Добавляем Zero блок
Скопировать код
Настраиваем стили для карточек
2 шаг
  1. По комментариям в коде заменяем цвет необходимых элементов
  2. Для изменения цвета метки, скачиваем svg файл
  3. В Figma заменяем черный цвет элементов на необходимый
  4. Загружаем получившийся svg файл на Тильду (в любой блок для изображений, и копируем ссылку на изображение)
  5. Заменяем ссылку на файл в строках 252, 257, 262
3 шаг
Добавляем блок T123 и копируем в него код
Скопировать код
В коде блока T123 добавлены массив-образец {в таких скобках}, который необходимо продублировать необходимое количество раз и настроить:
  1. Заменить координаты метки
  2. Заменить изображения объектов
  3. Заменить описание и адрес
  4. Заменить цену и кол-во спальных мест
  5. Заменить ссылку для кнопки "Подробнее"
При необходимости, можно удалить строку с лишним параметром
Настраиваем информацию для карточек
4 шаг
<!--TS09 - Модификация для Тильды. Я.Карта с кластерами и карточками объектов https://mod.tistols.com/karta-s-kartochkami -->
<div id="karta"></div> <!-- Контейнер, в который будет встроена карта -->
<style>
:root {
    --green:#141414;             /* Основной цвет: используется для фона кластера и кнопок */
    --green-hovered:#000;        /* Цвет при наведении на элементы */
    --text-color:#fff;           /* Основной цвет текста (белый) */
    --border:5px;                /* Радиус скругления углов */
}

#karta {
    width: 100%;                 /* Карта растягивается на всю ширину */
    height: 100%;                /* Карта растягивается на всю высоту родительского блока */
    padding: 0;                  /* Убираем внутренние отступы */
    margin: 0;                   /* Убираем внешние отступы */
}

.ymaps-2-1-79-balloon__content ymaps {
    height: 100% !important;     /* Высота контента на всю доступную */
    display: flex;               /* Используем флексбокс для вертикального расположения */
    flex-direction: column;     /* Располагаем элементы по вертикали */
    width: 250px;                /* Ширина всплывающего окна */
}

.ymaps-2-1-79-balloon__content ymaps img {
    width: 100%!important;       /* Картинка во всплывающем окне занимает всю ширину */
}

.ymaps-2-1-79-balloon {
    width:300px;                 /* Ширина самого балуна */
}

.cluster-item {
    display: flex;               /* Располагаем элементы кластера с помощью флексбокса */
    flex-direction: column;     /* Располагаем их вертикально */
}

.ymaps-2-1-79-default-cluster {
    line-height: normal!important;     /* Убираем лишние расстояния между строками */
    height:auto !important;           /* Высота подстраивается под контент */
    width:fit-content!important;      /* Ширина автоматически подстраивается под контент */
}

.custom-cluster-icon {
    width:fit-content;                /* Ширина по содержимому */
    height: fit-content;             /* Высота по содержимому */
    border-radius: var(--border);    /* Скругление углов, заданное в переменной */
    text-align: center;              /* Текст по центру */
    font-weight: 400;                /* Толщина шрифта */
    color: #fff;                     /* Цвет текста — белый */
    background-color: var(--green); /* Цвет фона иконки кластера */
    line-height: normal;             /* Обычный межстрочный интервал */
    display: flex;                   /* Используем флексбокс */
    justify-content: center;        /* Центруем по горизонтали */
    align-items: center;            /* Центруем по вертикали */
    padding: 3px;                    /* Внутренние отступы */
    gap: 5px                         /* Расстояние между элементами внутри */
}

.custom-cluster-icon .count {
    background-color: white;          /* Белый фон для счётчика */
    color: var(--green);              /* Цвет текста — основной */
    border-radius: 50px;              /* Скругление — делает круг */
    width:15px;                       /* Ширина кружка */
    height: 15px;                     /* Высота кружка */
    display: flex;                    /* Центруем число внутри */
    align-items: center;
    justify-content: center;
    font-size: 9px;                   /* Размер цифры */
    font-weight: 600;                 /* Жирность цифры */
}

.custom-cluster-icon .info {
    white-space: nowrap;             /* Запрещает перенос текста */
    padding-right: 3px;              /* Отступ справа */
}

.baloon_info {
    background: #fff;                /* Белый фон балуна */
    border-radius: 20px;             /* Скругление углов */
    padding: 15px;                   /* Внутренние отступы */
    max-width: 320px;                /* Максимальная ширина */
    max-height: 400px;               /* Максимальная высота */
    overflow-y: scroll;              /* Прокрутка по вертикали */
}

.baloon_info img {
    max-width: 100%;                 /* Картинки не выходят за границы */
}

.custom-content {
    margin-bottom: 20px;             /* Отступ снизу */
}

.ymaps-2-1-79-balloon {
    box-shadow: none;                /* Убираем тень */
}

.ymaps-2-1-79-balloon__layout {
    background: transparent;         /* Прозрачный фон */
}

.ymaps-2-1-79-balloon__close + .ymaps-2-1-79-balloon__content {
    padding: 15px;                   /* Отступ внутри */
    border-radius: var(--border);   /* Скругление углов */
    background: #fff;               /* Белый фон */
    margin-right: 0;                /* Убираем отступ справа */
}

.ymaps-2-1-79-balloon__content ymaps {
    height: 100%!important;         /* Контент растягивается по высоте */
}

.ymaps-2-1-79-balloon__content .costum-title {
    display: none;                  /* Скрываем заголовок по умолчанию */
}

.ymaps-2-1-79-b-cluster-tabs__menu-item-text .costum-title {
    display: block;                 /* Показываем заголовок в табах */
}

.costum-content {
    height: 100%;                   /* Высота на 100% родителя */
    display: flex;                  /* Располагаем содержимое с помощью флексбокса */
    flex-direction: column;        /* Элементы идут вертикально */
    font-size: 13px;               /* Размер текста */
    line-height: 20px;             /* Межстрочный интервал */
}

.costum-content h2 {
    color: var(--text-color);      /* Цвет заголовка */
    padding: 20px 0;               /* Отступы сверху и снизу */
}

.costum-content p {
    color: var(--text-color);      /* Цвет параграфа */
}

.costum-content img {
    width: 220px;                  /* Ширина изображения */
    height: 180px;                 /* Высота изображения */
    object-fit: cover;             /* Картинка заполняет область без искажений */
    border-radius: var(--border); /* Скруглённые углы */
    margin-bottom: 20px;          /* Отступ снизу */
}

.costum-btn {
    color: #fff!important;         /* Цвет текста кнопки */
    background: #141414;           /* Фон кнопки */
    border-radius: 5px;            /* Скругление кнопки */
    padding: 10px 10px;            /* Внутренние отступы */
    margin-top: 10px;              /* Отступ сверху */
    max-width: fit-content;        /* Ширина подстраивается под контент */
}

.ymaps-2-1-79-b-cluster-tabs__item-header .accordion-header,
.ymaps-2-1-79-balloon-content__header .accordion-header {
    background: #fff;              /* Белый фон заголовка аккордеона */
    color: var(--text-color);      /* Цвет текста */
    font-size: 15px;               /* Размер текста */
    pointer-events: none;          /* Отключаем клики */
}

.costum-content .costum-btn:hover {
    color: var(--green)!important;       /* Цвет текста при наведении */
    background: var(--green-hovered);    /* Фон при наведении */
}

.accordion-header {
    font-size: 12px;               /* Размер текста */
    font-weight: 500;              /* Жирность */
    background-color: var(--green-hovered); /* Цвет фона */
    color: var(--green);           /* Цвет текста */
    padding: 10px;                 /* Внутренний отступ */
    border-radius: var(--border); /* Скругление */
    width: 100%;                   /* Полная ширина */
}

.accordion-header:hover {
    background-color: var(--green); /* Цвет при наведении */
    color: #fff;                     /* Цвет текста при наведении */
}

.ymaps-2-1-79-b-cluster-tabs__menu-item_current_yes {
    border-radius: 10px 0 0 10px;   /* Скругление активного таба */
}

.ymaps-2-1-79-b-cluster-tabs__menu-item_current_yes .accordion-header {
    background-color: var(--green); /* Фон активного заголовка */
    color: #fff;                    /* Цвет текста активного заголовка */
}

.accordion-content {
    padding: 5px;                   /* Внутренние отступы */
    border: 1px solid #141414;     /* Рамка */
    background-color: #fff;        /* Фон */
    border-radius: var(--border);  /* Скругление */
}

.ymaps-2-1-79-b-cluster-tabs__menu-item {
    padding: 0;                     /* Убираем отступы */
}

.ymaps-2-1-79-b-cluster-content {
    display: flex;                  /* Флекс-контейнер */
    max-width: 320px;              /* Максимальная ширина */
}

.ymaps-2-1-79-b-cluster-tabs__section_type_nav {
    max-width: 90px;               /* Ширина панели навигации в табах */
}

.ymaps-2-1-79-b-cluster-tabs__item-body {
    padding-right: 0;              /* Убираем правый отступ */
}

@media screen and (max-width:640px) {
    #karta {
        width: 100%;
        height: 100%;
    }

    .ymaps-2-1-79-balloon__close + .ymaps-2-1-79-balloon__content {
        max-width: 300px;          /* Уменьшаем ширину балуна на мобилке */
    }

    .costum-content img {
        width: 155px;              /* Уменьшаем размер картинки */
        height: 105px;
    }

    .ymaps-2-1-79-b-cluster-content {
        display: flex;
        max-width: 320px;
    }

    .custom-content {
        max-width: 200px!important; /* Ограничиваем ширину */
    }

    .ymaps-2-1-79-b-cluster-tabs__section_type_nav {
        min-width: 80px!important;
    }

    .ymaps-2-1-79-balloon__content ymaps {
        max-width: 250px!important;
        width: 100%;
    }
}

.ymaps-2-1-79-placemark_theme_darkgreen {
    background: url(https://static.tildacdn.com/tild6566-3036-4333-b366-306334373362/svgexport-1_70_1.svg); /* Кастомный маркер */
    background-position: 0 40px;
}

.ymaps-2-1-79-placemark__l {
    background: url(https://static.tildacdn.com/tild6566-3036-4333-b366-306334373362/svgexport-1_70_1.svg)!important; /* Левая часть */
    background-position: 0 0;
}

.ymaps-2-1-79-placemark__r {
    background: url(https://static.tildacdn.com/tild6566-3036-4333-b366-306334373362/svgexport-1_70_1.svg)!important; /* Правая часть */
    background-position: 80px 0!important;
}
</style>
<!--TS09 - Модификация для Тильды. Я.Карта с кластерами и карточками объектов https://mod.tistols.com/karta-s-kartochkami -->
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>

<script>
    var objects = [
        {
            coordinates: [55.545105, 37.55964], // здесь задаем координаты для метки
            image: "https://static.tildacdn.com/tild3266-3739-4135-b933-623964303461/thumbnail_00c55482-d.jpg", // фото объекта
            description: "1-к квартира, 37м²", // заголовок (над фото)
            address: "ул. Изюмская, д.46к2", // адрес (под фото)
            price: 2200, // цена
            sleepingPlaces: 2, // спальных мест
            link: "#1" //ссылка для кнопки "Подробнее"
        },
{
            coordinates: [55.548375, 37.534469],
            image: "https://static.tildacdn.com/tild6433-6665-4436-b665-353430336633/thumbnail_b8166acc-e.jpg", 
            description: "1-к квартира, 37м²",
            address: "Плавский проезд, д.5",
            price: 2700,
            sleepingPlaces: 3,
            link: "#2"
        },
{
            coordinates: [55.545722, 37.534325],
            image: "https://static.tildacdn.com/tild6132-3930-4338-b261-666630376232/thumbnail_3c73912f-1.jpg", 
            description: "2-к квартира, 54м²",
            address: "ул. Адмирала Лазарева, д.19",
            price: 2700,
            sleepingPlaces: 4,
            link: "#3"
        }
    ];
</script>

<script>
$(function(){

    ymaps.ready(function () {
    var karta = new ymaps.Map("karta", {
        center: [55.755864, 37.617698],
        zoom: 10
    });

    var geoObjects = [];
    var clusterer = new ymaps.Clusterer({
        groupByCoordinates: false,
        clusterDisableClickZoom: true,
        clusterIcons: [{
            href: '', // Путь к картинке (если нужна)
            size: [80, 80],
            offset: [-40, -40]
        }],
        clusterIconContentLayout: ymaps.templateLayoutFactory.createClass(
            '<div class="custom-cluster-icon"><span class="count">{{ properties.geoObjects.length }}</span> <span class="info"> от {{ properties.minPrice }} ₽</span></div>'
        ),
        // Кастомный макет для балуна кластера
        clusterBalloonContentLayout: ymaps.templateLayoutFactory.createClass(
            '<div style="max-height: 320px; overflow-y: auto; width: 100%;overflow-x: hidden;">' +
                '{% for geoObject in properties.geoObjects %}' +
                    '<div class="cluster-item" style="margin-bottom: 10px;">' +
                        '<strong>{{ geoObject.properties.description }}</strong>' +
                        '<img src="{{ geoObject.properties.image }}" alt="{{ geoObject.properties.name }}" style="width: 100%; height: auto; max-height: 150px; margin: 5px 0;">' +
                        '<p>Адрес: {{ geoObject.properties.address }}</p>' +
                        '<p>Спальных мест: {{ geoObject.properties.sleepingPlaces }}</p>' +
                        '<p>Цена: от {{ geoObject.properties.price }} ₽</p>' +
                        '<a class="costum-btn" href="{{ geoObject.properties.link }}" target="_blank">Подробнее</a>' +
                    '</div>' +
                    '<hr>' +
                '{% endfor %}' +
            '</div>'
        ),
        clusterBalloonPanelMaxMapArea: 0 // Отключает автоматическое увеличение балуна кластера
    });

    objects.forEach(function (obj) {
        var placemark = new ymaps.Placemark(obj.coordinates, {
            description: obj.description,
            image: obj.image,
            address: obj.address,
            sleepingPlaces:obj.sleepingPlaces,
            price: obj.price,
            link: obj.link,
            balloonContentHeader: '<strong>' + obj.description + '</strong>',
            balloonContentBody: '<img src="' + obj.image + '" alt="' + obj.name + '" style="width: 100px; height: auto;">' +
                                '<p>Адрес: ' + obj.address + '</p>' +
                                '<p>Спальных мест: ' + obj.sleepingPlaces + '</p>' +
                                '<p>Цена: от ' + obj.price + ' ₽</p>' +
                                '<a class="costum-btn" href="' + obj.link + '">Подробнее</a>',
            iconContent: obj.price + ' ₽'
        }, {
            preset: 'islands#darkGreenStretchyIcon'
        });

        geoObjects.push(placemark);
    });

    clusterer.add(geoObjects);
    karta.geoObjects.add(clusterer);

    // Вычисляем минимальную цену сразу после добавления объектов в кластер
    function updateClusterMinPrices() {
        clusterer.getClusters().forEach(function(cluster) {
            var clusterGeoObjects = cluster.getGeoObjects();
            var minPrice = Math.min.apply(null, clusterGeoObjects.map(function(geoObject) {
                return parseInt(geoObject.properties.get('iconContent').replace(' ₽', ''));
            }));
            cluster.properties.set('minPrice', minPrice);
        });
    }

    updateClusterMinPrices();

    clusterer.events.add('objectsadd', updateClusterMinPrices);
    karta.events.add('boundschange', function(e) {
        if (e.get('newZoom') !== e.get('oldZoom')) {
            updateClusterMinPrices();
        }
    });
});

});
</script>
Вам также может быть интересно: