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.
wubloader/thrimbletrimmer/driveclock/drive.js

123 lines
3.2 KiB
JavaScript

const PAGE_WIDTH = 1920;
const MINUTES_PER_PAGE = 60;
const POINT_WIDTH = PAGE_WIDTH * 8 * 60 / MINUTES_PER_PAGE;
const MILES_PER_PAGE = 45;
const BUS_POSITION_X = 93;
const BASE_ODO = 109.3;
const UPDATE_INTERVAL_MS = 5000
const WUBLOADER_URL = "";
const SKY_URLS = {
day: "db_day.png",
dawn: "db_dawn.png",
dusk: "db_dusk.png",
night: "db_night.png",
};
const BUS_URLS = {
day: "bus_day.png",
dawn: "bus_day.png",
dusk: "bus_day.png",
night: "bus_night.png",
};
function setSkyElements(left, right, timeToTransition) {
const leftElement = document.getElementById("sky-left");
const rightElement = document.getElementById("sky-right");
const busElement = document.getElementById("bus");
leftElement.style.backgroundImage = `url(${SKY_URLS[left]})`;
rightElement.style.backgroundImage = `url(${SKY_URLS[right]})`;
if (left === right) {
leftElement.style.width = "100%";
} else {
const transitionPercent = timeToTransition / MINUTES_PER_PAGE;
leftElement.style.width = `${transitionPercent * 100}%`
}
bus.style.backgroundImage = `url(${BUS_URLS[left]})`;
}
function nextSkyTransition(timeofday, clock) {
switch (timeofday) {
case "dawn":
case "day":
return [19 * 60, "dusk"]; // 7pm
case "dusk":
return [20 * 60, "night"]; // 8pm
case "night":
return [6 * 60 + 40, "dawn"]; // 6:40am
}
}
function setSky(timeofday, clock) {
const [transition, newSky] = nextSkyTransition(timeofday, clock);
// 1440 minutes in 24h, this code will return time remaining even if
// the transition is in the morning and we're currently in the evening.
const timeToTransition = (1440 + transition - clock) % 1440;
if (timeToTransition < MINUTES_PER_PAGE) {
// Transition on screen
setSkyElements(timeofday, newSky, timeToTransition);
} else {
// No transition on screen
setSkyElements(timeofday, timeofday, undefined);
}
}
function setOdo(odo) {
const distancePixels = PAGE_WIDTH * (odo - BASE_ODO) / MILES_PER_PAGE;
const offset = (BUS_POSITION_X - distancePixels) % POINT_WIDTH;
const stopsElement = document.getElementById("stops");
stopsElement.style.backgroundPosition = `${offset}px 0px`;
}
async function update() {
const busDataResponse = await fetch(`${WUBLOADER_URL}/thrimshim/bus/buscam`);
if (!busDataResponse.ok) {
return;
}
const busData = await busDataResponse.json();
console.log("Got data:", busData);
setOdo(busData.odometer);
setSky(busData.timeofday, busData.clock_minutes);
}
// Initial conditions, before the first refresh finishes
setSky("day", 7 * 60);
setOdo(BASE_ODO);
// Testing mode. Set true to enable.
const test = false;
if (test) {
let h = 0;
// Set to how long 1h of in-game time should take in real time
const hourTimeMs = 1 * 1000;
// Set to how often to update the screen
const interval = 30;
setInterval(() => {
h += interval / hourTimeMs;
setOdo(BASE_ODO + 45 * h);
if (h < 19) {
setSky("day", 60 * h);
} else {
m = (h % 24) * 60;
let tod;
if (m < 6 * 60 + 40) {
tod = "night";
} else if (m < 19 * 60) {
tod = "dawn";
} else if (m < 20 * 60) {
tod = "dusk";
} else {
tod = "night";
}
setSky(tod, m);
}
}, interval);
} else {
// Do first update immediately, then every UPDATE_INTERVAL_MS
setInterval(update, UPDATE_INTERVAL_MS);
update();
}