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.

246 lines
8.0 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_en: 'new moon', //not visible: not in nightsky, and in daysky it's the hidden side that's light up by the sun
name_fr: 'nouvelle lune',
name_nl: 'nieuwe maan',
name_es: 'luna nueva',
picto: '🌑',
},
{ name_en: 'waxing crescent', //in daysky, but a bit in the west: from late morning to post-dusk, not in nightsky
name_fr: 'premier croissant',
name_nl: 'jonge maansikkel',
name_es: 'creciente cóncava',
picto: '🌒',
},
{ name_en: 'first quarter', //at the west intersection of night and day skies -> begin to appear in night: afternoon to early evening
name_fr: 'premier quartier',
name_nl: 'eerste kwartier',
name_es: 'cuarto creciente',
picto: '🌓',
},
{ name_en: 'waxing gibbous', //in the nightsky, but a bit in the west: from late afternoon to most of the night
name_fr: 'gibbeuse croissante',
name_nl: 'wassende maan',
name_es: 'creciente gibosa',
picto: '🌔',
},
{ name_en: 'full moon', //all night: sunset to sunrise
name_fr: 'pleine lune',
name_nl: 'volle maan',
name_es: 'luna llena',
picto: '🌕',
},
{ name_en: 'waning gibbous', //in the nightsky, but a bit in the east: most of the night to early morning
name_fr: 'gibbeuse décroissante',
name_nl: 'krimpende maan',
name_es: 'menguante gibosa',
picto: '🌖',
},
{ name_en: 'last quarter', //at the east intersection of night and day skies -> begin to appear in day: late night to morning
name_fr: 'dernier quartier',
name_nl: 'laatste kwartier',
name_es: 'cuarto menguante',
picto: '🌗',
},
{ name_en: 'waning crescent', //in daysky, but a bit in the east: from pre-dawn to early afternoon, not in nightsky
name_fr: 'dernier croissant',
name_nl: 'krimpende maansikkel',
name_es: 'menguante cóncava',
picto: '🌘',
}
]
function getLocalFromURL(){
let local = "";
let url = window.location.href;
let filename = url.split("/").pop().split(".")[0];
let lang_split = filename.split("_");
if (lang_split.length == 1){
local = "en-gb";
}
else{
if (lang_split[1] == "fr"){
local = "fr-be";
}
else if (lang_split[1] == "nl"){
local = "nl-be";
}
else if (lang_split[1] == "es"){
local = "es-es";
}
}
return local;
}
// 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, lat=0, long=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, lat, long);
moon['distance'] = mooncalc_position.distance;
return moon;
}
function getSunStateFromDate(date, lat=0, long=0, timezone){
// --- get suncalc sun object
// for complementary info such as: sunset time
// Note: suncalc gives us sunset time as a date object
// meaning if we just print it it will print in local user time
// what we need to do:
// js sunset_time --> ISO string in UTC --> luxon sunset_time
// set proper timezone to luxon sunset_time
// print it in it's timezone
let sun_calc = SunCalc.getTimes(date, lat, long);
let sunrise = sun_calc["sunrise"];
let sunset = sun_calc["sunset"];
let offset_sunset = luxon.DateTime.fromISO(sunset.toISOString());
offset_sunset = offset_sunset.setZone(timezone);
let offset_sunrise = luxon.DateTime.fromISO(sunrise.toISOString());
offset_sunrise = offset_sunrise.setZone(timezone);
return [offset_sunrise, offset_sunset];
}
// 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);
$element.addClass("computed");
}
$(document).ready(function(){
window.current_local = getLocalFromURL();
});