Генплан посёлка на сайте

Содержание статьи

Если вы хотите отображать генплан коттеджного поселка или участков на своем сайте, то вам нужно использовать открытый метод для получения информации о наличии участков в API Домопланера.

Пример виджета:

Код, который создает этот виджет. Кастомизируйте под свои нужны:

<!-- Сначала размечаем верстку -->
<div class="genplan-outer">
    <div class="genplan-scroll-icon" data-key="scroll-icon"></div>
    <div class="genplan-area-scroll" data-key="genplan-scroll">
        <div id="genplan-area" class="genplan-area">
            <div class="genplan-area-planinfo" data-type="planinfo"></div>
            <div class="genplan-area-svg" data-type="svg"></div>
        </div>
    </div>
</div>
<!-- Далее идут стили -->
<script>
setTimeout(function() {
    (function($) {

        /* Это переменные */
        /* URL запросите у нашей технической поддержки */
        let url = 'https://domoplaner.ru/widget-api/widget/ID/SID/areas';
        let tildaModalCode = '#popup:myform';
        let tildaCommentField = 'comment';

        // далее лучше уже не трогать
        let $genplan = $('#genplan-area');
        let $scroll = $(('[data-key="genplan-scroll"]'));
        let $scrollIcon = $(('[data-key="scroll-icon"]'));
        let $genplanSvg = $('[data-type="svg"]');
        let $planInfo = $('[data-type="planinfo"]');
        let areasStorage;

        // нужно, чтобы потом открыть попап
        //document.write("<a class='js-modal-clicker' href='" + tildaModalCode + "' style='display:none'></a>");
        window.openRequest = onButtonClick;
        window.closeGenplanSelect = closeGenplanSelect;

        $.getJSON(url, function(resp) {
            if (!resp || !resp.sections || !resp.sections.length) return;

            // в sections массив, мы берем первую
            let genplanInfo = resp.sections[0];
            areasStorage = genplanInfo.areas;

            let genplanImage = genplanInfo.image_link;
            let containerWidth = $genplan.width();

            // нужно рассчитать высоту для генплана
            let proportion = containerWidth / genplanInfo.image_width;
            let containerHeight = genplanInfo.image_height / genplanInfo.image_width * containerWidth;

            // задаем стиль отображения генплана
            $genplan.css({
                height: containerHeight + 'px',
                'background-image': 'url(' + genplanImage + ')'
            });

            /* далее выводим участки, и биндим к ним события */
            $genplanSvg.html(getSvgHtml(areasStorage, proportion));
            bindAreaEvents(areasStorage);

            if (isMobile()) {
                let w = $scroll.width();
                let wc = $genplan.width();

                $scroll.scrollLeft((wc - w) / 2);
            }
        });

        function getSvgHtml(areas, proportion) {
            let html = '<svg>';

            for (let area of areas) {
                html += '<polygon points="' + correctPoints(area.svg, proportion) + '" data-area-id="' + area.id + '" data-status="' + area.status + '"></polygon>';
            }

            html += '</svg>';

            return html
        }

        function onButtonClick(id) {
            let area = getAreaById(id);
            openModal(area);
            onPolygonMouseOut();
        }

        function correctPoints(svgPath, proportion) {

            let points = [];
            svgPath.split(' ').forEach(function(point) {
                let pointArr = point.split(',');
                points.push([
                    pointArr[0] * proportion,
                    pointArr[1] * proportion
                ].join(','));
            })

            return points.join(' ');
        }

        function bindAreaEvents(areas) {

            areas.forEach(function(area) {
                let $poly = $('polygon[data-area-id="' + area.id + '"]');
                if (!$poly) return;

                if (isMobile()) {
                    $poly.on('click', onPolygonMouseEnter)
                } else {
                    $poly.on('mousemove', onPolygonMouseMove)
                    $poly.on('mouseout', onPolygonMouseOut)
                    $poly.on('mouseenter', onPolygonMouseEnter)
                    $poly.on('click', onPolygonClick)
                }
            });

            // при первом таче через 3 секунды скрыть иконку
            $genplan.on('touchstart', function() {
                setTimeout(function() {
                    $scrollIcon.addClass('passive');
                }, 3000);
            })
        }

        function isMobile() {
            return $(window).width() < 768;
        }

        function getAreaByPolygon(poly) {
            return getAreaById($(poly).data().areaId);
        }

        function getAreaById(id) {
            return areasStorage.find(function(area) {
                return area.id === id;
            });
        }

        function openModal(area) {
            if (!area) return;

            alert('Клик по: '+JSON.stringify(area));

            setTimeout(function() {
                let commentText = getCommentForRequest(area);
                document.querySelector("a.js-modal-clicker[href='" + tildaModalCode + "']").click();
                $('[data-tooltip-hook="' + tildaModalCode + '"] [name="' + tildaCommentField + '"]').val(commentText);
            });
        }

        function onPolygonClick(areaId) {
            openModal(getAreaByPolygon(this));
        }

        function getCommentForRequest(area) {
            return ('Хочу узнать подробности по участку: №' + area.number + ' в проекте ' + area.project);
        }

        function getPlanInfoHtmlByArea(area) {
            let html = '<div class="genplan-closer" onclick="window.closeGenplanSelect()"></div><div class="dp-area-button" onclick="window.openRequest(' + area.id + ')">Подробнее</div><div class="dp-area-number">Участок №' + area.number + '</div>';
            html += '<div class="dp-area-area">Площадь: <b>' + (+(area.area / 100).toFixed(2)) + ' соток</b></div>';

            html += '<div class="dp-area-status">'
            if (area.status === 0) html += 'Свободно – <b>' + thousandsStr(area.price) + ' ₽</b>';
            if (area.status === 1) html += 'Забронировано';
            if (area.status === 2) html += 'Недоступно';
            html += '</div>';

            return html;
        }


        function onPolygonMouseEnter(e) {
            let area = getAreaByPolygon(this);
            if (!area) return;

            $planInfo.html(getPlanInfoHtmlByArea(area)).addClass('active');
        }

        function onPolygonMouseMove(e) {
            var left = e.clientX;

            if (left > ($(window).width() - 270)) {
                left = $(window).width() - 270;
            }

            $planInfo.css({
                left: left + 'px',
                top: e.clientY + 'px',
            })
        }


        function onPolygonMouseOut() {
            $planInfo.removeClass('active');
        }

        function closeGenplanSelect() {
            $planInfo.removeClass('active');
        }

        function thousandsStr(input, separator) {
            if (input === 0) return 0;

            let num = input;
            if (typeof num === 'string') num = parseFloat(num.replace(',', '.'));

            if (typeof num !== 'number') return;

            var str = num.toString();

            if (str.indexOf('.') !== -1) str = num.toFixed(2);

            return str.replace(/\B(?=(\d{3})+(?!\d))/g, separator || ' ').replace('.', ',');
        }


    })(jQuery);
}, 2000);
</script>
<!-- Далее идут стили -->
<style>
.genplan-area {
    margin: auto;
    width: 900px;
    background-position: center;
    background-size: cover;
    position: relative;
    font-family: Arial;
}

