more consistent navigation control
This commit is contained in:
parent
1f688318b5
commit
9a09ccd1ea
|
@ -39,7 +39,7 @@ class CurrentWeather extends WeatherDisplay {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Unable to get current observations');
|
console.error('Unable to get current observations');
|
||||||
console.error(e);
|
console.error(e);
|
||||||
this.setStatus(STATUS.error);
|
this.setStatus(STATUS.failed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// we only get here if there was no error above
|
// we only get here if there was no error above
|
||||||
|
|
|
@ -35,12 +35,12 @@ class ExtendedForecast extends WeatherDisplay {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Unable to get extended forecast');
|
console.error('Unable to get extended forecast');
|
||||||
console.error(e);
|
console.error(e);
|
||||||
this.setStatus(STATUS.error);
|
this.setStatus(STATUS.failed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// we only get here if there was no error above
|
// we only get here if there was no error above
|
||||||
this.data = this.parseExtendedForecast(forecast.properties.periods);
|
this.data = this.parseExtendedForecast(forecast.properties.periods);
|
||||||
this.screnIndex = 0;
|
this.screenIndex = 0;
|
||||||
this.drawCanvas();
|
this.drawCanvas();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ const icons = (() => {
|
||||||
case 'tsra_hi':
|
case 'tsra_hi':
|
||||||
case 'tsra_hi-n':
|
case 'tsra_hi-n':
|
||||||
case 'hurricane':
|
case 'hurricane':
|
||||||
return addPath('CC_TStorm');
|
return addPath('CC_TStorm.gif');
|
||||||
|
|
||||||
case 'wind_few':
|
case 'wind_few':
|
||||||
case 'wind_sct':
|
case 'wind_sct':
|
||||||
|
|
|
@ -100,6 +100,7 @@ class LocalForecast extends WeatherDisplay {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`GetWeatherForecast failed: ${weatherParameters.forecast}`);
|
console.error(`GetWeatherForecast failed: ${weatherParameters.forecast}`);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
this.setStatus(STATUS.failed);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,29 @@ class Radar extends WeatherDisplay {
|
||||||
this.dopplerRadarImageMax = 6;
|
this.dopplerRadarImageMax = 6;
|
||||||
// update timing
|
// update timing
|
||||||
this.timing.baseDelay = 350;
|
this.timing.baseDelay = 350;
|
||||||
this.timing.delay = [4,1,1,1,1,1,12];
|
this.timing.delay = [
|
||||||
|
{time: 4, si: 0},
|
||||||
|
{time: 1, si: 1},
|
||||||
|
{time: 1, si: 2},
|
||||||
|
{time: 1, si: 3},
|
||||||
|
{time: 1, si: 4},
|
||||||
|
{time: 1, si: 5},
|
||||||
|
{time: 4, si: 6},
|
||||||
|
{time: 1, si: 0},
|
||||||
|
{time: 1, si: 1},
|
||||||
|
{time: 1, si: 2},
|
||||||
|
{time: 1, si: 3},
|
||||||
|
{time: 1, si: 4},
|
||||||
|
{time: 1, si: 5},
|
||||||
|
{time: 4, si: 6},
|
||||||
|
{time: 1, si: 0},
|
||||||
|
{time: 1, si: 1},
|
||||||
|
{time: 1, si: 2},
|
||||||
|
{time: 1, si: 3},
|
||||||
|
{time: 1, si: 4},
|
||||||
|
{time: 1, si: 5},
|
||||||
|
{time: 12, si: 6},
|
||||||
|
];
|
||||||
|
|
||||||
// pre-load background image (returns promise)
|
// pre-load background image (returns promise)
|
||||||
this.backgroundImage = utils.image.load('images/BackGround4_1.png');
|
this.backgroundImage = utils.image.load('images/BackGround4_1.png');
|
||||||
|
@ -47,7 +69,7 @@ class Radar extends WeatherDisplay {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Unable to get list of radars');
|
console.error('Unable to get list of radars');
|
||||||
console.error(e);
|
console.error(e);
|
||||||
this.setStatus(STATUS.error);
|
this.setStatus(STATUS.failed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +214,6 @@ class Radar extends WeatherDisplay {
|
||||||
this.data = radarInfo.map(radar=>radar.canvas);
|
this.data = radarInfo.map(radar=>radar.canvas);
|
||||||
|
|
||||||
this.times = radarInfo.map(radar=>radar.time);
|
this.times = radarInfo.map(radar=>radar.time);
|
||||||
this.drawCanvas();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async drawCanvas() {
|
async drawCanvas() {
|
||||||
|
|
|
@ -27,7 +27,7 @@ class WeatherDisplay {
|
||||||
delay: 1, // 1*1second = 1 second total display time
|
delay: 1, // 1*1second = 1 second total display time
|
||||||
};
|
};
|
||||||
this.navBaseCount = 0;
|
this.navBaseCount = 0;
|
||||||
this.screenIndex = 0;
|
this.screenIndex = -1; // special starting condition
|
||||||
|
|
||||||
this.setStatus(STATUS.loading);
|
this.setStatus(STATUS.loading);
|
||||||
this.createCanvas(elemId);
|
this.createCanvas(elemId);
|
||||||
|
@ -65,21 +65,8 @@ class WeatherDisplay {
|
||||||
// set status
|
// set status
|
||||||
this.setStatus(STATUS.loading);
|
this.setStatus(STATUS.loading);
|
||||||
|
|
||||||
// set up the timing delays
|
// recalculate navigation timing (in case it was modified in the constructor)
|
||||||
if (Array.isArray(this.timing.delay) && typeof this.timing.delay[0] === 'number') {
|
this.calcNavTiming();
|
||||||
// array is defined as how long each screen should be displayed. This needs to be converted into total time for use here
|
|
||||||
if (!this.timing.fullDelay) {
|
|
||||||
let sum = 0;
|
|
||||||
this.timing.fullDelay = this.timing.delay.map(val => {
|
|
||||||
const calc = sum + val;
|
|
||||||
sum += val;
|
|
||||||
return calc;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update total screens
|
|
||||||
if (Array.isArray(this.timing.delay)) this.timing.totalScreens = this.timing.delay.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drawCanvas() {
|
drawCanvas() {
|
||||||
|
@ -104,9 +91,7 @@ class WeatherDisplay {
|
||||||
// if (_ScrollText !== '') OkToDrawCustomScrollText = true;
|
// if (_ScrollText !== '') OkToDrawCustomScrollText = true;
|
||||||
if (this.elemId === 'almanac') OkToDrawNoaaImage = false;
|
if (this.elemId === 'almanac') OkToDrawNoaaImage = false;
|
||||||
if (this.elemId === 'travelForecast') OkToDrawNoaaImage = false;
|
if (this.elemId === 'travelForecast') OkToDrawNoaaImage = false;
|
||||||
if (this.elemId === 'regionalForecast0') OkToDrawNoaaImage = false;
|
if (this.elemId === 'regionalForecast') OkToDrawNoaaImage = false;
|
||||||
if (this.elemId === 'regionalForecast1') OkToDrawNoaaImage = false;
|
|
||||||
if (this.elemId === 'regionalForecast2') OkToDrawNoaaImage = false;
|
|
||||||
if (this.elemId === 'radar') {
|
if (this.elemId === 'radar') {
|
||||||
OkToDrawCurrentConditions = false;
|
OkToDrawCurrentConditions = false;
|
||||||
OkToDrawCurrentDateTime = false;
|
OkToDrawCurrentDateTime = false;
|
||||||
|
@ -228,12 +213,6 @@ class WeatherDisplay {
|
||||||
|
|
||||||
// reset timing
|
// reset timing
|
||||||
this.startNavCount(navigation.isPlaying());
|
this.startNavCount(navigation.isPlaying());
|
||||||
|
|
||||||
// if there was a command the canvas has already been drawn
|
|
||||||
if (navCmd) return;
|
|
||||||
|
|
||||||
// refresh the canvas (in case the screen index changed)
|
|
||||||
if (navCmd) this.drawCanvas();
|
|
||||||
}
|
}
|
||||||
hideCanvas() {
|
hideCanvas() {
|
||||||
this.stopNavBaseCount(true);
|
this.stopNavBaseCount(true);
|
||||||
|
@ -263,21 +242,70 @@ class WeatherDisplay {
|
||||||
// call base count change if available for this function
|
// call base count change if available for this function
|
||||||
if (this.baseCountChange) this.baseCountChange(this.navBaseCount);
|
if (this.baseCountChange) this.baseCountChange(this.navBaseCount);
|
||||||
|
|
||||||
// determine type of timing
|
// handle base count/screen index changes
|
||||||
// simple delay
|
this.updateScreenFromBaseCount();
|
||||||
if (typeof this.timing.delay === 'number') {
|
}
|
||||||
this.navNext();
|
|
||||||
|
updateScreenFromBaseCount() {
|
||||||
|
// get the next screen index
|
||||||
|
let nextScreenIndex = this.screenIndexFromBaseCount();
|
||||||
|
|
||||||
|
// special cases for first and last frame
|
||||||
|
// must compare with false as nextScreenIndex could be 0 which is valid
|
||||||
|
if (nextScreenIndex === false) {
|
||||||
|
this.sendNavDisplayMessage(navigation.msg.response.next);
|
||||||
|
this.stopNavBaseCount();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// array of timing integers
|
// test for no change and exit early
|
||||||
if (Array.isArray(this.timing.delay) && typeof this.timing.delay[0] === 'number') {
|
if (nextScreenIndex === this.screenIndex) return;
|
||||||
// scan the array for a matching number and calculate new screen index from the number
|
|
||||||
const timingMatch = this.timing.fullDelay.indexOf(this.navBaseCount);
|
this.screenIndex = nextScreenIndex;
|
||||||
// if not found return
|
|
||||||
if (timingMatch < 0 && this.navBaseCount <= this.timing.fullDelay[this.timing.totalScreens-1]) return;
|
// call the appropriate screen index change method
|
||||||
// navigate to the next screen
|
if (!this.screenIndexChange) {
|
||||||
this.navNext();
|
this.drawCanvas();
|
||||||
|
} else {
|
||||||
|
this.screenIndexChange(this.screenIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// take the three timing formats shown above and break them into arrays for consistent usage in navigation functions
|
||||||
|
// this.timing.fullDelay = [end of screen index 0 in base counts, end of screen index 1...]
|
||||||
|
// this.timing.screenIndexes = [screen index to use during this.timing.fullDelay[0], screen index to use during this.timing.fullDelay[1], ...]
|
||||||
|
calcNavTiming() {
|
||||||
|
// update total screens
|
||||||
|
if (Array.isArray(this.timing.delay)) this.timing.totalScreens = this.timing.delay.length;
|
||||||
|
|
||||||
|
// if the delay is provided as a single value, expand it to a series of the same value
|
||||||
|
let intermediateDelay = [];
|
||||||
|
if (typeof this.timing.delay === 'number') {
|
||||||
|
for (let i = 0; i < this.timing.totalScreens; i++) intermediateDelay.push(this.timing.delay);
|
||||||
|
} else {
|
||||||
|
// map just the delays to the intermediate block
|
||||||
|
intermediateDelay = this.timing.delay.map(delay => {
|
||||||
|
if (typeof delay === 'object') return delay.time;
|
||||||
|
return delay;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the cumulative end point of each delay
|
||||||
|
let sum = 0;
|
||||||
|
this.timing.fullDelay = intermediateDelay.map(val => {
|
||||||
|
const calc = sum + val;
|
||||||
|
sum += val;
|
||||||
|
return calc;
|
||||||
|
});
|
||||||
|
|
||||||
|
// generate a list of screen either sequentially if not provided in an object or from the object
|
||||||
|
if (Array.isArray(this.timing.delay) && typeof this.timing.delay[0] === 'object') {
|
||||||
|
// extract screen indexes from objects
|
||||||
|
this.timing.screenIndexes = this.timing.delay.map(delay => delay.si);
|
||||||
|
} else {
|
||||||
|
// generate sequential screen indexes
|
||||||
|
this.timing.screenIndexes = [];
|
||||||
|
for (let i = 0; i < this.timing.totalScreens; i++) this.timing.screenIndexes.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,62 +315,40 @@ class WeatherDisplay {
|
||||||
if (command === navigation.msg.command.firstFrame) {
|
if (command === navigation.msg.command.firstFrame) {
|
||||||
this.resetNavBaseCount();
|
this.resetNavBaseCount();
|
||||||
} else {
|
} else {
|
||||||
// increment screen index
|
// set the base count to the next available frame
|
||||||
this.screenIndex++;
|
const newBaseCount = this.timing.fullDelay.find(delay => delay > this.navBaseCount);
|
||||||
|
this.navBaseCount = newBaseCount;
|
||||||
}
|
}
|
||||||
// test for end reached
|
this.updateScreenFromBaseCount();
|
||||||
if (this.screenIndex >= this.timing.totalScreens) {
|
|
||||||
this.screenIndex = this.timing.totalScreens - 1;
|
|
||||||
this.sendNavDisplayMessage(navigation.msg.response.next);
|
|
||||||
this.stopNavBaseCount();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.baseCountFromScreenIndex();
|
|
||||||
// if the end was not reached, update the canvas (typical), or run a callback (atypical)
|
|
||||||
if (!this.screenIndexChange) {
|
|
||||||
this.drawCanvas();
|
|
||||||
} else {
|
|
||||||
this.screenIndexChange(this.screenIndex);
|
|
||||||
}
|
|
||||||
this.showCanvas();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// navigate to previous screen
|
// navigate to previous screen
|
||||||
navPrev(command) {
|
navPrev(command) {
|
||||||
// check for special 'last frame' command
|
// check for special 'last frame' command
|
||||||
if (command === navigation.msg.command.lastFrame) {
|
if (command === navigation.msg.command.lastFrame) {
|
||||||
this.screenIndex = this.timing.totalScreens-1;
|
this.navBaseCount = this.timing.fullDelay[this.timing.totalScreens-1]-1;
|
||||||
} else {
|
} else {
|
||||||
// decrement screen index
|
// find the highest fullDelay that is less than the current base count
|
||||||
this.screenIndex--;
|
const newBaseCount = this.timing.fullDelay.reduce((acc, delay) => {
|
||||||
|
if (delay < this.navBaseCount) return delay;
|
||||||
|
return acc;
|
||||||
|
},0);
|
||||||
|
// if the new base count is zero then we're already at the first screen
|
||||||
|
if (newBaseCount === 0 && this.navBaseCount === 0) {
|
||||||
|
this.sendNavDisplayMessage(navigation.msg.response.previous);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.navBaseCount = newBaseCount;
|
||||||
}
|
}
|
||||||
|
this.updateScreenFromBaseCount();
|
||||||
// test for end reached
|
|
||||||
if (this.screenIndex < 0) {
|
|
||||||
this.screenIndex = 0;
|
|
||||||
this.sendNavDisplayMessage(navigation.msg.response.previous);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.baseCountFromScreenIndex();
|
|
||||||
// if the end was not reached, update the canvas (typical), or run a callback (atypical)
|
|
||||||
if (!this.screenIndexChange) {
|
|
||||||
this.drawCanvas();
|
|
||||||
} else {
|
|
||||||
this.screenIndexChange(this.screenIndex);
|
|
||||||
}
|
|
||||||
this.showCanvas();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate a baseCount from the screen index for the array timings
|
// get the screen index for the current base count, returns false if past end of timing array (go to next screen, stop timing)
|
||||||
baseCountFromScreenIndex() {
|
screenIndexFromBaseCount() {
|
||||||
if (!Array.isArray(this.timing.delay)) return;
|
// find the first timing in the timing array that is greater than the base count
|
||||||
// first screen starts at zero
|
const timingIndex = this.timing.fullDelay.findIndex(delay => delay > this.navBaseCount);
|
||||||
if (this.screenIndex === 0) {
|
if (timingIndex === -1) return false;
|
||||||
this.navBaseCount = 0;
|
return this.timing.screenIndexes[timingIndex];
|
||||||
return;
|
|
||||||
}
|
|
||||||
// otherwise return one more than the previous sum
|
|
||||||
this.navBaseCount = this.timing.fullDelay[this.screenIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start and stop base counter
|
// start and stop base counter
|
||||||
|
@ -357,7 +363,7 @@ class WeatherDisplay {
|
||||||
}
|
}
|
||||||
resetNavBaseCount() {
|
resetNavBaseCount() {
|
||||||
this.navBaseCount = 0;
|
this.navBaseCount = 0;
|
||||||
this.screenIndex = 0;
|
this.screenIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendNavDisplayMessage(message) {
|
sendNavDisplayMessage(message) {
|
||||||
|
|
Loading…
Reference in a new issue