Moon Phase Simulator

Interactive Moon phase simulator.

Moon Phase Simulator

Moon Phase Simulator

New Moon
New Moon First Quarter Full Moon Last Quarter

About Moon Phases

The Moon completes a full orbit around Earth approximately every 29.5 days. As it orbits, the portion of the Moon that appears illuminated from Earth changes, creating the lunar phases we observe.

The phases occur because we see the portion of the Moon that’s illuminated by the Sun from different angles as the Moon orbits Earth.

Major phases:

  • New Moon: The Moon is between Earth and Sun, with its dark side facing us
  • Waxing Crescent: A small portion of the illuminated side becomes visible
  • First Quarter: Half of the Moon appears illuminated
  • Waxing Gibbous: More than half, but not all of the Moon is illuminated
  • Full Moon: The entire near side of the Moon is illuminated
  • Waning Gibbous: More than half, but decreasing
  • Last Quarter: Half of the Moon appears illuminated (opposite side from First Quarter)
  • Waning Crescent: A small crescent is visible, diminishing until the next New Moon
import { useState, useEffect } from 'react'; export default function MoonPhaseSimulator() { const [orbitalPosition, setOrbitalPosition] = useState(0); const [isAnimating, setIsAnimating] = useState(false); const [animationSpeed, setAnimationSpeed] = useState(1); useEffect(() => { let animationFrame; if (isAnimating) { const animate = () => { setOrbitalPosition(prev => (prev + 0.5 * animationSpeed) % 360); animationFrame = requestAnimationFrame(animate); }; animationFrame = requestAnimationFrame(animate); } return () => { if (animationFrame) { cancelAnimationFrame(animationFrame); } }; }, [isAnimating, animationSpeed]); const handleSliderChange = (e) => { setOrbitalPosition(parseFloat(e.target.value)); }; const toggleAnimation = () => { setIsAnimating(prev => !prev); }; const adjustSpeed = (newSpeed) => { setAnimationSpeed(newSpeed); }; // Calculate moon phase information const moonPhase = (() => { if (orbitalPosition >= 350 || orbitalPosition < 10) return "New Moon"; if (orbitalPosition >= 10 && orbitalPosition < 80) return "Waxing Crescent"; if (orbitalPosition >= 80 && orbitalPosition < 100) return "First Quarter"; if (orbitalPosition >= 100 && orbitalPosition < 170) return "Waxing Gibbous"; if (orbitalPosition >= 170 && orbitalPosition < 190) return "Full Moon"; if (orbitalPosition >= 190 && orbitalPosition < 260) return "Waning Gibbous"; if (orbitalPosition >= 260 && orbitalPosition < 280) return "Last Quarter"; if (orbitalPosition >= 280 && orbitalPosition < 350) return "Waning Crescent"; return "Unknown"; })(); // Calculate illumination percentage (simplified approximation) const illuminationPercentage = Math.abs(Math.sin((orbitalPosition * Math.PI) / 180)) * 100; return (

Moon Phase Simulator

{/* Main visualization area */}
{/* Sun (fixed light source) */}
{/* Earth */}
{/* Moon's orbit path */}
{/* Moon */}
{/* Moon base */}
{/* Moon shadow based on position */}
180 ? Math.min(100, Math.max(0, ((orbitalPosition - 180) / 180) * 100)) : Math.min(100, Math.max(0, (1 - orbitalPosition / 180) * 100))}% 0 0)` }}>
{/* Moon phase visualization */}

Current Moon Phase: {moonPhase}

{/* Moon base */}
{/* Moon shadow based on phase */}

Illumination: {illuminationPercentage.toFixed(1)}%

Orbit position: {orbitalPosition.toFixed(1)}°

{/* Controls */}
Speed:
); }