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


<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Лепесток звёздного глобуса — 1000 мм</title>
<style>
html,body{
  margin:0;
  padding:0;
  background:#fff;
}
svg{
  display:block;
  width:1000mm;
  height:1000mm;
}
.grid{
  fill:none;
  stroke:#f8f8f8;
  stroke-width:0.3;
  vector-effect:non-scaling-stroke;
}
.edge{
  fill:none;
  stroke:#808080;
  stroke-width:0.3;
  vector-effect:non-scaling-stroke;
}
#download{
  position:fixed;
  top:10px;
  left:10px;
  z-index:100;
  padding:10px 16px;
  font-size:16px;
  cursor:pointer;
}
</style>
</head>

<body>

<button id="download">Скачать SVG</button>

<svg
  id="petal"
  xmlns="http://www.w3.org/2000/svg"
  width="1000mm"
  height="1000mm"
  viewBox="-550 -550 1100 1100">

  <rect x="-550" y="-550" width="1100" height="1100" fill="white"/>

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

</svg>

<script>
const svg = document.getElementById("petal");
const grid = document.getElementById("grid");
const edges = document.getElementById("edges");

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

const R = 500;

// Один лепесток = 1 час = 15°
// Центральный меридиан = 0°
// Края лепестка = -7.5° и +7.5°
const HALF_LON = 7.5;

// Масштаб по широте.
// Для плоской развёртки сферы используем
// истинную дугу меридиана:
// 90° = πR/2.
function Y(latDeg){
  return -R * latDeg * Math.PI / 180;
}

// Поперечная координата:
// x = R * sin(longitude) * cos(latitude)
function X(latDeg, lonDeg){
  const lat = latDeg * Math.PI / 180;
  const lon = lonDeg * Math.PI / 180;

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

function makePath(d, cls, parent){
  const p = document.createElementNS(NS,"path");
  p.setAttribute("d",d);
  p.setAttribute("class",cls);
  parent.appendChild(p);
  return p;
}

/*
====================================================
ПАРАЛЛЕЛИ КАЖДЫЕ 5°
====================================================
От -85° до +85°.
*/
for(let lat=-85; lat<=85; lat+=5){

  const y=Y(lat);

  const x1=X(lat,-HALF_LON);
  const x2=X(lat, HALF_LON);

  makePath(
    `M ${x1.toFixed(4)} ${y.toFixed(4)}
     L ${x2.toFixed(4)} ${y.toFixed(4)}`,
    "grid",
    grid
  );
}

/*
====================================================
МЕРИДИАНЫ
====================================================

15 минут = 3.75°
30 минут = 7.5°
45 минут = 11.25°

В пределах одного лепестка находятся:
- центральный меридиан 0°
- ±3.75° = четверть часа
- ±7.5° = границы лепестка

Но для удобства разметки внутри лепестка
рисуем также линии ±3.75°.
*/

/*
Центральный меридиан
*/
{
  let d="";

  for(let lat=-90;lat<=90;lat+=1){

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

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

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

/*
Меридианы ±15 минут
*/
for(const lon of [-3.75,3.75]){

  let d="";

  for(let lat=-90;lat<=90;lat+=1){

    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)} `;
  }

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

/*
====================================================
КРАЯ ЛЕПЕСТКА
====================================================
Края серые, 0.3 мм.
*/

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

  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)} `;
  }

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

/*
====================================================
ПОЛЮСА
====================================================
Добавляем короткие замыкающие дуги,
чтобы контур лепестка был замкнут.
*/

function poleEdge(lat){

  let d="";

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

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

    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)} `;
  }

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

poleEdge(90);
poleEdge(-90);

/*
====================================================
СКАЧИВАНИЕ SVG
====================================================
*/

document.getElementById("download").addEventListener("click",()=>{

  const clone=svg.cloneNode(true);

  const serializer=new XMLSerializer();
  let source=serializer.serializeToString(clone);

  source='<?xml version="1.0" encoding="UTF-8"?>\n'+source;

  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_zvezdnogo_globusa_1chas_1000mm.svg";

  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);

  setTimeout(()=>{
    URL.revokeObjectURL(url);
  },1000);

});
</script>

</body>
</html>