3

I am looking for method / npm package which can achieve :

  1. Moon phase
  2. SVG or any graphical representation of moon phase
  3. Illumination for that date

I have tried : suncalc but in this package SunCalc.getMoonIllumination() satisfies illumination and phase but from phase saying if it's full moon or not is tricky. and it doesn't have graphical representation.

Dhaval Chaudhary
  • 5,428
  • 2
  • 24
  • 39
  • You will probably need to find/create your own moon graphics – coagmano Feb 28 '18 at 23:26
  • @FredStark ok i can go for my own graphics but again the phases i am getting from here : https://github.com/mourner/suncalc#moon-illumination are never exact 0.5 for full moon or 0.75 so i am always getting intermediate stages. what i can do about that? i mean any roundof technique? – Dhaval Chaudhary Mar 01 '18 at 04:41
  • Does this work `Math.round(SunCalc.getMoonIllumination(new Date()).phase * 4) / 4`? – coagmano Mar 01 '18 at 05:25
  • https://runkit.com/embed/i08xwuhsax8h – coagmano Mar 01 '18 at 05:28
  • @FredStark if you go by that approach 0.6262591729500427 is converted to 0.75 which is last quarter but it should have been Waning Gibbous. – Dhaval Chaudhary Mar 01 '18 at 07:59
  • Oh I thought you meant you wanted to round to the nearest .25. You can round to the nearest 28th? Then you get 0, .25, .5, .75 for a day each `Math.round(SunCalc.getMoonIllumination(date).phase * 28) / 28` – coagmano Mar 01 '18 at 08:20
  • 1
    https://runkit.com/coagmano/runkit-npm-suncalc-moonillumination – coagmano Mar 01 '18 at 08:29
  • @FredStark thank you so much this works. but can you explain a bit why 28 worked? and it would be great if you put it as answer :) – Dhaval Chaudhary Mar 01 '18 at 08:50
  • 1
    Not sure about my formatting, but hopefully I've answered your questions :) – coagmano Mar 01 '18 at 09:09

1 Answers1

4

I don't think there are packages that come with SVGs, so you will need to source / produce those yourself.

As for getting SunCalc to give you a nice number for the phase that actually sits on 0, 0.25, 0.5, or 0.75 for a bit, the easiest is to do some rounding:

If you want to round directly to those numbers, you can round to the nearest quarter:

var date = new Date();
Math.round(SunCalc.getMoonIllumination(date).phase * 4) / 4;

Or (as you specified in comments) if you want it to still go through the waxing/waning sections and stick to Full Moon / New Moon / Quarters for around about a day, you can round to the nearest 28th:

var date = new Date();
Math.round(SunCalc.getMoonIllumination(date).phase * 28) / 28;

Why does this work? and why 28?

So the simplest way to explain is to look at the quarters example again. We want the rounded number to match one of the options (0, 0.25, 0.5, 0.75).

Because Math.round, rounds to the nearest integer, we want these results to become integers we can round to. By multiplying them by 4 we get:

0    * 4 = 0
0.25 * 4 = 1
0.5  * 4 = 2
0.75 * 4 = 3

Everything we get in between these ends up rounding to one of them (except some round to 5, which we would need to wrap around ourselves).

Then we divide the result by the same multiplier to get the numbers back in the expected range.

Now 28 works because for two reasons:

  1. 4 is a factor of 28. So some numbers will come back as multiples of .25
  2. Because it is close to the length of the lunar cycle (~29.53) in days

This means that we end up with the result rounding to each value for approximately a day

coagmano
  • 5,542
  • 1
  • 28
  • 41
  • thank you this pretty much explain what all i need. but just 1 last question getMoonIllumination function takes date and time so which time of the day i should pass current or any specific(this is for more accuracy may be)? – Dhaval Chaudhary Mar 01 '18 at 09:15
  • You'll just have to test which works best for you. You might need to take a look at how timezones affect the result as well – coagmano Mar 01 '18 at 09:18
  • Np :D Thank you so much! you saved my day :) – Dhaval Chaudhary Mar 01 '18 at 09:32