LiveAtlas/src/leaflet/control/ClockControl.ts
2020-12-10 02:22:29 +00:00

106 lines
3.3 KiB
TypeScript

import L, {ControlOptions} from 'leaflet';
import Util from '@/util';
import {DynmapWorldState} from "@/dynmap";
export interface ClockControlOptions extends ControlOptions {
showDigitalClock: boolean;
showWeather: boolean;
}
export class ClockControl extends L.Control {
// @ts-ignore
options: ClockControlOptions;
private _map ?: L.Map;
private _container?: HTMLElement;
private _sun?: HTMLElement;
private _moon?: HTMLElement;
private _clock?: HTMLElement;
private _weather?: HTMLElement;
constructor(options: ClockControlOptions) {
super(options);
options.position = 'topleft';
L.Util.setOptions(this, options);
}
onAdd(map: L.Map) {
this._container = L.DomUtil.create('div', 'largeclock timeofday');
this._sun = L.DomUtil.create('div', 'timeofday sun', this._container);
this._moon = L.DomUtil.create('div', 'timeofday moon', this._sun);
this._sun.style.backgroundPosition = (-150) + 'px ' + (-150) + 'px';
this._moon.style.backgroundPosition = (-150) + 'px ' + (-150) + 'px';
if (this.options.showDigitalClock) {
this._clock = L.DomUtil.create('div', 'timeofday digitalclock', this._container)
}
if (this.options.showWeather) {
this._weather = L.DomUtil.create('div', 'weather', this._container)
}
return this._container;
}
update(worldState: DynmapWorldState) {
const timeOfDay = worldState.timeOfDay;
let sunAngle;
if (timeOfDay > 23100 || timeOfDay < 12900) {
//day mode
let movedTime = timeOfDay + 900;
movedTime = (movedTime >= 24000) ? movedTime - 24000 : movedTime;
//Now we have 0 -> 13800 for the day period
//Divide by 13800*2=27600 instead of 24000 to compress day
sunAngle = ((movedTime) / 27600 * 2 * Math.PI);
} else {
//night mode
const movedTime = timeOfDay - 12900;
//Now we have 0 -> 10200 for the night period
//Divide by 10200*2=20400 instead of 24000 to expand night
sunAngle = Math.PI + ((movedTime) / 20400 * 2 * Math.PI);
}
const moonAngle = sunAngle + Math.PI;
if (timeOfDay >= 0) {
this._sun!.style.backgroundPosition = (-50 * Math.cos(sunAngle)) + 'px ' + (-50 * Math.sin(sunAngle)) + 'px';
this._moon!.style.backgroundPosition = (-50 * Math.cos(moonAngle)) + 'px ' + (-50 * Math.sin(moonAngle)) + 'px';
} else {
this._sun!.style.backgroundPosition = '-150px -150px';
this._moon!.style.backgroundPosition = '-150px -150px';
}
const minecraftTime = Util.getMinecraftTime(timeOfDay);
if(timeOfDay >= 0) {
this._clock!.classList.remove(minecraftTime.night ? 'day' : 'night');
this._clock!.classList.add(minecraftTime.day ? 'day' : 'night');
this._clock!.textContent = [
minecraftTime.hours.toString().padStart(2, '0'),
minecraftTime.minutes.toString().padStart(2, '0')
].join(':');
} else {
this._clock!.classList.remove(minecraftTime.night ? 'day' : 'night');
this._clock!.textContent = '';
}
if(this.options.showWeather) {
const dayNight = (timeOfDay > 23100 || timeOfDay < 12900) ? "day" : "night";
let className = 'sunny';
if (worldState.raining) {
className = 'stormy';
if (worldState.thundering) {
className = 'thunder';
}
}
this._weather?.classList.remove('stormy_day', 'stormy_night', 'sunny_day', 'sunny_night', 'thunder_day', 'thunder_night');
this._weather?.classList.add(`${className}_${dayNight}`);
}
}
}