2020-09-04 18:02:20 +00:00
|
|
|
/* globals _StationInfo, luxon, _RegionalCities, utils, icons, _TravelCities, SunCalc */
|
|
|
|
const {DateTime} = luxon;
|
|
|
|
const _DayShortNames = { 'Sunday': 'Sun', 'Monday': 'Mon', 'Tuesday': 'Tue', 'Wednesday': 'Wed', 'Thursday': 'Thu', 'Friday': 'Fri', 'Saturday': 'Sat' };
|
|
|
|
const _DayLongNameArray = Object.keys(_DayShortNames);
|
|
|
|
const _DayLongNames = { 'Sun': 'Sunday', 'Mon': 'Monday', 'Tue': 'Tuesday', 'Wed': 'Wednesday', 'Thu': 'Thursday', 'Fri': 'Friday', 'Sat': 'Saturday' };
|
|
|
|
const _MonthLongNames = { 'Jan': 'January', 'Feb': 'February', 'Mar': 'March', 'Apr': 'April', 'May': 'May', 'Jun': 'June', 'Jul': 'July', 'Aug': 'August', 'Sep': 'September', 'Oct': 'October', 'Nov': 'November', 'Dec': 'December' };
|
|
|
|
|
|
|
|
var canvasProgress;
|
|
|
|
var divProgress;
|
|
|
|
|
|
|
|
var divRegionalCurrentMap;
|
|
|
|
var canvasRegionalObservations;
|
|
|
|
|
|
|
|
var divRegionalForecastMap1;
|
|
|
|
var divRegionalForecastMap2;
|
|
|
|
var canvasRegionalForecast1;
|
|
|
|
var canvasRegionalForecast2;
|
|
|
|
|
|
|
|
var divDopplerRadarMap;
|
|
|
|
var canvasLocalRadar;
|
|
|
|
|
|
|
|
var divTemperature;
|
|
|
|
var divStation;
|
|
|
|
var divConditions;
|
|
|
|
var divHumidity;
|
|
|
|
var divIcon;
|
|
|
|
var divDewpoint;
|
|
|
|
var divCeiling;
|
|
|
|
var divVisibility;
|
|
|
|
var divWind;
|
|
|
|
var divPressure;
|
|
|
|
var divGust;
|
|
|
|
var divHeatIndex;
|
|
|
|
var canvasCurrentWeather;
|
|
|
|
|
|
|
|
var canvasExtendedForecast1;
|
|
|
|
var canvasExtendedForecast2;
|
|
|
|
|
|
|
|
var canvasLocalForecast;
|
|
|
|
|
|
|
|
var divHazards;
|
|
|
|
var divHazardsScroll;
|
|
|
|
var canvasHazards;
|
|
|
|
|
|
|
|
var canvasAlmanac;
|
|
|
|
var canvasAlmanacTides;
|
|
|
|
var canvasOutlook;
|
|
|
|
var canvasMarineForecast;
|
|
|
|
var canvasAirQuality;
|
|
|
|
|
|
|
|
var tblTravelCities;
|
|
|
|
var divTravelCitiesScroll;
|
|
|
|
var canvasTravelForecast;
|
|
|
|
|
|
|
|
var divOutlookTemp;
|
|
|
|
var cnvOutlookTemp;
|
|
|
|
var divOutlookPrcp;
|
|
|
|
var cnvOutlookPrcp;
|
|
|
|
|
|
|
|
var tblRegionalObservations;
|
|
|
|
var canvasLatestObservations;
|
|
|
|
|
|
|
|
var _WeatherParameters = null;
|
|
|
|
|
|
|
|
var _DopplerRadarInterval = null;
|
|
|
|
var _DopplerRadarImageIndex = 0;
|
|
|
|
var _DopplerRadarImageMax = 6;
|
|
|
|
|
|
|
|
var LoadStatuses = {
|
|
|
|
Loading: 0,
|
|
|
|
Loaded: 1,
|
|
|
|
Failed: 2,
|
|
|
|
NoData: 3,
|
|
|
|
};
|
|
|
|
|
|
|
|
var _UpdateWeatherCanvasInterval = null;
|
|
|
|
var _UpdateWeatherUpdateMs = 50;
|
|
|
|
var canvasBackGroundDateTime = null;
|
|
|
|
var canvasBackGroundCurrentConditions = null;
|
|
|
|
|
|
|
|
var CurrentConditionTypes = {
|
|
|
|
Title: 0,
|
|
|
|
Conditions: 1,
|
|
|
|
Temperature: 2,
|
|
|
|
HumidityDewpoint: 3,
|
|
|
|
BarometricPressure: 4,
|
|
|
|
Wind: 5,
|
|
|
|
VisibilityCeiling: 6,
|
|
|
|
MonthPrecipitation: 7,
|
|
|
|
};
|
|
|
|
var _UpdateWeatherCurrentConditionType = CurrentConditionTypes.Title;
|
|
|
|
var _UpdateWeatherCurrentConditionCounterMs = 0;
|
|
|
|
|
|
|
|
var _UpdateCustomScrollTextMs = 0;
|
|
|
|
|
|
|
|
var _UpdateHazardsY = 0;
|
|
|
|
|
|
|
|
var _UpdateLocalForecastIndex = 0;
|
|
|
|
|
|
|
|
var CanvasTypes = {
|
|
|
|
Progress: 0,
|
|
|
|
CurrentWeather: 1,
|
|
|
|
LatestObservations: 2,
|
|
|
|
TravelForecast: 3,
|
|
|
|
RegionalForecast1: 4,
|
|
|
|
RegionalForecast2: 5,
|
|
|
|
RegionalObservations: 6,
|
|
|
|
LocalForecast: 7,
|
|
|
|
MarineForecast: 8,
|
|
|
|
ExtendedForecast1: 9,
|
|
|
|
ExtendedForecast2: 10,
|
|
|
|
Almanac: 11,
|
|
|
|
AlmanacTides: 12,
|
|
|
|
AirQuality: 13,
|
|
|
|
Outlook: 14,
|
|
|
|
LocalRadar: 15,
|
|
|
|
Hazards: 16,
|
|
|
|
};
|
|
|
|
var _FirstCanvasType = CanvasTypes.Progress;
|
|
|
|
var _LastCanvasType = CanvasTypes.Hazards;
|
|
|
|
var _CurrentCanvasType = _FirstCanvasType;
|
|
|
|
var _CurrentPosition = 0.0;
|
|
|
|
var _PreviousPosition = 0.0;
|
|
|
|
|
|
|
|
var _IsPlaying = false;
|
|
|
|
var _PlayIntervalId = null;
|
|
|
|
|
|
|
|
var _IsAudioPlaying = false;
|
|
|
|
var _AudioPlayIntervalId = null;
|
|
|
|
var _AudioPlayInterval = 100;
|
|
|
|
var _AudioFadeOutIntervalId = null;
|
|
|
|
var _MusicUrls = [];
|
|
|
|
var _MusicUrlsTemp = [];
|
|
|
|
var audMusic = null;
|
|
|
|
var _AudioContext = null;
|
|
|
|
var _AudioBufferSource = null;
|
|
|
|
var _AudioDuration = 0;
|
|
|
|
var _AudioCurrentTime = 0;
|
|
|
|
var _AudioGain = null;
|
|
|
|
var _AudioRefreshIntervalId = null;
|
|
|
|
|
|
|
|
var _IsNarrationPlaying = false;
|
|
|
|
var _Utterance = false;
|
|
|
|
var _CurrentUtterance = false;
|
|
|
|
var _CurrentUtteranceId = null;
|
|
|
|
var _IsSpeaking = false;
|
|
|
|
|
|
|
|
const OperatingSystems = {
|
|
|
|
Unknown: 0,
|
|
|
|
Windows: 1,
|
|
|
|
MacOS: 2,
|
|
|
|
Linux: 3,
|
|
|
|
Unix: 4,
|
|
|
|
iOS: 5,
|
|
|
|
Andriod: 6,
|
|
|
|
WindowsPhone: 7,
|
|
|
|
};
|
|
|
|
let _OperatingSystem = OperatingSystems.Unknown;
|
|
|
|
const _UserAgent = window.navigator.userAgent;
|
|
|
|
if (_UserAgent.indexOf('Win') !== -1) _OperatingSystem = OperatingSystems.Windows;
|
|
|
|
if (_UserAgent.indexOf('Mac') !== -1) _OperatingSystem = OperatingSystems.MacOS;
|
|
|
|
if (_UserAgent.indexOf('X11') !== -1) _OperatingSystem = OperatingSystems.Unix;
|
|
|
|
if (_UserAgent.indexOf('Linux') !== -1) _OperatingSystem = OperatingSystems.Linux;
|
|
|
|
if (_UserAgent.indexOf('iPad') !== -1) _OperatingSystem = OperatingSystems.iOS;
|
|
|
|
if (_UserAgent.indexOf('iPhone') !== -1) _OperatingSystem = OperatingSystems.iOS;
|
|
|
|
if (_UserAgent.indexOf('iPod') !== -1) _OperatingSystem = OperatingSystems.iOS;
|
|
|
|
if (_UserAgent.toLowerCase().indexOf('android') !== -1) _OperatingSystem = OperatingSystems.Andriod;
|
|
|
|
if (_UserAgent.indexOf('Windows Phone') !== -1) _OperatingSystem = OperatingSystems.WindowsPhone;
|
|
|
|
|
|
|
|
const GetMonthPrecipitation = async (WeatherParameters) => {
|
|
|
|
const DateTime = luxon.DateTime;
|
|
|
|
const today = DateTime.local().startOf('day').toISO().replace('.000','');
|
|
|
|
|
|
|
|
try {
|
|
|
|
const cliProducts = await $.ajaxCORS({
|
|
|
|
type: 'GET',
|
|
|
|
url: 'https://api.weather.gov/products',
|
|
|
|
data: {
|
|
|
|
location: WeatherParameters.WeatherOffice,
|
|
|
|
type: 'CLI',
|
|
|
|
start: today,
|
|
|
|
},
|
|
|
|
dataType: 'json',
|
|
|
|
crossDomain: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
// get the first url from the list
|
|
|
|
const cli = await $.ajaxCORS({
|
|
|
|
type: 'GET',
|
|
|
|
url: cliProducts['@graph'][0]['@id'],
|
|
|
|
dataType: 'json',
|
|
|
|
crossDomain: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
WeatherParameters.WeatherMonthlyTotals = WeatherMonthlyTotalsParser(cli.productText);
|
|
|
|
console.log(WeatherParameters.WeatherMonthlyTotals);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
console.error('GetMonthPrecipitation failed');
|
|
|
|
console.error(e);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var GetOutlook = function (WeatherParameters) {
|
|
|
|
WeatherParameters.Outlook = null;
|
|
|
|
|
|
|
|
// No current support for HI and AK.
|
|
|
|
if (WeatherParameters.State === 'HI' || WeatherParameters.State === 'AK') {
|
|
|
|
GetTideInfo2(WeatherParameters);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var ImagesLoadedCounter = 0;
|
|
|
|
var ImagesLoadedMax = 2;
|
|
|
|
|
|
|
|
var ImageOnError = function () {
|
|
|
|
GetTideInfo2(WeatherParameters);
|
|
|
|
};
|
|
|
|
|
|
|
|
var ImageOnLoad = function () {
|
|
|
|
ImagesLoadedCounter++;
|
|
|
|
if (ImagesLoadedCounter < ImagesLoadedMax) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var Outlook = {};
|
|
|
|
|
|
|
|
var now = new Date();
|
|
|
|
var CurrentMonth = new Date(now.getYear(), now.getMonth(), 1);
|
|
|
|
if (now.getDate() <= 14) {
|
|
|
|
CurrentMonth = CurrentMonth.addMonths(-1);
|
|
|
|
}
|
|
|
|
Outlook.From = CurrentMonth.getMonthShortName();
|
|
|
|
CurrentMonth = CurrentMonth.addMonths(1);
|
|
|
|
Outlook.To = CurrentMonth.getMonthShortName();
|
|
|
|
|
|
|
|
var cnvOutlookTempId = 'cnvOutlookTemp';
|
|
|
|
var contextTemp;
|
|
|
|
|
|
|
|
if (_DontLoadGifs === false) {
|
|
|
|
// Clear the current image.
|
|
|
|
divOutlookTemp.empty();
|
|
|
|
|
|
|
|
divOutlookTemp.html('<canvas id=\'' + cnvOutlookTempId + '\' />');
|
|
|
|
cnvOutlookTemp = $('#' + cnvOutlookTempId);
|
|
|
|
cnvOutlookTemp.attr('width', '719'); // For Chrome.
|
|
|
|
cnvOutlookTemp.attr('height', '707'); // For Chrome.
|
|
|
|
}
|
|
|
|
cnvOutlookTemp = $('#' + cnvOutlookTempId);
|
|
|
|
contextTemp = cnvOutlookTemp[0].getContext('2d');
|
|
|
|
contextTemp.drawImage(TempImage, 0, 0);
|
|
|
|
|
|
|
|
var TempColor = GetOutlookColor(WeatherParameters, contextTemp);
|
|
|
|
var Temperature = GetOutlookTemperatureIndicator(TempColor);
|
|
|
|
Outlook.Temperature = Temperature;
|
|
|
|
|
|
|
|
var cnvOutlookPrcpId = 'cnvOutlookPrcp';
|
|
|
|
var contextPrcp;
|
|
|
|
|
|
|
|
if (_DontLoadGifs === false) {
|
|
|
|
// Clear the current image.
|
|
|
|
divOutlookPrcp.empty();
|
|
|
|
|
|
|
|
divOutlookPrcp.html('<canvas id=\'' + cnvOutlookPrcpId + '\' />');
|
|
|
|
cnvOutlookPrcp = $('#' + cnvOutlookPrcpId);
|
|
|
|
cnvOutlookPrcp.attr('width', '719'); // For Chrome.
|
|
|
|
cnvOutlookPrcp.attr('height', '707'); // For Chrome.
|
|
|
|
}
|
|
|
|
cnvOutlookPrcp = $('#' + cnvOutlookPrcpId);
|
|
|
|
contextPrcp = cnvOutlookPrcp[0].getContext('2d');
|
|
|
|
contextPrcp.drawImage(PrcpImage, 0, 0);
|
|
|
|
|
|
|
|
var PrcpColor = GetOutlookColor(WeatherParameters, contextPrcp);
|
|
|
|
var Precipitation = GetOutlookPrecipitationIndicator(PrcpColor);
|
|
|
|
Outlook.Precipitation = Precipitation;
|
|
|
|
|
|
|
|
WeatherParameters.Outlook = Outlook;
|
|
|
|
|
|
|
|
PopulateOutlook(WeatherParameters);
|
|
|
|
|
|
|
|
GetTideInfo2(WeatherParameters);
|
|
|
|
};
|
|
|
|
|
|
|
|
var TempUrl = 'https://www.cpc.ncep.noaa.gov/products/predictions/30day/off14_temp.gif';
|
|
|
|
TempUrl = 'cors/?u=' + encodeURIComponent(TempUrl);
|
|
|
|
var TempImage = new Image();
|
|
|
|
TempImage.onload = ImageOnLoad;
|
|
|
|
TempImage.onerror = ImageOnError;
|
|
|
|
TempImage.src = TempUrl;
|
|
|
|
|
|
|
|
var PrcpUrl = 'https://www.cpc.ncep.noaa.gov/products/predictions/30day/off14_prcp.gif';
|
|
|
|
PrcpUrl = 'cors/?u=' + encodeURIComponent(PrcpUrl);
|
|
|
|
var PrcpImage = new Image();
|
|
|
|
PrcpImage.onload = ImageOnLoad;
|
|
|
|
TempImage.onerror = ImageOnError;
|
|
|
|
PrcpImage.src = PrcpUrl;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
var GetOutlookColor = function (WeatherParameters, context) {
|
|
|
|
var X = 0;
|
|
|
|
var Y = 0;
|
|
|
|
var PixelColor = '';
|
|
|
|
var Latitude = WeatherParameters.Latitude;
|
|
|
|
var Longitude = WeatherParameters.Longitude;
|
|
|
|
|
|
|
|
// The height is in the range of latitude 75'N (top) - 15'N (bottom)
|
|
|
|
Y = ((75 - Latitude) / 53) * 707;
|
|
|
|
|
|
|
|
if (Latitude < 48.83) {
|
|
|
|
Y -= Math.abs(48.83 - Latitude) * 2.9;
|
|
|
|
}
|
|
|
|
if (Longitude < -100.46) {
|
|
|
|
Y -= Math.abs(-100.46 - Longitude) * 1.7;
|
|
|
|
} else {
|
|
|
|
Y -= Math.abs(-100.46 - Longitude) * 1.7;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The width is in the range of the longitude ???
|
|
|
|
X = ((-155 - Longitude) / -110) * 719; // -155 - -40
|
|
|
|
|
|
|
|
if (Longitude < -100.46) {
|
|
|
|
X -= Math.abs(-100.46 - Longitude) * 1;
|
|
|
|
|
|
|
|
if (Latitude > 40) {
|
|
|
|
X += Math.abs(40 - Latitude) * 4;
|
|
|
|
} else {
|
|
|
|
X -= Math.abs(40 - Latitude) * 4;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
X += Math.abs(-100.46 - Longitude) * 2;
|
|
|
|
|
|
|
|
if (Latitude < 36 && Longitude > -90) {
|
|
|
|
X += Math.abs(36 - Latitude) * 8;
|
|
|
|
} else {
|
|
|
|
X -= Math.abs(36 - Latitude) * 6;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The further left and right from lat 45 and lon -97 the y increases
|
|
|
|
X = Math.round(X);
|
|
|
|
Y = Math.round(Y);
|
|
|
|
|
|
|
|
// Determine if there is any "non-white" colors around the area.
|
|
|
|
// Search a 16x16 region.
|
|
|
|
var FoundColor = false;
|
|
|
|
for (var ColorX = X - 8; ColorX <= X + 8; ColorX++) {
|
|
|
|
for (var ColorY = Y - 8; ColorY <= Y + 8; ColorY++) {
|
|
|
|
PixelColor = GetPixelColor(context, ColorX, ColorY);
|
|
|
|
|
|
|
|
if (PixelColor !== '#FFFFFF' && PixelColor !== '#000000') {
|
|
|
|
FoundColor = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FoundColor) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FoundColor) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PixelColor;
|
|
|
|
};
|
|
|
|
|
|
|
|
var GetOutlookTemperatureIndicator = function (PixelColor) {
|
|
|
|
var RGB = HexToRgb(PixelColor);
|
|
|
|
|
|
|
|
if (RGB.b > RGB.r) {
|
|
|
|
return 'B';
|
|
|
|
} else if (RGB.r > RGB.b) {
|
|
|
|
return 'A';
|
|
|
|
} else {
|
|
|
|
return 'N';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var GetOutlookPrecipitationIndicator = function (PixelColor) {
|
|
|
|
var RGB = HexToRgb(PixelColor);
|
|
|
|
|
|
|
|
if (RGB.g > RGB.r) {
|
|
|
|
return 'A';
|
|
|
|
} else if (RGB.r > RGB.g) {
|
|
|
|
return 'B';
|
|
|
|
} else {
|
|
|
|
return 'N';
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const GetPixelColor = (context, x, y) => {
|
|
|
|
var PixelData = context.getImageData(x, y, 1, 1).data;
|
|
|
|
var R = PixelData[0];
|
|
|
|
var G = PixelData[1];
|
|
|
|
var B = PixelData[2];
|
|
|
|
return '#' + ('000000' + RgbToHex(R, G, B)).slice(-6);
|
|
|
|
};
|
|
|
|
|
|
|
|
const RgbToHex = (r, g, b) => {
|
|
|
|
if (r > 255 || g > 255 || b > 255) throw 'Invalid color component';
|
|
|
|
return ((r << 16) | (g << 8) | b).toString(16).toUpperCase();
|
|
|
|
};
|
|
|
|
|
|
|
|
const HexToRgb = (h) => {
|
|
|
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(h);
|
|
|
|
return result ? {
|
|
|
|
r: parseInt(result[1], 16),
|
|
|
|
g: parseInt(result[2], 16),
|
|
|
|
b: parseInt(result[3], 16),
|
|
|
|
} : null;
|
|
|
|
};
|
|
|
|
|
|
|
|
var PopulateOutlook = function (WeatherParameters) {
|
|
|
|
if (WeatherParameters === null || (_DontLoadGifs && WeatherParameters.Progress.Almanac !== LoadStatuses.Loaded)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var Outlook = WeatherParameters.Outlook;
|
|
|
|
|
|
|
|
// Draw canvas
|
|
|
|
var canvas = canvasOutlook[0];
|
|
|
|
var context = canvas.getContext('2d');
|
|
|
|
|
|
|
|
var BackGroundImage = new Image();
|
|
|
|
BackGroundImage.onload = function () {
|
|
|
|
context.drawImage(BackGroundImage, 0, 0);
|
|
|
|
DrawHorizontalGradientSingle(context, 0, 30, 500, 90, _TopColor1, _TopColor2);
|
|
|
|
DrawTriangle(context, 'rgb(28, 10, 87)', 500, 30, 450, 90, 500, 90);
|
|
|
|
DrawHorizontalGradientSingle(context, 0, 90, 52, 399, _SideColor1, _SideColor2);
|
|
|
|
DrawHorizontalGradientSingle(context, 584, 90, 640, 399, _SideColor1, _SideColor2);
|
|
|
|
|
|
|
|
DrawTitleText(context, 'Almanac', 'Outlook');
|
|
|
|
|
|
|
|
DrawText(context, 'Star4000', '24pt', '#FFFFFF', 320, 180, '30 Day Outlook', 2, 'center');
|
|
|
|
|
|
|
|
var DateRange = 'MID-' + Outlook.From.toUpperCase() + ' TO MID-' + Outlook.To.toUpperCase();
|
|
|
|
DrawText(context, 'Star4000', '24pt', '#FFFFFF', 320, 220, DateRange, 2, 'center');
|
|
|
|
|
|
|
|
var Temperature = GetOutlookDescription(Outlook.Temperature);
|
|
|
|
DrawText(context, 'Star4000', '24pt', '#FFFFFF', 70, 300, 'Temperatures: ' + Temperature, 2);
|
|
|
|
|
|
|
|
var Precipitation = GetOutlookDescription(Outlook.Precipitation);
|
|
|
|
DrawText(context, 'Star4000', '24pt', '#FFFFFF', 70, 380, 'Precipitation: ' + Precipitation, 2);
|
|
|
|
|
|
|
|
UpdateWeatherCanvas(WeatherParameters, canvasOutlook);
|
|
|
|
};
|
|
|
|
//BackGroundImage.src = "images/BackGround1_" + _Themes.toString() + ".png";
|
|
|
|
BackGroundImage.src = 'images/BackGround1_1.png';
|
|
|
|
};
|
|
|
|
|
|
|
|
var GetOutlookDescription = function (OutlookIndicator) {
|
|
|
|
switch (OutlookIndicator) {
|
|
|
|
case 'N':
|
|
|
|
return 'Normal';
|
|
|
|
case 'A':
|
|
|
|
return 'Above Normal';
|
|
|
|
case 'B':
|
|
|
|
return 'Below Normal';
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
String.prototype.capitalize = function () {
|
|
|
|
return this.toLowerCase().replace(/\b[a-z]/g, function (letter) {
|
|
|
|
return letter.toUpperCase();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Date.prototype.stdTimezoneOffset = function () {
|
|
|
|
var jan = new Date(this.getFullYear(), 0, 1);
|
|
|
|
var jul = new Date(this.getFullYear(), 6, 1);
|
|
|
|
return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
|
|
|
|
};
|
|
|
|
|
|
|
|
Date.prototype.dst = function () {
|
|
|
|
return this.getTimezoneOffset() < this.stdTimezoneOffset();
|
|
|
|
};
|
|
|
|
|
|
|
|
var GetWeatherHazards3 = function (WeatherParameters) {
|
|
|
|
var ZoneId = WeatherParameters.ZoneId;
|
|
|
|
var HazardUrls = [];
|
|
|
|
var HazardCounter = 0;
|
|
|
|
|
|
|
|
WeatherParameters.WeatherHazardConditions =
|
|
|
|
{
|
|
|
|
ZoneId: WeatherParameters.ZoneId,
|
|
|
|
Hazards: [],
|
|
|
|
};
|
|
|
|
|
|
|
|
var Url = 'https://alerts.weather.gov/cap/wwaatmget.php?x=' + ZoneId + '&y=0';
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
// Load the xml file using ajax
|
|
|
|
$.ajaxCORS({
|
|
|
|
type: 'GET',
|
|
|
|
url: Url,
|
2020-09-08 03:06:44 +00:00
|
|
|
dataType: 'text',
|
2020-09-04 18:02:20 +00:00
|
|
|
crossDomain: true,
|
|
|
|
cache: false,
|
2020-09-08 03:06:44 +00:00
|
|
|
success: function (text) {
|
|
|
|
// IE doesn't support XML tags with colons.
|
|
|
|
text = text.replaceAll('<cap:', '<cap_');
|
|
|
|
text = text.replaceAll('</cap:', '</cap_');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var $xml = $(text);
|
|
|
|
//console.log(xml);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
$xml.find('entry').each(function () {
|
|
|
|
var entry = $(this);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
// Skip non-alerts.
|
|
|
|
var cap_msgType = entry.find('cap_msgType');
|
|
|
|
if (cap_msgType.text() !== 'Alert') {
|
|
|
|
return true;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var link = entry.find('link');
|
|
|
|
var Url = link.attr('href');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
HazardUrls.push(Url);
|
|
|
|
});
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (HazardUrls.length === 0) {
|
|
|
|
PopulateHazardConditions(WeatherParameters);
|
|
|
|
console.log(WeatherParameters.WeatherHazardConditions);
|
|
|
|
return;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
$(HazardUrls).each(function () {
|
|
|
|
var Url = this.toString();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
$.ajaxCORS({
|
|
|
|
type: 'GET',
|
|
|
|
url: Url,
|
|
|
|
dataType: 'xml',
|
|
|
|
crossDomain: true,
|
|
|
|
cache: true,
|
|
|
|
success: function (xml) {
|
|
|
|
var $xml = $(xml);
|
|
|
|
console.log(xml);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var description = $xml.find('description');
|
|
|
|
WeatherParameters.WeatherHazardConditions.Hazards.push(description.text());
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
HazardCounter++;
|
|
|
|
if (HazardCounter === HazardUrls.length) {
|
|
|
|
PopulateHazardConditions(WeatherParameters);
|
|
|
|
console.log(WeatherParameters.WeatherHazardConditions);
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
2020-09-08 03:06:44 +00:00
|
|
|
},
|
|
|
|
error: function () {
|
|
|
|
console.error('GetWeatherHazards3 failed for Url: ' + Url);
|
|
|
|
WeatherParameters.Progress.Hazards = LoadStatuses.Failed;
|
|
|
|
},
|
|
|
|
});
|
2020-09-04 18:02:20 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
},
|
|
|
|
error: function (xhr, error, errorThrown) {
|
2020-09-08 03:06:44 +00:00
|
|
|
console.error('GetWeatherHazards3 failed: ' + errorThrown);
|
|
|
|
WeatherParameters.Progress.Hazards = LoadStatuses.Failed;
|
2020-09-04 18:02:20 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
$(() => {
|
|
|
|
canvasBackGroundDateTime = $('#canvasBackGroundDateTime');
|
|
|
|
canvasBackGroundCurrentConditions = $('#canvasBackGroundCurrentConditions');
|
|
|
|
canvasProgress = $('#canvasProgress');
|
|
|
|
divProgress = $('#divProgress');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasLocalRadar = $('#canvasLocalRadar');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasRegionalForecast1 = $('#canvasRegionalForecast1');
|
|
|
|
canvasRegionalForecast2 = $('#canvasRegionalForecast2');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasRegionalObservations = $('#canvasRegionalObservations');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasCurrentWeather = $('#canvasCurrentWeather');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasExtendedForecast1 = $('#canvasExtendedForecast1');
|
|
|
|
canvasExtendedForecast2 = $('#canvasExtendedForecast2');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasLocalForecast = $('#canvasLocalForecast');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
divHazards = $('#divHazards');
|
|
|
|
divHazardsScroll = $('#divHazardsScroll');
|
|
|
|
canvasHazards = $('#canvasHazards');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasAlmanac = $('#canvasAlmanac');
|
|
|
|
canvasAlmanacTides = $('#canvasAlmanacTides');
|
|
|
|
canvasOutlook = $('#canvasOutlook');
|
|
|
|
canvasMarineForecast = $('#canvasMarineForecast');
|
|
|
|
canvasAirQuality = $('#canvasAirQuality');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
divOutlookTemp = $('#divOutlookTemp');
|
|
|
|
divOutlookPrcp = $('#divOutlookPrcp');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasTravelForecast = $('#canvasTravelForecast');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasLatestObservations = $('#canvasLatestObservations');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasProgress.mousemove(canvasProgress_mousemove);
|
|
|
|
canvasProgress.click(canvasProgress_click);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
_WeatherParameters = {};
|
|
|
|
|
|
|
|
_WeatherParameters.WeatherHazardConditions = {};
|
|
|
|
|
|
|
|
const WeatherCanvases = [];
|
|
|
|
WeatherCanvases.push(canvasProgress);
|
|
|
|
WeatherCanvases.push(canvasCurrentWeather);
|
|
|
|
WeatherCanvases.push(canvasLatestObservations);
|
|
|
|
WeatherCanvases.push(canvasTravelForecast);
|
|
|
|
WeatherCanvases.push(canvasRegionalForecast1);
|
|
|
|
WeatherCanvases.push(canvasRegionalForecast2);
|
|
|
|
WeatherCanvases.push(canvasRegionalObservations);
|
|
|
|
WeatherCanvases.push(canvasAlmanac);
|
|
|
|
WeatherCanvases.push(canvasAlmanacTides);
|
|
|
|
WeatherCanvases.push(canvasOutlook);
|
|
|
|
WeatherCanvases.push(canvasMarineForecast);
|
|
|
|
WeatherCanvases.push(canvasAirQuality);
|
|
|
|
WeatherCanvases.push(canvasLocalForecast);
|
|
|
|
WeatherCanvases.push(canvasExtendedForecast1);
|
|
|
|
WeatherCanvases.push(canvasExtendedForecast2);
|
|
|
|
WeatherCanvases.push(canvasHazards);
|
|
|
|
WeatherCanvases.push(canvasLocalRadar);
|
|
|
|
_WeatherParameters.WeatherCanvases = WeatherCanvases;
|
|
|
|
|
|
|
|
$(WeatherCanvases).each(function () {
|
|
|
|
var WeatherCanvas = $(this);
|
|
|
|
WeatherCanvas.css('position', 'absolute');
|
|
|
|
WeatherCanvas.css('top', '0px');
|
|
|
|
WeatherCanvas.css('left', '0px');
|
|
|
|
WeatherCanvas.hide();
|
|
|
|
});
|
|
|
|
canvasProgress.show();
|
|
|
|
|
|
|
|
_WeatherParameters.TravelCities = _TravelCities;
|
|
|
|
|
|
|
|
_WeatherParameters.Progress = new Progress({
|
|
|
|
WeatherParameters: _WeatherParameters,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
var NavigateMenu = function () {
|
|
|
|
if (_IsPlaying) {
|
|
|
|
NavigatePlayToggle();
|
|
|
|
}
|
|
|
|
Navigate(0);
|
|
|
|
_PlayMs = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
$.fn.scrollIntoView = function () {
|
|
|
|
const $self = this;
|
|
|
|
const OkToFadeOut = true;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
_WeatherParameters.WeatherCanvases.forEach($WeatherCanvas => {
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
if (!$WeatherCanvas.is($self)) {
|
|
|
|
if ($WeatherCanvas.is(':visible')) {
|
|
|
|
$WeatherCanvas.css('z-index', '9999');
|
|
|
|
if (!OkToFadeOut) {
|
|
|
|
$WeatherCanvas.hide();
|
|
|
|
} else {
|
|
|
|
$WeatherCanvas.fadeOut({
|
|
|
|
progress: () => {
|
|
|
|
UpdateWeatherCanvas(_WeatherParameters, $WeatherCanvas);
|
|
|
|
UpdateWeatherCanvas(_WeatherParameters, $self);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!$WeatherCanvas.is(':visible')) {
|
|
|
|
$WeatherCanvas.css('z-index', '');
|
|
|
|
$WeatherCanvas.show();
|
|
|
|
}
|
|
|
|
$WeatherCanvas.stop();
|
|
|
|
$WeatherCanvas.css('opacity', '');
|
|
|
|
UpdateWeatherCanvas(_WeatherParameters, $WeatherCanvas);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
_RefreshGifs = true;
|
|
|
|
window.setTimeout(function () { _RefreshGifs = false; }, 200);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var _PlayInterval = 100;
|
|
|
|
var _PlayMs = 0;
|
|
|
|
var _PlayMsOffsets = {
|
|
|
|
Start: 0,
|
|
|
|
End: 0,
|
|
|
|
Length: 0,
|
|
|
|
CurrentWeather_Start: 0,
|
|
|
|
CurrentWeather_End: 10000,
|
|
|
|
CurrentWeather_Length: 10000,
|
|
|
|
CurrentWeather_Loaded: false,
|
|
|
|
LatestObservations_Start: 0,
|
|
|
|
LatestObservations_End: 0,
|
|
|
|
LatestObservations_Length: 10000,
|
|
|
|
LatestObservations_Loaded: false,
|
|
|
|
TravelForecast_Start: 0,
|
|
|
|
TravelForecast_End: 0,
|
|
|
|
TravelForecast_Length: 60000,
|
|
|
|
TravelForecast_Loaded: false,
|
|
|
|
RegionalForecast1_Start: 0,
|
|
|
|
RegionalForecast1_End: 0,
|
|
|
|
RegionalForecast1_Length: 10000,
|
|
|
|
RegionalForecast1_Loaded: false,
|
|
|
|
RegionalForecast2_Start: 0,
|
|
|
|
RegionalForecast2_End: 0,
|
|
|
|
RegionalForecast2_Length: 10000,
|
|
|
|
RegionalForecast2_Loaded: false,
|
|
|
|
RegionalObservations_Start: 0,
|
|
|
|
RegionalObservations_End: 0,
|
|
|
|
RegionalObservations_Length: 10000,
|
|
|
|
RegionalObservations_Loaded: false,
|
|
|
|
LocalForecast_Start: 0,
|
|
|
|
LocalForecast_End: 0,
|
|
|
|
LocalForecast_Length: 0,
|
|
|
|
LocalForecast_Loaded: false,
|
|
|
|
MarineForecast_Start: 0,
|
|
|
|
MarineForecast_End: 0,
|
|
|
|
MarineForecast_Length: 10000,
|
|
|
|
MarineForecast_Loaded: false,
|
|
|
|
AirQuality_Start: 0,
|
|
|
|
AirQuality_End: 0,
|
|
|
|
AirQuality_Length: 10000,
|
|
|
|
AirQuality_Loaded: false,
|
|
|
|
ExtendedForecast1_Start: 0,
|
|
|
|
ExtendedForecast1_End: 0,
|
|
|
|
ExtendedForecast1_Length: 10000,
|
|
|
|
ExtendedForecast1_Loaded: false,
|
|
|
|
ExtendedForecast2_Start: 0,
|
|
|
|
ExtendedForecast2_End: 0,
|
|
|
|
ExtendedForecast2_Length: 10000,
|
|
|
|
ExtendedForecast2_Loaded: false,
|
|
|
|
Almanac_Start: 0,
|
|
|
|
Almanac_End: 0,
|
|
|
|
Almanac_Length: 10000,
|
|
|
|
Almanac_Loaded: false,
|
|
|
|
AlmanacTides_Start: 0,
|
|
|
|
AlmanacTides_End: 0,
|
|
|
|
AlmanacTides_Length: 10000,
|
|
|
|
AlmanacTides_Loaded: false,
|
|
|
|
Outlook_Start: 0,
|
|
|
|
Outlook_End: 0,
|
|
|
|
Outlook_Length: 10000,
|
|
|
|
Outlook_Loaded: false,
|
|
|
|
LocalRadar_Start: 0,
|
|
|
|
LocalRadar_End: 0,
|
|
|
|
LocalRadar_Length: 15000,
|
|
|
|
LocalRadar_Loaded: false,
|
|
|
|
Hazards_Start: 0,
|
|
|
|
Hazards_End: 0,
|
|
|
|
Hazards_Length: 0,
|
|
|
|
Hazards_Loaded: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var canvasProgress_mousemove = function (e) {
|
|
|
|
canvasProgress.css('cursor', '');
|
|
|
|
|
|
|
|
var RatioX = canvasProgress.width() / 640;
|
|
|
|
var RatioY = canvasProgress.height() / 480;
|
|
|
|
|
|
|
|
if (e.offsetX >= (70 * RatioX) && e.offsetX <= (565 * RatioX)) {
|
|
|
|
//if (e.offsetY >= (105 * RatioY) && e.offsetY <= (350 * RatioY))
|
|
|
|
if (e.offsetY >= (100 * RatioY) && e.offsetY <= (385 * RatioY)) {
|
|
|
|
// Show hand cursor.
|
|
|
|
canvasProgress.css('cursor', 'pointer');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var canvasProgress_click = function (e) {
|
|
|
|
var Hazards = _WeatherParameters.WeatherHazardConditions.Hazards;
|
|
|
|
|
|
|
|
var RatioX = canvasProgress.width() / 640;
|
|
|
|
var RatioY = canvasProgress.height() / 480;
|
|
|
|
|
|
|
|
if (e.offsetX >= (70 * RatioX) && e.offsetX <= (565 * RatioX)) {
|
|
|
|
if (e.offsetY >= (100 * RatioY) && e.offsetY < (129 * RatioY)) {
|
|
|
|
if (_WeatherParameters.Progress.CurrentConditions === LoadStatuses.Loaded) {
|
|
|
|
// Current Conditions
|
|
|
|
_CurrentCanvasType = CanvasTypes.CurrentWeather;
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aCurrentWeather";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (129 * RatioY) && e.offsetY < (158 * RatioY)) {
|
|
|
|
// Latest Observations
|
|
|
|
if (_WeatherParameters.Progress.NearbyConditions === LoadStatuses.Loaded) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.LatestObservations;
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aLatestObservations";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (158 * RatioY) && e.offsetY < (187 * RatioY)) {
|
|
|
|
// Travel Forecast
|
|
|
|
if (_WeatherParameters.Progress.TravelForecast === LoadStatuses.Loaded) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.TravelForecast;
|
|
|
|
UpdateTravelCities(0);
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aTravelForecast";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (187 * RatioY) && e.offsetY < (216 * RatioY)) {
|
|
|
|
// Regional Forecast
|
|
|
|
if (_WeatherParameters.Progress.TomorrowsRegionalMap === LoadStatuses.Loaded) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.RegionalForecast1;
|
|
|
|
//window.location.hash = "#aRegionalForecast";
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (216 * RatioY) && e.offsetY < (245 * RatioY)) {
|
|
|
|
if (_WeatherParameters.Progress.CurrentRegionalMap === LoadStatuses.Loaded) {
|
|
|
|
// Regional Observations
|
|
|
|
_CurrentCanvasType = CanvasTypes.RegionalObservations;
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aRegionalObservations";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (245 * RatioY) && e.offsetY < (274 * RatioY)) {
|
|
|
|
// Local Forecast
|
|
|
|
if (_WeatherParameters.Progress.WordedForecast === LoadStatuses.Loaded) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.LocalForecast;
|
|
|
|
UpdateLocalForecast(0);
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aLocalForecast";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (274 * RatioY) && e.offsetY < (303 * RatioY)) {
|
|
|
|
// Extended Forecast
|
|
|
|
if (_WeatherParameters.Progress.FourDayForecast === LoadStatuses.Loaded) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.ExtendedForecast1;
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aExtendedForecast";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (303 * RatioY) && e.offsetY < (332 * RatioY)) {
|
|
|
|
// Almanac
|
|
|
|
if (_WeatherParameters.Progress.Almanac === LoadStatuses.Loaded) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.Almanac;
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aAlmanac";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (332 * RatioY) && e.offsetY < (361 * RatioY)) {
|
|
|
|
// Local Radar
|
|
|
|
if (_WeatherParameters.Progress.DopplerRadar === LoadStatuses.Loaded) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.LocalRadar;
|
|
|
|
UpdateDopplarRadarImage(0);
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aLocalRadar";
|
|
|
|
NavigateReset();
|
|
|
|
}
|
|
|
|
} else if (e.offsetY >= (361 * RatioY) && e.offsetY < (390 * RatioY)) {
|
|
|
|
// Hazards
|
|
|
|
if (_WeatherParameters.Progress.Hazards === LoadStatuses.Loaded && Hazards.length > 0) {
|
|
|
|
_CurrentCanvasType = CanvasTypes.Hazards;
|
|
|
|
UpdateHazards(0);
|
|
|
|
AssignPlayMsOffsets();
|
|
|
|
//window.location.hash = "#aHazards";
|
|
|
|
NavigateReset();
|
2020-09-08 03:06:44 +00:00
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
String.prototype.centerText = function(numberOfSpaces) {
|
|
|
|
var text = this;
|
|
|
|
text = text.trim();
|
|
|
|
if (text.length > numberOfSpaces) {
|
|
|
|
return text;
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
2020-09-08 03:06:44 +00:00
|
|
|
var l = text.length;
|
|
|
|
var w2 = Math.floor(numberOfSpaces / 2);
|
|
|
|
var l2 = Math.floor(l / 2);
|
|
|
|
var s = new Array(w2 - l2).join(' ');
|
|
|
|
text = s + text + s;
|
|
|
|
if (text.length < numberOfSpaces) {
|
|
|
|
text += new Array(numberOfSpaces - text.length + 1).join(' ');
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
2020-09-08 03:06:44 +00:00
|
|
|
return text;
|
2020-09-04 18:02:20 +00:00
|
|
|
};
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var PopulateHazardConditions = function (WeatherParameters) {
|
|
|
|
if (WeatherParameters === null || (_DontLoadGifs && WeatherParameters.Progress.Hazards !== LoadStatuses.Loaded)) {
|
|
|
|
return;
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var WeatherHazardConditions = WeatherParameters.WeatherHazardConditions;
|
|
|
|
var ZoneId = WeatherHazardConditions.ZoneId;
|
|
|
|
var Text;
|
|
|
|
var Line;
|
|
|
|
var SkipLine;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var DontLoadGifs = _DontLoadGifs;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
divHazards.empty();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
$(WeatherHazardConditions.Hazards).each(function () {
|
|
|
|
//Text = this.replaceAll("\n", "<br/>");
|
|
|
|
//divHazards.html(divHazards.html() + "<br/><br/>" + Text);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
Text = this.toString();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
SkipLine = false;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
Text = Text.replaceAll('\n', ' ');
|
|
|
|
//Text = Text.replaceAll("*** ", "");
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
//$(Text.split("\n")).each(function ()
|
|
|
|
$(Text.split(' ')).each(function () {
|
|
|
|
Line = this.toString();
|
|
|
|
Line = Line.toUpperCase();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (Line.startsWith('&&')) {
|
|
|
|
return false;
|
|
|
|
} else if (Line.startsWith('$$')) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (SkipLine) {
|
|
|
|
if (Line === '') {
|
|
|
|
SkipLine = false;
|
|
|
|
return true;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (Line.startsWith(ZoneId)) {
|
|
|
|
SkipLine = true;
|
|
|
|
return true;
|
|
|
|
} else if (Line.indexOf('>') !== -1) {
|
|
|
|
SkipLine = true;
|
|
|
|
return true;
|
|
|
|
} else if (Line.indexOf('LAT...LON ') !== -1) {
|
|
|
|
SkipLine = true;
|
|
|
|
return true;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
//divHazards.html(divHazards.html() + "<br/>" + Line);
|
|
|
|
if (Line.indexOf('.') === 0 || Line.indexOf('*') === 0) {
|
|
|
|
divHazards.html(divHazards.html() + '<br/><br/>');
|
|
|
|
if (Line.indexOf('.') === 0 && Line.indexOf('...') !== 0) {
|
|
|
|
Line = Line.substr(1);
|
|
|
|
}
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
divHazards.html(divHazards.html() + Line + ' ');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
divHazards.html(divHazards.html() + '<br/><br/>');
|
|
|
|
});
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var DrawHazards = function () {
|
|
|
|
// Draw canvas
|
|
|
|
var canvas = canvasHazards[0];
|
|
|
|
var context = canvas.getContext('2d');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var BackGroundImage = new Image();
|
|
|
|
BackGroundImage.onload = function () {
|
|
|
|
context.drawImage(BackGroundImage, 0, 0);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (DontLoadGifs) {
|
|
|
|
UpdateHazards();
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (WeatherHazardConditions.Hazards.length > 0) {
|
|
|
|
WeatherParameters.Progress.Hazards = LoadStatuses.Loaded;
|
|
|
|
} else {
|
|
|
|
WeatherParameters.Progress.Hazards = LoadStatuses.NoData;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
UpdateWeatherCanvas(WeatherParameters, canvasHazards);
|
2020-09-04 18:02:20 +00:00
|
|
|
};
|
2020-09-08 03:06:44 +00:00
|
|
|
BackGroundImage.src = 'images/BackGround7.png';
|
|
|
|
};
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var HazardsText = divHazards.html();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
HazardsText = HazardsText.replaceAll('<br>', '\n');
|
|
|
|
HazardsText = HazardsText.replaceAll('<br/>', '\n');
|
|
|
|
HazardsText = HazardsText.replaceAll('<br />', '\n');
|
|
|
|
HazardsText = HazardsText.replaceAll('<br></br>', '\n');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
WeatherHazardConditions.HazardsText = HazardsText;
|
|
|
|
WeatherHazardConditions.HazardsTextC = ConvertConditionsToMetric(HazardsText);
|
|
|
|
if (_Units === Units.Metric) {
|
|
|
|
HazardsText = WeatherHazardConditions.HazardsTextC;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var HazardsWrapped = HazardsText.wordWrap(32);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var cnvHazardsScroll;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var ShowHazardsScroll = function () {
|
|
|
|
var cnvHazardsScrollId;
|
|
|
|
var context;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
cnvHazardsScrollId = 'cnvHazardsScroll';
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var HazardsWrappedLines = HazardsWrapped.split('\n');
|
|
|
|
var MaxHazardsWrappedLines = 365;
|
|
|
|
if (_OperatingSystem === OperatingSystems.Andriod) {
|
|
|
|
MaxHazardsWrappedLines = 92;
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (HazardsWrappedLines.length > MaxHazardsWrappedLines) {
|
|
|
|
HazardsWrappedLines = HazardsWrappedLines.splice(0, MaxHazardsWrappedLines - 1);
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
2020-09-08 03:06:44 +00:00
|
|
|
var height = 0 + (HazardsWrappedLines.length * 45);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (DontLoadGifs === false) {
|
|
|
|
// Clear the current image.
|
|
|
|
divHazardsScroll.empty();
|
|
|
|
divHazardsScroll.html('<canvas id=\'' + cnvHazardsScrollId + '\' />');
|
|
|
|
cnvHazardsScroll = $('#' + cnvHazardsScrollId);
|
|
|
|
cnvHazardsScroll.attr('width', '640'); // For Chrome.
|
|
|
|
cnvHazardsScroll.attr('height', height); // For Chrome.
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
2020-09-08 03:06:44 +00:00
|
|
|
cnvHazardsScroll = $('#' + cnvHazardsScrollId);
|
|
|
|
context = cnvHazardsScroll[0].getContext('2d');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
DrawBox(context, 'rgb(112, 35, 35)', 0, 0, 640, height);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
//var y = 0;
|
|
|
|
var y = 45;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
$(HazardsWrappedLines).each(function () {
|
|
|
|
var HazardLine = this.toString();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
DrawText(context, 'Star4000', '24pt', '#FFFFFF', 80, y, HazardLine, 1);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
y += 45;
|
|
|
|
});
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
DrawHazards();
|
2020-09-04 18:02:20 +00:00
|
|
|
};
|
2020-09-08 03:06:44 +00:00
|
|
|
ShowHazardsScroll();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
var UpdateHazards = function (Offset) {
|
|
|
|
var canvas = canvasHazards[0];
|
|
|
|
var context = canvas.getContext('2d');
|
|
|
|
var cnvHazardsScroll = $('#cnvHazardsScroll');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
switch (Offset) {
|
|
|
|
case undefined:
|
2020-09-04 18:02:20 +00:00
|
|
|
break;
|
2020-09-08 03:06:44 +00:00
|
|
|
case 0:
|
|
|
|
_UpdateHazardsY = 0;
|
2020-09-04 18:02:20 +00:00
|
|
|
break;
|
2020-09-08 03:06:44 +00:00
|
|
|
case Infinity:
|
|
|
|
_UpdateHazardsY = cnvHazardsScroll.height();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
_UpdateHazardsY += (385 * Offset);
|
|
|
|
if (_UpdateHazardsY > cnvHazardsScroll.height()) {
|
|
|
|
_UpdateHazardsY = cnvHazardsScroll.height();
|
|
|
|
} else if (_UpdateHazardsY < 0) {
|
|
|
|
_UpdateHazardsY = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
DrawBox(context, 'rgb(112, 35,35)', 0, 0, 640, 385);
|
|
|
|
context.drawImage(cnvHazardsScroll[0], 0, _UpdateHazardsY, 640, 385, 0, 0, 640, 385);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
};
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
const WeatherMonthlyTotalsParser = (text) => {
|
|
|
|
return +text.match(/MONTH TO DATE\s*(\d{1,2}\.\d\d)/)[1];
|
|
|
|
};
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
Number.prototype.pad = function(size) {
|
|
|
|
var s = String(this);
|
|
|
|
while (s.length < (size || 1)) {
|
|
|
|
s = '0' + s;
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
};
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
const Progress = function (e) {
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
const _ProgressInterval = window.setInterval(() => {
|
|
|
|
gifProgress.get_canvas().width = (ProgressPercent / 100) * 530 + 1;
|
|
|
|
|
|
|
|
if (ProgressPercent > 0) {
|
|
|
|
gifProgress.setX(53);
|
|
|
|
gifProgress.setY(430);
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
_DisplayLoadingDetails();
|
|
|
|
if (ProgressPercent >= 100) {
|
|
|
|
gifProgress.pause();
|
|
|
|
window.clearInterval(_ProgressInterval);
|
|
|
|
if (typeof _CallBack === 'function') _CallBack({ Status: 'LOADED', LastUpdate: new Date() });
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
}, 250);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
const _DisplayLoadingDetails = () => {
|
|
|
|
context.drawImage(BackGroundImage, 0, 100, 640, 300, 0, 100, 640, 300);
|
|
|
|
DrawHorizontalGradientSingle(context, 0, 90, 52, 399, _SideColor1, _SideColor2);
|
|
|
|
DrawHorizontalGradientSingle(context, 584, 90, 640, 399, _SideColor1, _SideColor2);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
const __DrawText = (caption, status) => {
|
|
|
|
let StatusText;
|
|
|
|
let StatusColor;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
OffsetY += 29;
|
|
|
|
};
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
__DrawText('Current Conditions', WeatherParameters.Progress.CurrentConditions);
|
|
|
|
__DrawText('Latest Observations', WeatherParameters.Progress.NearbyConditions);
|
|
|
|
__DrawText('Travel Forecast', WeatherParameters.Progress.TravelForecast);
|
|
|
|
__DrawText('Regional Forecast', WeatherParameters.Progress.TomorrowsRegionalMap);
|
|
|
|
__DrawText('Regional Observations', WeatherParameters.Progress.CurrentRegionalMap);
|
|
|
|
__DrawText('Local Forecast', WeatherParameters.Progress.WordedForecast);
|
|
|
|
__DrawText('Extended Forecast', WeatherParameters.Progress.FourDayForecast);
|
|
|
|
__DrawText('Almanac', WeatherParameters.Progress.Almanac);
|
|
|
|
__DrawText('Local Radar', WeatherParameters.Progress.DopplerRadar);
|
|
|
|
__DrawText('Hazardous Weather', WeatherParameters.Progress.Hazards);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
};
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
this.DrawProgress = async () => {
|
|
|
|
const DontLoadGifs = _DontLoadGifs;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
BackGroundImage = await utils.loadImg('images/BackGround1_1.png');
|
|
|
|
_self.Loaded = false;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (!DontLoadGifs || !gifProgress) {
|
|
|
|
// Conditions Icon
|
|
|
|
gifProgress = await utils.SuperGifAsync({
|
|
|
|
src: 'images/Progress1.gif',
|
|
|
|
loop_delay: 100,
|
|
|
|
auto_play: true,
|
|
|
|
canvas: canvas,
|
|
|
|
x: 50,
|
|
|
|
y: 480,
|
2020-09-04 18:02:20 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
context.drawImage(BackGroundImage, 0, 0);
|
|
|
|
DrawHorizontalGradientSingle(context, 0, 30, 500, 90, _TopColor1, _TopColor2);
|
|
|
|
DrawTriangle(context, 'rgb(28, 10, 87)', 500, 30, 450, 90, 500, 90);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
canvasBackGroundDateTime[0].getContext('2d').drawImage(canvas, 410, 30, 175, 60, 0, 0, 175, 60);
|
|
|
|
canvasBackGroundCurrentConditions[0].getContext('2d').drawImage(canvas, 0, 405, 640, 75, 0, 0, 640, 75);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
DrawTitleText(context, 'WeatherStar', '4000+ 2.00');
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
// Draw a box for the progress.
|
|
|
|
DrawBox(context, '#000000', 51, 428, 534, 22);
|
|
|
|
DrawBox(context, '#ffffff', 53, 430, 530, 18);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
_DisplayLoadingDetails();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
UpdateWeatherCanvas(WeatherParameters, canvasProgress);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
_self.Loaded = true;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (DontLoadGifs === false)e.OnLoad();
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
};
|
|
|
|
this.DrawProgress();
|
|
|
|
};
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
const DrawCustomScrollText = (WeatherParameters, context) => {
|
|
|
|
const font = 'Star4000';
|
|
|
|
const size = '24pt';
|
|
|
|
const color = '#ffffff';
|
|
|
|
const shadow = 2;
|
|
|
|
let x = 640;
|
|
|
|
const y = 430;
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
if (WeatherParameters.Progress.GetTotalPercentage() !== 100) {
|
|
|
|
return;
|
2020-09-04 18:02:20 +00:00
|
|
|
}
|
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
// Clear the date and time area.
|
|
|
|
context.drawImage(canvasBackGroundCurrentConditions[0], 0, 0, 640, 75, 0, 405, 640, 75);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
const text = _ScrollText;
|
|
|
|
//text = "WELCOME TO THE WEATHER STAR 4000+! IF YOU ARE ENJOYING THIS SITE THEN YOU WILL LOVE THE WEATHER STAR 4000 SIMULATOR!";
|
|
|
|
//text = "Hello World!";
|
|
|
|
//text = "A";
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
x = 640 - ((_UpdateCustomScrollTextMs / _UpdateWeatherUpdateMs) * 5);
|
|
|
|
// Wait an extra 5 characters.
|
|
|
|
if (x < ((text.length + 10) * 15 * -1)) {
|
|
|
|
_UpdateCustomScrollTextMs = 0;
|
|
|
|
x = 640;
|
|
|
|
}
|
2020-09-04 18:02:20 +00:00
|
|
|
|
2020-09-08 03:06:44 +00:00
|
|
|
// Draw the current condition.
|
|
|
|
DrawText(context, font, size, color, x, y, text, shadow);
|
2020-09-04 18:02:20 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const AssignScrollText = (e) => {
|
|
|
|
_ScrollText = e.ScrollText;
|
|
|
|
_UpdateCustomScrollTextMs = 0;
|
|
|
|
_UpdateWeatherCurrentConditionType = CurrentConditionTypes.Title;
|
|
|
|
_UpdateWeatherCurrentConditionCounterMs = 0;
|
|
|
|
};
|
|
|
|
|