Загрузка данных


<!DOCTYPE html><html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Лепесток глобуса — 1000 мм</title><style>
html, body {
    margin: 0;
    padding: 0;
    background: #e5e5e5;
}

body {
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 20px;
    box-sizing: border-box;
}

#download {
    position: fixed;
    top: 15px;
    left: 15px;
    z-index: 100;
    padding: 10px 18px;
    border: 1px solid #555;
    border-radius: 5px;
    background: white;
    color: #222;
    font-size: 16px;
    cursor: pointer;
    box-shadow: 0 2px 6px rgba(0,0,0,.2);
}

#download:hover {
    background: #f0f0f0;
}

svg {
    display: block;
    width: min(90vw, 1000px);
    height: auto;
    background: white;
}

/* Все внутренние линии */
.grid {
    fill: none;
    stroke: #f8f8f8;
    stroke-width: 0.1;
    vector-effect: non-scaling-stroke;
}

/* Края лепестка */
.edge {
    fill: none;
    stroke: #555;
    stroke-width: 0.2;
    vector-effect: non-scaling-stroke;
}

.petal-fill {
    fill: white;
    stroke: none;
}
</style></head><body><button id="download">Скачать SVG</button>

<svg
id="petal"
xmlns="http://www.w3.org/2000/svg"
width="1000mm"
height="1590.796mm"
viewBox="-80 -10 160 1590.796"
preserveAspectRatio="xMidYMin meet">

<path id="petalShape" class="petal-fill"></path>

<g id="grid"></g>
<g id="edges"></g>

</svg><script>
"use strict";

const NS = "http://www.w3.org/2000/svg";

const svg = document.getElementById("petal");
const petalShape = document.getElementById("petalShape");
const grid = document.getElementById("grid");
const edges = document.getElementById("edges");

const R = 500;
const HALF_LON = 7.5;


/* --------------------------------------------------
   ПРОЕКЦИЯ ПО МЕРИДИАНУ
-------------------------------------------------- */

function Y(latDeg) {
    const lat = latDeg * Math.PI / 180;
    return R * (Math.PI / 2 - lat);
}


/* --------------------------------------------------
   ШИРИНА ЛЕПЕСТКА
-------------------------------------------------- */

function X(latDeg, lonDeg) {
    const lat = latDeg * Math.PI / 180;
    const lon = lonDeg * Math.PI / 180;

    return R * Math.sin(lon) * Math.cos(lat);
}


/* --------------------------------------------------
   СОЗДАНИЕ SVG PATH
-------------------------------------------------- */

function createPath(d, className, parent) {
    const path = document.createElementNS(NS, "path");

    path.setAttribute("d", d);
    path.setAttribute("class", className);

    parent.appendChild(path);

    return path;
}


/* ==================================================
   1. ФОРМА ЛЕПЕСТКА
================================================== */

let petalPath = "";

/* Левая сторона: Север → Юг */
for (let lat = 90; lat >= -90; lat -= 0.25) {

    const x = X(lat, -HALF_LON);
    const y = Y(lat);

    if (lat === 90) {
        petalPath += `M ${x.toFixed(4)} ${y.toFixed(4)} `;
    } else {
        petalPath += `L ${x.toFixed(4)} ${y.toFixed(4)} `;
    }
}

/* Южный полюс */
{
    const x = X(-90, HALF_LON);
    const y = Y(-90);

    petalPath += `L ${x.toFixed(4)} ${y.toFixed(4)} `;
}

/* Правая сторона: Юг → Север */
for (let lat = -89.75; lat <= 90; lat += 0.25) {

    const x = X(lat, HALF_LON);
    const y = Y(lat);

    petalPath += `L ${x.toFixed(4)} ${y.toFixed(4)} `;
}

/* Замыкание */
petalPath += "Z";

petalShape.setAttribute("d", petalPath);


/* ==================================================
   2. ПАРАЛЛЕЛИ КАЖДЫЕ 5°
================================================== */

for (let lat = 85; lat >= -85; lat -= 5) {

    const y = Y(lat);

    const xLeft = X(lat, -HALF_LON);
    const xRight = X(lat, HALF_LON);

    createPath(
        `M ${xLeft.toFixed(4)} ${y.toFixed(4)}
         L ${xRight.toFixed(4)} ${y.toFixed(4)}`,
        "grid",
        grid
    );
}


/* ==================================================
   3. МЕРИДИАНЫ ±3.75°
================================================== */

for (const lon of [-3.75, 3.75]) {

    let d = "";

    for (let lat = 90; lat >= -90; lat -= 0.5) {

        const x = X(lat, lon);
        const y = Y(lat);

        if (lat === 90) {
            d += `M ${x.toFixed(4)} ${y.toFixed(4)} `;
        } else {
            d += `L ${x.toFixed(4)} ${y.toFixed(4)} `;
        }
    }

    createPath(d, "grid", grid);
}


/* ==================================================
   4. КРАЯ ЛЕПЕСТКА
================================================== */

for (const lon of [-HALF_LON, HALF_LON]) {

    let d = "";

    for (let lat = 90; lat >= -90; lat -= 0.25) {

        const x = X(lat, lon);
        const y = Y(lat);

        if (lat === 90) {
            d += `M ${x.toFixed(4)} ${y.toFixed(4)} `;
        } else {
            d += `L ${x.toFixed(4)} ${y.toFixed(4)} `;
        }
    }

    createPath(d, "edge", edges);
}


/* ==================================================
   5. ЛИНИИ ПОЛЮСОВ
================================================== */

function poleEdge(lat) {

    let d = "";

    for (let i = 0; i <= 40; i++) {

        const lon =
            -HALF_LON +
            i * (15 / 40);

        const x = X(lat, lon);
        const y = Y(lat);

        if (i === 0) {
            d += `M ${x.toFixed(4)} ${y.toFixed(4)} `;
        } else {
            d += `L ${x.toFixed(4)} ${y.toFixed(4)} `;
        }
    }

    createPath(d, "edge", edges);
}

poleEdge(90);
poleEdge(-90);


/* ==================================================
   6. СКАЧИВАНИЕ ГОТОВОГО SVG
================================================== */

document.getElementById("download").addEventListener("click", function () {

    const clone = svg.cloneNode(true);

    const style = document.createElementNS(NS, "style");

    style.textContent = `
        .grid {
            fill: none;
            stroke: #f8f8f8;
            stroke-width: 0.1;
        }

        .edge {
            fill: none;
            stroke: #555;
            stroke-width: 0.2;
        }

        .petal-fill {
            fill: white;
            stroke: none;
        }
    `;

    clone.insertBefore(style, clone.firstChild);

    const serializer = new XMLSerializer();

    let source =
        '<?xml version="1.0" encoding="UTF-8"?>\n' +
        serializer.serializeToString(clone);

    const blob = new Blob(
        [source],
        {
            type: "image/svg+xml;charset=utf-8"
        }
    );

    const url = URL.createObjectURL(blob);

    const a = document.createElement("a");

    a.href = url;
    a.download = "lepetok_globus_1000mm.svg";

    document.body.appendChild(a);

    a.click();

    document.body.removeChild(a);

    setTimeout(function () {
        URL.revokeObjectURL(url);
    }, 1000);
});
</script></body>
</html>