JSFiddle - React, Tailwind, and code Playground

by rew222

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/suncalc/1.8.0/suncalc.min.js"></script>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Moon Phases SVG</title>
  </head>
<body>

  
<div>
<svg id="moon" width="100%" height="100%" viewBox="0 0 200 200">
  <defs>
    <filter id="blur">
      <feGaussianBlur in="SourceGraphic" stdDeviation="2" />
    </filter>
    <pattern id="moonTexture" patternUnits="objectBoundingBox" width="1" height="1">
      
     <image xlink:href="https://i.imgur.com/H38CJMA.jpg" x="-7" y="-7" width="200" height="200" preserveAspectRatio="xMidYMid slice" />
     <!--  <image width="200" height="200" preserveAspectRatio="xMidYMid slice" xlink:href="https://i.imgur.com/XIwmPPk.jpg"></image> -->
      
    </pattern>
  </defs>
  <g id="moonGroup" transform="rotate(0 100 100)">
    <circle cx="100" cy="100" r="80" />
    <path id="arcPath" class="shadow" d="" />
  </g>
</svg>
</div>
<div class="date-input">
	<input type="date" id="dateInput">
</div>
</body>
</html>

CSS

@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,900|Dosis:300,400,600,700,800|Finlandica:400|Droid+Sans:400,700|Lato:300,400,700,900|PT+Sans:400,700|Ubuntu:300,400,500,700|Open+Sans:400,300,600,700|Roboto:400,300,500,700,900|Roboto+Condensed:400,300,700|Atkinson+Hyperlegible:400|Open+Sans+Condensed:300,700|Mohave:400|Play:400,700|Maven+Pro:400,500,700,900&subset=latin,latin-ext);


#moon{
  height: 300px;
  width: 300px;
  background-image: url("https://i.imgur.com/Rg4CeGt.jpg");
}
svg {
  border: 5px solid green;
}
circle {
  fill: url(#moonTexture);
  stroke: darkgrey;
  stroke-width: 2;
}
path.shadow {
  fill: black;
  filter: url(#blur);
}

body{
  position: fixed;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  background-image: url("https://i.imgur.com/k7SRgZ4.jpg");
}

.date-input input[type="date"] {
  height: 30px;
  width: 150px;
  background-color: black;
  color: white;
  font-family: Finlandica;
  font-size: 1em;
  border: none;
  padding: 8px;
  border-radius: 4px;
}

JavaScript

const moon = document.getElementById('moon');
let arcPath = document.getElementById('arcPath');  
let moonGroup = document.getElementById('moonGroup');
const dateSelect = document.querySelector('input')

//Washington DC
const lat = 38.889805;
const lon = -77.009056;
const moonDate = new Date();

//Southern Hemisphere is Opposite
const phases = [
    {f1: "1 0", f2: "0 0", o: 0}, // Waxing Crescent
    {f1: "1 0", f2: "1 1", o: 0},// Waxing Gibbous
    {f1: "1 0", f2: "1 1", o: 270}, // Waning Gibbous
    {f1: "1 1", f2: "0 1", o: 90}, // Waning Crescent
 ];

// Function to calculate a custom path based on the moon's illumination fraction
function getCustomMoonPath(illuminationFraction, phase) {
  const r = 80; // Radius
  const cx = 100; // Center x
  const cy = 100; // Center y

  const angle = 2 * Math.PI * illuminationFraction;
  const x = cx + r * Math.cos(angle);
  const y = cy - r * Math.sin(angle);
  
  const flag1 = phases[phase].f1;
  const flag2 = phases[phase].f2;
  
  return `M ${cx},${cy - r} A ${r},${r} 0 ${flag1} ${cx},${cy + r} A ${r * (illuminationFraction * 2 - 1)},${r} 0 ${flag2} ${cx},${cy - r} Z`;
}

// Update the moon path based on the current illumination fraction
function updateMoonPath(mD) {
  let mC = SunCalc.getMoonIllumination(mD);
  let mP = SunCalc.getMoonPosition(mD, lat, lon);
  let mZ = SunCalc.getMoonTimes(mD, lat, lon);  // Just For Console Log
  let mT = ((mC.angle - mP.parallacticAngle) * (180/Math.PI)).toFixed(3); 
  let illumination = mC.fraction;
  
  let phase = Math.min(Math.floor((mC.phase) / .25), 3);
  let displayTilt = mT<0?phases[phase].o-Math.abs(mT):phases[phase].o-mT;

  let cP = getCustomMoonPath(illumination, phase);
  //console.log((mZ.set) ? (mZ.set).toLocaleTimeString('en-US') : "" );
  console.log("Date: "+ mD, "Phase: " + phase, "Illumination: " + mC.fraction , "Angle: " + mC.angle, "Parallactic Angle: " + mP.parallacticAngle, "Tilt: " + mT, "Display Tilt: " + displayTilt);
  console.log("Moon Rise: " +...