mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-17 09:09:30 -07:00
better startup play/stop handing
This commit is contained in:
@@ -44,7 +44,7 @@ class CurrentWeather extends WeatherDisplay {
|
||||
}
|
||||
// we only get here if there was no error above
|
||||
this.data = Object.assign({}, observations, {station: station});
|
||||
this.drawCanvas();
|
||||
this.setStatus(STATUS.loaded);
|
||||
}
|
||||
|
||||
async drawCanvas () {
|
||||
@@ -175,7 +175,6 @@ class CurrentWeather extends WeatherDisplay {
|
||||
}));
|
||||
|
||||
this.finishDraw();
|
||||
this.setStatus(STATUS.loaded);
|
||||
}
|
||||
|
||||
shortConditions(condition) {
|
||||
|
||||
@@ -41,8 +41,7 @@ class ExtendedForecast extends WeatherDisplay {
|
||||
// we only get here if there was no error above
|
||||
this.data = this.parseExtendedForecast(forecast.properties.periods);
|
||||
this.screenIndex = 0;
|
||||
this.drawCanvas();
|
||||
|
||||
this.setStatus(STATUS.loaded);
|
||||
}
|
||||
|
||||
// the api provides the forecast in 12 hour increments, flatten to day increments with high and low temperatures
|
||||
@@ -166,6 +165,5 @@ class ExtendedForecast extends WeatherDisplay {
|
||||
}));
|
||||
|
||||
this.finishDraw();
|
||||
this.setStatus(STATUS.loaded);
|
||||
}
|
||||
}
|
||||
@@ -55,8 +55,7 @@ class LatestObservations extends WeatherDisplay {
|
||||
this.setStatus(STATUS.noData);
|
||||
return;
|
||||
}
|
||||
|
||||
this.drawCanvas();
|
||||
this.setStatus(STATUS.loaded);
|
||||
}
|
||||
|
||||
async drawCanvas() {
|
||||
@@ -111,7 +110,6 @@ class LatestObservations extends WeatherDisplay {
|
||||
y += 40;
|
||||
});
|
||||
this.finishDraw();
|
||||
this.setStatus(STATUS.loaded);
|
||||
}
|
||||
|
||||
shortenCurrentConditions(condition) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
// navigation handles progress, next/previous and initial load messages from the parent frame
|
||||
/* globals utils, _StationInfo, STATUS */
|
||||
/* globals index, utils, _StationInfo, STATUS */
|
||||
/* globals CurrentWeather, LatestObservations, TravelForecast, RegionalForecast, LocalForecast, ExtendedForecast, Almanac, Radar, Progress */
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
@@ -15,7 +15,6 @@ const UNITS = {
|
||||
const navigation = (() => {
|
||||
let weatherParameters = {};
|
||||
let displays = [];
|
||||
let initialLoadDone = false;
|
||||
let currentUnits = UNITS.english;
|
||||
let playing = false;
|
||||
let progress;
|
||||
@@ -25,7 +24,6 @@ const navigation = (() => {
|
||||
};
|
||||
|
||||
const message = (data) => {
|
||||
|
||||
// dispatch event
|
||||
if (!data.type) return;
|
||||
switch (data.type) {
|
||||
@@ -48,14 +46,10 @@ const navigation = (() => {
|
||||
};
|
||||
|
||||
const postMessage = (type, message = {}) => {
|
||||
const parent = window.parent;
|
||||
parent.postMessage(JSON.stringify({type, message}, window.location.origin));
|
||||
index.message({type, message});
|
||||
};
|
||||
|
||||
const getWeather = async (latLon) => {
|
||||
// reset statuses
|
||||
initialLoadDone = false;
|
||||
|
||||
// get initial weather data
|
||||
const point = await utils.weather.getPoint(latLon.lat, latLon.lon);
|
||||
|
||||
@@ -93,6 +87,11 @@ const navigation = (() => {
|
||||
// update the main process for display purposes
|
||||
postMessage('weatherParameters', weatherParameters);
|
||||
|
||||
// draw the progress canvas
|
||||
progress = new Progress(-1,'progress');
|
||||
await progress.drawCanvas();
|
||||
progress.showCanvas();
|
||||
|
||||
// start loading canvases if necessary
|
||||
if (displays.length === 0) {
|
||||
displays = [
|
||||
@@ -114,25 +113,21 @@ const navigation = (() => {
|
||||
// ShowDopplerMap(this.weatherParameters);
|
||||
// GetWeatherHazards3(this.weatherParameters);
|
||||
|
||||
// draw the progress canvas
|
||||
progress = new Progress(-1,'progress');
|
||||
progress.drawCanvas();
|
||||
progress.showCanvas();
|
||||
};
|
||||
|
||||
// receive a status update from a module {id, value}
|
||||
const updateStatus = (value) => {
|
||||
// skip if initial load
|
||||
if (initialLoadDone) return;
|
||||
// test for loaded status
|
||||
if (value.status !== STATUS.loaded) return;
|
||||
|
||||
if (value.id < 0) return;
|
||||
progress.drawCanvas(displays, countLoadedCanvases());
|
||||
|
||||
// if this is the first display and we're playing, load it up so it starts playing
|
||||
if (isPlaying() && value.id === 0 && value.status === STATUS.loaded) {
|
||||
navTo(msg.command.firstFrame);
|
||||
}
|
||||
|
||||
// send loaded messaged to parent
|
||||
if (countLoadedCanvases() < displays.length) return;
|
||||
postMessage('loaded');
|
||||
// store the display number
|
||||
};
|
||||
|
||||
const countLoadedCanvases = () => displays.reduce((acc, display) => {
|
||||
@@ -183,9 +178,9 @@ const navigation = (() => {
|
||||
const navTo = (direction) => {
|
||||
// test for a current display
|
||||
const current = currentDisplay();
|
||||
progress.hideCanvas();
|
||||
if (!current) {
|
||||
// special case for no active displays (typically on progress screen)
|
||||
progress.hideCanvas();
|
||||
displays[0].navNext(msg.command.firstFrame);
|
||||
return;
|
||||
}
|
||||
@@ -223,14 +218,23 @@ const navigation = (() => {
|
||||
const setPlaying = (newValue) => {
|
||||
playing = newValue;
|
||||
postMessage('isPlaying', playing);
|
||||
// if we're playing and on the progress screen jump to the next screen
|
||||
if (!progress) return;
|
||||
if (playing && !currentDisplay()) navTo(msg.command.firstFrame);
|
||||
};
|
||||
|
||||
// handle all navigation buttons
|
||||
const handleNavButton = (button) => {
|
||||
switch (button) {
|
||||
case 'play':
|
||||
setPlaying(true);
|
||||
break;
|
||||
case 'playToggle':
|
||||
setPlaying(!playing);
|
||||
break;
|
||||
case 'stop':
|
||||
setPlaying(false);
|
||||
break;
|
||||
case 'next':
|
||||
setPlaying(false);
|
||||
navTo(msg.command.nextFrame);
|
||||
|
||||
@@ -95,12 +95,13 @@ class Progress extends WeatherDisplay {
|
||||
canvasClick(e) {
|
||||
const x = e.offsetX;
|
||||
const y = e.offsetY;
|
||||
console.log(x,y);
|
||||
// eliminate off canvas and outside area clicks
|
||||
if (!this.isActive()) return;
|
||||
if (y < 100 || y > 410) return;
|
||||
if (x < 440 || x > 570) return;
|
||||
|
||||
// stop playing
|
||||
navigation.message('navButton', stop);
|
||||
// use the y value to determine an index
|
||||
const index = Math.floor((y-100)/29);
|
||||
const display = navigation.getDisplay(index);
|
||||
|
||||
@@ -67,14 +67,11 @@ class TravelForecast extends WeatherDisplay {
|
||||
return;
|
||||
}
|
||||
|
||||
this.drawCanvas(true);
|
||||
this.setStatus(STATUS.loaded);
|
||||
this.drawLongCanvas();
|
||||
}
|
||||
|
||||
async drawCanvas(newData) {
|
||||
// there are technically 2 canvases: the standard canvas and the extra-long canvas that contains the complete
|
||||
// list of cities. The second canvas is copied into the standard canvas to create the scroll
|
||||
super.drawCanvas();
|
||||
|
||||
async drawLongCanvas () {
|
||||
// create the "long" canvas if necessary
|
||||
if (!this.longCanvas) {
|
||||
this.longCanvas = document.createElement('canvas');
|
||||
@@ -85,61 +82,67 @@ class TravelForecast extends WeatherDisplay {
|
||||
// set up variables
|
||||
const cities = this.data;
|
||||
|
||||
// draw the long canvas only if there is new data
|
||||
if (newData) {
|
||||
this.longContext.clearRect(0,0,this.longCanvas.width,this.longCanvas.height);
|
||||
this.longContext.clearRect(0,0,this.longCanvas.width,this.longCanvas.height);
|
||||
|
||||
// draw the "long" canvas with all cities
|
||||
draw.box(this.longContext, 'rgb(35, 50, 112)', 0, 0, 640, _TravelCities.length*this.cityHeight);
|
||||
// draw the "long" canvas with all cities
|
||||
draw.box(this.longContext, 'rgb(35, 50, 112)', 0, 0, 640, _TravelCities.length*this.cityHeight);
|
||||
|
||||
for (let i = 0; i <= 4; i++) {
|
||||
const y = i * 346;
|
||||
draw.horizontalGradient(this.longContext, 0, y, 640, y + 346, '#102080', '#001040');
|
||||
}
|
||||
for (let i = 0; i <= 4; i++) {
|
||||
const y = i * 346;
|
||||
draw.horizontalGradient(this.longContext, 0, y, 640, y + 346, '#102080', '#001040');
|
||||
}
|
||||
|
||||
await Promise.all(cities.map(async (city, index) => {
|
||||
await Promise.all(cities.map(async (city, index) => {
|
||||
// calculate base y value
|
||||
const y = 50+this.cityHeight*index;
|
||||
const y = 50+this.cityHeight*index;
|
||||
|
||||
// city name
|
||||
draw.text(this.longContext, 'Star4000 Large Compressed', '24pt', '#FFFF00', 80, y, city.name, 2);
|
||||
// city name
|
||||
draw.text(this.longContext, 'Star4000 Large Compressed', '24pt', '#FFFF00', 80, y, city.name, 2);
|
||||
|
||||
// check for forecast data
|
||||
if (city.icon) {
|
||||
// check for forecast data
|
||||
if (city.icon) {
|
||||
// get temperatures and convert if necessary
|
||||
let {low, high} = city;
|
||||
let {low, high} = city;
|
||||
|
||||
if (navigation.units() === UNITS.metric) {
|
||||
low = utils.units.fahrenheitToCelsius(low);
|
||||
high = utils.units.fahrenheitToCelsius(high);
|
||||
}
|
||||
|
||||
// convert to strings with no decimal
|
||||
const lowString = Math.round(low).toString();
|
||||
const highString = Math.round(high).toString();
|
||||
|
||||
const xLow = (500 - (lowString.length * 20));
|
||||
draw.text(this.longContext, 'Star4000 Large', '24pt', '#FFFF00', xLow, y, lowString, 2);
|
||||
|
||||
const xHigh = (560 - (highString.length * 20));
|
||||
draw.text(this.longContext, 'Star4000 Large', '24pt', '#FFFF00', xHigh, y, highString, 2);
|
||||
|
||||
this.gifs.push(await utils.image.superGifAsync({
|
||||
src: city.icon,
|
||||
loop_delay: 100,
|
||||
auto_play: true,
|
||||
canvas: this.longCanvas,
|
||||
x: 330,
|
||||
y: y - 35,
|
||||
max_width: 47,
|
||||
}));
|
||||
} else {
|
||||
draw.text(this.longContext, 'Star4000 Small', '24pt', '#FFFFFF', 400, y - 18, 'NO TRAVEL', 2);
|
||||
draw.text(this.longContext, 'Star4000 Small', '24pt', '#FFFFFF', 400, y, 'DATA AVAILABLE', 2);
|
||||
if (navigation.units() === UNITS.metric) {
|
||||
low = utils.units.fahrenheitToCelsius(low);
|
||||
high = utils.units.fahrenheitToCelsius(high);
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
// convert to strings with no decimal
|
||||
const lowString = Math.round(low).toString();
|
||||
const highString = Math.round(high).toString();
|
||||
|
||||
const xLow = (500 - (lowString.length * 20));
|
||||
draw.text(this.longContext, 'Star4000 Large', '24pt', '#FFFF00', xLow, y, lowString, 2);
|
||||
|
||||
const xHigh = (560 - (highString.length * 20));
|
||||
draw.text(this.longContext, 'Star4000 Large', '24pt', '#FFFF00', xHigh, y, highString, 2);
|
||||
|
||||
this.gifs.push(await utils.image.superGifAsync({
|
||||
src: city.icon,
|
||||
loop_delay: 100,
|
||||
auto_play: true,
|
||||
canvas: this.longCanvas,
|
||||
x: 330,
|
||||
y: y - 35,
|
||||
max_width: 47,
|
||||
}));
|
||||
} else {
|
||||
draw.text(this.longContext, 'Star4000 Small', '24pt', '#FFFFFF', 400, y - 18, 'NO TRAVEL', 2);
|
||||
draw.text(this.longContext, 'Star4000 Small', '24pt', '#FFFFFF', 400, y, 'DATA AVAILABLE', 2);
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
async drawCanvas() {
|
||||
// there are technically 2 canvases: the standard canvas and the extra-long canvas that contains the complete
|
||||
// list of cities. The second canvas is copied into the standard canvas to create the scroll
|
||||
super.drawCanvas();
|
||||
|
||||
// set up variables
|
||||
const cities = this.data;
|
||||
|
||||
// draw the standard context
|
||||
this.context.drawImage(await this.backgroundImage, 0, 0);
|
||||
@@ -155,7 +158,12 @@ class TravelForecast extends WeatherDisplay {
|
||||
this.context.drawImage(this.longCanvas, 0, 0, 640, 289, 0, 110, 640, 289);
|
||||
|
||||
this.finishDraw();
|
||||
this.setStatus(STATUS.loaded);
|
||||
}
|
||||
|
||||
async showCanvas() {
|
||||
// special to travel forecast to draw the remainder of the canvas
|
||||
await this.drawCanvas();
|
||||
super.showCanvas();
|
||||
}
|
||||
|
||||
// screen index change callback just runs the base count callback
|
||||
|
||||
@@ -225,6 +225,10 @@ class WeatherDisplay {
|
||||
return document.getElementById(this.elemId+'Canvas').offsetParent !== null;
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// navigation timings
|
||||
// totalScreens = total number of screens that are available
|
||||
// baseDelay = ms to delay before re-evaluating screenIndex
|
||||
@@ -246,7 +250,7 @@ class WeatherDisplay {
|
||||
this.updateScreenFromBaseCount();
|
||||
}
|
||||
|
||||
updateScreenFromBaseCount() {
|
||||
async updateScreenFromBaseCount() {
|
||||
// get the next screen index
|
||||
let nextScreenIndex = this.screenIndexFromBaseCount();
|
||||
|
||||
@@ -261,11 +265,17 @@ class WeatherDisplay {
|
||||
// test for no change and exit early
|
||||
if (nextScreenIndex === this.screenIndex) return;
|
||||
|
||||
this.screenIndex = nextScreenIndex;
|
||||
// test for -1 (no screen displayed yet)
|
||||
if (nextScreenIndex === -1) {
|
||||
this.screenIndex = 0;
|
||||
} else {
|
||||
this.screenIndex = nextScreenIndex;
|
||||
}
|
||||
|
||||
// call the appropriate screen index change method
|
||||
if (!this.screenIndexChange) {
|
||||
this.drawCanvas();
|
||||
await this.drawCanvas();
|
||||
this.showCanvas();
|
||||
} else {
|
||||
this.screenIndexChange(this.screenIndex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user