Simple script to generate moon phases ( https://en.wikipedia.org/wiki/Lunar_phase )
It uses 2 SVG (2 hemispheres) and some CSS transformation.
You can avoid JS if you don’t need real-time phase update.
HTML code
<div class="moon"> <svg height="200" width="100" class="moon-left"> <circle cx="100" cy="100" r="100" stroke="white" fill="white" class="bg"/> <circle cx="100" cy="100" r="100" stroke="white" fill="black" class="fg"/> </svg><svg height="200" width="100" class="moon-right"> <circle cx="0" cy="100" r="100" stroke="white" fill="white" class="bg"/> <circle cx="0" cy="100" r="100" stroke="white" fill="black" class="fg"/> </svg> <div id="phase"></div> </div>
CSS
html, body {width:100%;background-color:#333;margin:0;position:relative; font: 1em sans-serif;} .moon {width:200px;margin:2rem auto;} #phase {width:200px;margin:25px 0;} .moon-left,.moon-right {display:inline-block;width:100px;position:relative;margin:0;} .moon-left .bg,.moon-right .bg {stroke-width:2px;} .moon-right .fg {stroke-width:2px;} .moon-left .bg {fill:black;} .moon-left .fg {fill:white;transform-origin: 0% 0%;} .moon-right .fg {transform: scaleX(1);} .moon-left .fg {transform: scaleX(0) translateX(0);}
and JS code.ย The code is prolix and redundant, but it helps to understand what happens.
jQuery( "#phase" ).slider({ min: 0, max: 200, value: 2, step:10, slide: function( event, ui ) { updateMoon( ui.value ); } }); Math.radians = function(degrees) { return degrees * Math.PI / 180; }; function updateMoon(phase){ var phaseScale = 1, phaseTrans = 100, phaseRight = 0; if(phase <= 100) { phaseRight = (1-phase/100); } jQuery('.moon-right .fg').css({ 'transform':'scaleX(' + phaseRight + ')' }); if(phase >= 100) { phaseScale = (1-(phase-100)/100); phaseTrans = 100*phaseScale; } jQuery('.moon-left .fg').css({ 'transform':'translate('+phaseTrans+'px,0) scaleX(' + (1-phaseScale) + ')' }); }
and here the result JS/CSS Moon Phases