You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.9 KiB
JavaScript

// 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);
}