// utilities function used for both the watch and the calendar // MOONPHASES PICTO // ============================================================================ //shapes of the moon from north hemispheres //otherwise the picto are left-right inversed (and at the equator the crescent are in the bottom-top direction) const MOONPHASES = [ { name: 'new moon', //not visible: not in nightsky, and in daysky it's the hidden side that's light up by the sun picto: '🌑', }, { name: 'waxing crescent', //in daysky, but a bit in the west: from late morning to post-dusk, not in nightsky picto: '🌒', }, { name: 'first quarter', //at the west intersection of night and day skies -> begin to appear in night: afternoon to early evening picto: '🌓', }, { name: 'waxing gibbous', //in the nightsky, but a bit in the west: from late afternoon to most of the night picto: '🌔', }, { name: 'full moon', //all night: sunset to sunrise picto: '🌕', }, { name: 'waning gibbous', //in the nightsky, but a bit in the east: most of the night to early morning picto: '🌖', }, { name: 'last quarter', //at the east intersection of night and day skies -> begin to appear in day: late night to morning picto: '🌗', }, { name: 'waning crescent', //in daysky, but a bit in the east: from pre-dawn to early afternoon, not in nightsky picto: '🌘', } ] // JS DATE FORMATING // ============================================================================ function format_date_time(date){ // format date object everywhere the same on the website formated_date = {} formated_date['day'] = new Intl.DateTimeFormat('en-GB', { weekday: 'long' }).format(date); // formated_date['date'] = new Intl.DateTimeFormat('fr-BE', { // day: 'numeric', // month: 'numeric', // year: 'numeric' // }).format(date); formated_date['date'] = { day: ('0' + date.getDate()).slice(-2), month: ('0' + String(date.getMonth()+1)).slice(-2), year: date.getFullYear().toString().slice(-2) } formated_date['date'] = Object.values(formated_date['date']).join("."); formated_date['time'] = new Intl.DateTimeFormat('fr-BE', { // timeStyle: 'long' timeStyle: 'short' }).format(date); return formated_date; } function format_luxon_date(date){ formated_date = {}; date = date.setLocale(window.current_local); // date = date.setLocale('en-gb'); // date = date.setLocale('fr-be'); // date = date.setLocale('sp'); // date = date.setLocale('nl-be'); formated_date['day'] = date.toLocaleString({weekday: 'long'}); formated_date['date'] = date.toLocaleString({month: '2-digit', day: '2-digit', year: '2-digit'}); formated_date['time'] = date.toLocaleString({timeStyle: 'short'}); // for stylistic purposes formated_date['date'] = formated_date['date'].split("/").join("."); return formated_date; } // MOON COMPUTATION // ============================================================================ // average length of a lunation const LUNATION = 29.53058770576; // eps is the little interval around singular event to consider them as short period // otherwise we will never show "full moon" for example // 0.5, means we show "full moon" 12h before and 12h after the exact event const EPS = 0.5 / LUNATION; function getMoonDataFromPhase(phase){ // take a 0 ot 1 number and return an object with all data for display if (phase < EPS) return MOONPHASES[0]; else if(phase < 0.25 - EPS) return MOONPHASES[1]; else if(phase < 0.25 + EPS) return MOONPHASES[2]; else if(phase < 0.5 - EPS) return MOONPHASES[3]; else if(phase < 0.5 + EPS) return MOONPHASES[4]; else if(phase < 0.75 - EPS) return MOONPHASES[5]; else if(phase < 0.75 + EPS) return MOONPHASES[6]; else if(phase < 1 - EPS) return MOONPHASES[7]; else return MOONPHASES[0]; } function getMoonStateFromDate(date, latitude=0, longitude=0){ // return a moon object containing everything that we need let mooncalc_illumination = SunCalc.getMoonIllumination(date); let moon = getMoonDataFromPhase(mooncalc_illumination.phase); moon['illumination'] = mooncalc_illumination.fraction; moon['phase'] = mooncalc_illumination.phase; /* TODO: those data depend of the location on earth!! lat and lon to precise */ let mooncalc_position = SunCalc.getMoonPosition(date, latitude, longitude); moon['distance'] = mooncalc_position.distance; return moon; } // PHASE TO TYPO // ============================================================================ function mapValue(value, min, max, new_min, new_max){ return (((value - min) / (max - min)) * (new_max - new_min)) + new_min; } function getCircle(value){ // return a (x, y) tuple describing a circle of radius 1 at (0,0) // value goes from 0 to 1 // with i=0 being the top pole, and i=0.5 is the bottom pole let theta = value * 2 * Math.PI; let x = Math.sin(theta); let y = Math.cos(theta); // console.log(i, x, y); // NOTE: at i=0.5 we should have x=0 and y = -1, 7 // but we get a js rounding error for x return [x,y]; } function updateAxis($element, value, secondAxis=true){ // take a jquery element and a value from 0 to 1 // and write the css line to update the two variable font axis // OLD CODE for losange // 0 at new moon, 1 at full moon // let x = (Math.abs(i - 0.5) * -2) + 1; // 1 at first quart and last quarter, 0 at new and full moon // let y = (Math.abs(x - 0.5) * -2) + 1; let [x, y] = getCircle(value); // let weight = mapValue(x, 0, 1, 100, 500); // let wght = '"wght" ' + weight; // let slant = mapValue(y, 0, 1, 0, -10); // let slnt = '"slnt" ' + slant; let axis_1 = '"SERI" ' + mapValue(y, -1, 1, 100, 0); let axis_2 = '"slnt" ' + mapValue(x, -1, 1, -100, 100); let settings = secondAxis ? axis_1 + ", " + axis_2 : axis_1; $element.css("font-variation-settings", settings); }