.genplan-area-svg {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

.genplan-area-svg svg {
    width: 100%;
    height: 100%;
}


.genplan-area-planinfo {
    position: fixed;
    width: 240px;
    height: auto;
    font-size: 16px;
    pointer-events: none;
    background: #fff;
    z-index: 3;
    margin: 20px 0 0 20px;
    opacity: 0;
    transition: opacity 0.3s;
    padding: 20px;
    border-radius: 5px;
    box-shadow: 0px 2px 15px rgba(0, 0, 0, 0.2);
    transform: translateY(0%);
}

.genplan-area-planinfo.active {
    opacity: 1;
}

.genplan-area-planinfo .dp-area-button {
    position: absolute;
    top: 0;
    right: 0;
    padding: 5px 20px;
    display: none;
    width: 100px;
    text-align: center;
    background: #485275;
    color: #fff;
    bottom: 0;
    line-height: 120px;
    font-size: 16px;
}


.genplan-closer {
    background: #fff url(https://storage.yandexcloud.net/domoplaner/devmedia/297/close.png) center no-repeat;
    background-size: 28px;
    position: absolute;
    bottom: 100%;
    width: 50px;
    height: 50px;
    right: 10px;
    border-radius: 50%;
    margin-bottom: 20px;
    display: none;
}

.genplan-area-svg polygon {
    transition: 0.2s
}

.genplan-area-svg polygon[data-status="0"] {
    fill: #ffffff;
    fill-opacity: 0;
    cursor: pointer;
    stroke: #fff;
    stroke-width: 3;
}

.genplan-area-svg polygon[data-status="0"]:hover {
    fill-opacity: 0.5;
}

.genplan-area-svg polygon[data-status="1"] {
    fill: #5a502a;
    cursor: pointer;
    fill-opacity: 0.45;
}

.genplan-area-svg polygon[data-status="2"] {
    fill: #91ba56;
    fill-opacity: 0.8;
    pointer-events: none;
}

.genplan-scroll-icon {
    background: url(https://storage.yandexcloud.net/domoplaner/devmedia/297/scroll-icon.png) center no-repeat;
    background-size: cover;
    position: absolute;
    left: 50%;
    width: 50px;
    height: 50px;
    margin-left: -25px;
    top: 100px;
    transition: opacity 0.5s;
    pointer-events: none;
    animation: linear infinite;
    animation-name: genplan-left-right;
    animation-duration: 5s;
    display: none;
    z-index: 3;
}

.genplan-outer {
    position: relative;
}

.genplan-scroll-icon.passive {
    opacity: 0;
}

@-webkit-keyframes genplan-left-right {
    0% {
        transform: translateX(-10px);
    }

    50% {
        transform: translateX(10px);
    }

    100% {
        transform: translateX(-10px);
    }
}

@media only screen and (max-width: 767px) {}

@media only screen and (max-width: 767px) {
    .genplan-scroll-icon {
        display: block;
    }

    .genplan-closer {
        display: block;
    }

    .genplan-area-planinfo {
        left: 0;
        right: 0;
        width: auto;
        bottom: 0;
        transform: translateY(100%);
        transition: 0.3s;
        padding: 30px 20px;
        margin: 0;
        pointer-events: all;
    }

    .genplan-area-planinfo .dp-area-button {
        display: block;
    }

    .genplan-area-planinfo.active {
        transform: translateY(0%);
    }

    .genplan-area-scroll {
        overflow-x: auto;
        overflow-y: hidden;
        position: relative;
    }
}

.dp-area-number {
    font-size: 120%;
    margin-bottom: 10px;
}
</style>
Содержание статьи