From 4b7e314d56ed9776df72e338f827df1434e43f5f Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Mon, 7 Sep 2020 22:06:44 -0500 Subject: [PATCH] proper radar merge --- server/scripts/modules/radar.js | 43 +- server/scripts/twc3.js | 3573 ------------------------------- 2 files changed, 41 insertions(+), 3575 deletions(-) diff --git a/server/scripts/modules/radar.js b/server/scripts/modules/radar.js index e455730..934ae65 100644 --- a/server/scripts/modules/radar.js +++ b/server/scripts/modules/radar.js @@ -127,8 +127,10 @@ class Radar extends WeatherDisplay { // draw the entire image if (weatherParameters.State === 'HI') { + workingContext.clearRect(0, 0, 571, 600); workingContext.drawImage(imgBlob, 0, 0, 571, 600); } else { + workingContext.clearRect(0, 0, 2550, 1600); workingContext.drawImage(imgBlob, 0, 0, 2550, 1600); } @@ -138,8 +140,16 @@ class Radar extends WeatherDisplay { // get the base map context.drawImage(await this.baseMap, sourceXY.x, sourceXY.y, offsetX*2, offsetY*2, 0, 0, 640, 367); - // put the radar on top - context.drawImage(workingCanvas, radarSourceX, radarSourceY, (radarOffsetX * 2), (radarOffsetY * 2.33), 0, 0, 640, 367); + // crop the radar image + const cropCanvas = document.createElement('canvas'); + cropCanvas.width = 640; + cropCanvas.height = 367; + const cropContext = cropCanvas.getContext('2d'); + cropContext.imageSmoothingEnabled = false; + cropContext.drawImage(workingCanvas, radarSourceX, radarSourceY, (radarOffsetX * 2), (radarOffsetY * 2.33), 0, 0, 640, 367); + + // merge the radar and map + this.mergeDopplerRadarImage(context, cropContext); return canvas; })); @@ -349,4 +359,33 @@ class Radar extends WeatherDisplay { // rewrite the image RadarContext.putImageData(RadarImageData, 0, 0); } + + mergeDopplerRadarImage (mapContext, radarContext) { + var mapImageData = mapContext.getImageData(0, 0, mapContext.canvas.width, mapContext.canvas.height); + var radarImageData = radarContext.getImageData(0, 0, radarContext.canvas.width, radarContext.canvas.height); + + // examine every pixel, + // change any old rgb to the new-rgb + for (var i = 0; i < radarImageData.data.length; i += 4) { + // i + 0 = red + // i + 1 = green + // i + 2 = blue + // i + 3 = alpha (0 = transparent, 255 = opaque) + + // is this pixel the old rgb? + if ((mapImageData.data[i] < 116 && mapImageData.data[i + 1] < 116 && mapImageData.data[i + 2] < 116)) { + // change to your new rgb + + // Transparent + radarImageData.data[i] = 0; + radarImageData.data[i + 1] = 0; + radarImageData.data[i + 2] = 0; + radarImageData.data[i + 3] = 0; + } + } + + radarContext.putImageData(radarImageData, 0, 0); + + mapContext.drawImage(radarContext.canvas, 0, 0); + } } \ No newline at end of file diff --git a/server/scripts/twc3.js b/server/scripts/twc3.js index bbe3afc..154df24 100644 --- a/server/scripts/twc3.js +++ b/server/scripts/twc3.js @@ -203,252 +203,6 @@ const GetMonthPrecipitation = async (WeatherParameters) => { }; -var GetTideInfo2 = function (WeatherParameters) { - var Url = 'https://tidesandcurrents.noaa.gov/mdapi/latest/webapi/tidepredstations.json?'; //lat=40&lon=-73&radius=50"; - Url += 'lat=' + WeatherParameters.Latitude + '&'; - Url += 'lon=' + WeatherParameters.Longitude + '&radius=50'; - - - var MaxStationCount = 2; - var StationCount = 0; - var TideInfoCount = 0; - - WeatherParameters.WeatherTides = null; - - // Load the xml file using ajax - $.ajaxCORS({ - type: 'GET', - url: Url, - dataType: 'json', - crossDomain: true, - cache: false, - success: function (json) { - var StationIds = $(json.stationList); - - if (StationIds.length === 0) { - // No tide stations available for this location. - - - return; - } - - const Today = DateTime.local(); - const Tomorrow = Today.plus({days: 1}); - - StationIds.each(function () { - var StationName = this.name; - var StationId = this.stationId; - - //https://tidesandcurrents.noaa.gov/api/datagetter?product=predictions&application=NOS.COOPS.TAC.WL&begin_date=20181228&end_date=20181229&datum=MLLW&station=9410840&time_zone=lst_ldt&units=english&interval=hilo&format=json - var Url = 'https://tidesandcurrents.noaa.gov/api/datagetter?product=predictions&application=NOS.COOPS.TAC.WL'; - Url += `&begin_date=${Today.toFormat('yyyyMMDD')}`; - Url += `&end_date=${Tomorrow.toFormat('yyyyMMDD')}`; - Url += `&datum=MLLW&station=${StationId}`; - Url += '&time_zone=lst_ldt&units=english&interval=hilo&format=json'; - - if (WeatherParameters.WeatherTides === null) { - WeatherParameters.WeatherTides = []; - } - - var WeatherTide = { - StationId: StationId, - }; - WeatherTide.StationName = StationName; - WeatherParameters.WeatherTides.push(WeatherTide); - - // Load the xml file using ajax - $.ajaxCORS({ - type: 'GET', - url: Url, - dataType: 'json', - crossDomain: true, - cache: false, - success: function (json) { - - if (json.error) { - console.error(json.error); - } - - var TideTypes = []; - var TideTimes = []; - var TideDays = []; - - var Predictions = json.predictions; - - var Index = 0; - - $(Predictions).each(function () { - if (Index > 3) { - return false; - } - - var Now = new Date(); - var date = new Date(this.t); - - // Skip elements that are less than the current time. - if (date.getTime() < Now.getTime()) { - return true; - } - - switch (this.type) { - case 'H': - TideTypes.push('high'); - break; - default: - TideTypes.push('low'); - break; - } - - TideTimes.push(date.toTimeAMPM()); - TideDays.push(date.getDayShortName()); - - Index++; - }); - - $(TideTimes).each(function (Index) { - var TideTime = this.toString(); - TideTime = TideTime.replaceAll(' AM', 'am'); - TideTime = TideTime.replaceAll(' PM', 'pm'); - - if (TideTime.startsWith('0')) { - TideTime = TideTime.substr(1); - } - - TideTimes[Index] = TideTime; - }); - - WeatherTide.TideTypes = TideTypes; - WeatherTide.TideTimes = TideTimes; - WeatherTide.TideDays = TideDays; - - TideInfoCount++; - if (TideInfoCount >= MaxStationCount) { - PopulateTideInfo(WeatherParameters); - - - } - }, - error: function (xhr, error, errorThrown) { - console.error('GetTideInfo failed: ' + errorThrown); - - }, - }); - - StationCount++; - if (StationCount >= MaxStationCount) { - return false; - } - }); - - }, - error: function (xhr, error, errorThrown) { - console.error('GetTideInfo failed: ' + errorThrown); - }, - }); -}; - -var PopulateTideInfo = function (WeatherParameters) { - if (WeatherParameters === null || (_DontLoadGifs && WeatherParameters.Progress.Almanac !== LoadStatuses.Loaded)) { - return; - } - - var AlmanacInfo = WeatherParameters.AlmanacInfo; - var WeatherTides = WeatherParameters.WeatherTides; - - // Draw canvas - var canvas = canvasAlmanacTides[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', 'Tides'); - - var Sunrise = ''; - if (isNaN(AlmanacInfo.TodaySunRise)) { - Sunrise = 'None'; - } else { - Sunrise = AlmanacInfo.TodaySunRise.getFormattedTime(); - Sunrise = Sunrise.replaceAll(' am', 'am'); - Sunrise = Sunrise.replaceAll(' pm', 'pm'); - } - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 115, 375, 'Sunrise ' + Sunrise, 2); - - var Sunset = ''; - if (isNaN(AlmanacInfo.TodaySunSet)) { - Sunset = 'None'; - } else { - Sunset = AlmanacInfo.TodaySunSet.getFormattedTime(); - Sunset = Sunset.replaceAll(' am', 'am'); - Sunset = Sunset.replaceAll(' pm', 'pm'); - } - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 360, 375, 'Set ' + Sunset, 2); - - var y = 140; - var x = 0; - $(WeatherTides).each(function () { - var WeatherTide = this; - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 315, y, (WeatherTide.StationName + ' Tides').substr(0, 32), 2, 'center'); - y += 40; - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 70, y, 'Lows:', 2); - x = 360; - $(WeatherTide.TideTypes).each(function (Index) { - var TideType = this.toString(); - - if (TideType !== 'low') { - return true; - } - - var TideTime = WeatherTide.TideTimes[Index]; - var TideDay = WeatherTide.TideDays[Index]; - - if (_Units === Units.Metric) { - TideTime = utils.calc.TimeTo24Hour(TideTime); - } - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', x, y, TideTime + ' ' + TideDay, 2, 'right'); - x += 200; - }); - y += 40; - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 70, y, 'Highs:', 2); - x = 360; - $(WeatherTide.TideTypes).each(function (Index) { - var TideType = this.toString(); - - if (TideType !== 'high') { - return true; - } - - var TideTime = WeatherTide.TideTimes[Index]; - var TideDay = WeatherTide.TideDays[Index]; - - if (_Units === Units.Metric) { - TideTime = utils.calc.TimeTo24Hour(TideTime); - } - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', x, y, TideTime + ' ' + TideDay, 2, 'right'); - x += 200; - }); - y += 40; - - }); - - //WeatherParameters.Progress.Almanac = LoadStatuses.Loaded; - - UpdateWeatherCanvas(WeatherParameters, canvasAlmanacTides); - }; - //BackGroundImage.src = "images/BackGround1_1.png"; - //BackGroundImage.src = "images/BackGround1_" + _Themes.toString() + ".png"; - BackGroundImage.src = 'images/BackGround1_1.png'; -}; var GetOutlook = function (WeatherParameters) { WeatherParameters.Outlook = null; @@ -711,665 +465,6 @@ var GetOutlookDescription = function (OutlookIndicator) { } }; -var GetMarineForecast = async (WeatherParameters) => { - - var Url = 'https://l-36.com/weather_marine_cg.php?lat_long2='; - Url += encodeURIComponent(WeatherParameters.Latitude) + ',' + encodeURIComponent(WeatherParameters.Longitude); - - WeatherParameters.MarineForecast = null; - - // Load the xml file using ajax - $.ajaxCORS({ - type: 'GET', - url: Url, - dataType: 'html', - crossDomain: true, - cache: false, - success: function (html) { - var $html = $(html); - $html.find('[src]').attr('src', ''); // Prevents the browser from loading any images on this page. - var MarineZoneId = null; - - var select = $html.find('select[name=zone1]'); - var options = select.find('option'); - if (options.length !== 0) { - MarineZoneId = options.val(); - } - - WeatherParameters.MarineZoneId = MarineZoneId; - - if (MarineZoneId === null) { - GetWeatherForecast(_WeatherParameters); - return; - } - - var Url = 'https://forecast.weather.gov/shmrn.php?mz='; - Url += MarineZoneId; - - // Load the xml file using ajax - $.ajaxCORS({ - type: 'GET', - url: Url, - dataType: 'html', - crossDomain: true, - cache: false, - success: function (html) { - var $html = $(html); - $html.find('[src]').attr('src', ''); // Prevents the browser from loading any images on this page. - - if ($html.text().indexOf('No Current Marine Product for Zone ') !== -1) { - GetWeatherForecast(_WeatherParameters); - - return; - } - - var MarineForecast = {}; - - MarineForecast.Warning = ''; - //var spanWarn = $html.find(".warn"); - //if (spanWarn.length !== 0) - //{ - // MarineForecast.Warning = spanWarn.text().trim(); - // MarineForecast.Warning = MarineForecast.Warning.replace(" For Hazardous Seas", ""); - //} - var fontWarning = $html.find('font[size=\'+1\'][color=\'#FF0000\']'); - if (fontWarning.length !== 0) { - MarineForecast.Warning = fontWarning.text().trim(); - //MarineForecast.Warning = MarineForecast.Warning.replace(" For Hazardous Seas", ""); - - var Index = MarineForecast.Warning.indexOf(' FOR HAZARDOUS SEAS'); - if (Index !== -1) { - MarineForecast.Warning = MarineForecast.Warning.substr(0, Index); - } - - var Index2 = MarineForecast.Warning.indexOf(' IN EFFECT'); - if (Index2 !== -1) { - MarineForecast.Warning = MarineForecast.Warning.substr(0, Index2); - } - - MarineForecast.Warning = MarineForecast.Warning.capitalize(); - } - - MarineForecast.SeasOrWaves = 'SEAS'; - - var fontForecast = $html.find('font[size=\'+1\'][color=\'#800000\']'); - fontForecast.each(function (DayIndex) { - var Day = $(this); - var ForecastText = $(Day.parent()[0].nextSibling).text().trim().toUpperCase(); - ForecastText = ForecastText.replaceAll('\n', '').replaceAll(String.fromCharCode(160), ' '); - - var DayName = Day.text().trim().capitalize(); - if (_DayLongNames.hasOwnProperty(DayName)) { - DayName = _DayLongNames[DayName]; - } else if (DayName === 'Overnight') { - DayName = 'Tonight'; - } - DayName = DayName.replaceAll('Rest Of ', ''); - - var WindSpeedLow = 0; - var WindSpeedHigh = 0; - var WindSpeedLowC = 0; - var WindSpeedHighC = 0; - var WindDirection = ''; - var TideLow = 0; - var TideHigh = 0; - var TideLowC = 0; - var TideHighC = 0; - var TideConditions = ''; - var Index = 0; - var Index2 = 0; - var Offset = 0; - - if (ForecastText.indexOf('N WINDS ') !== -1 || ForecastText.indexOf('N WIND ') !== -1 || ForecastText.indexOf('NORTH WINDS ') !== -1 || ForecastText.indexOf('NORTH WIND ') !== -1) { - WindDirection = 'N'; - } else if (ForecastText.indexOf('S WINDS ') !== -1 || ForecastText.indexOf('S WIND ') !== -1 || ForecastText.indexOf('SOUTH WINDS ') !== -1 || ForecastText.indexOf('SOUTH WIND ') !== -1) { - WindDirection = 'S'; - } else if (ForecastText.indexOf('E WINDS ') !== -1 || ForecastText.indexOf('E WIND ') !== -1 || ForecastText.indexOf('EAST WINDS ') !== -1 || ForecastText.indexOf('EAST WIND ') !== -1) { - WindDirection = 'E'; - } else if (ForecastText.indexOf('W WINDS ') !== -1 || ForecastText.indexOf('W WIND ') !== -1 || ForecastText.indexOf('WEST WINDS ') !== -1 || ForecastText.indexOf('WEST WIND ') !== -1) { - WindDirection = 'W'; - } - if (ForecastText.indexOf('NE WINDS ') !== -1 || ForecastText.indexOf('NE WIND ') !== -1 || ForecastText.indexOf('NORTHEAST WINDS ') !== -1 || ForecastText.indexOf('NORTHEAST WIND ') !== -1) { - WindDirection = 'NE'; - } else if (ForecastText.indexOf('SE WINDS ') !== -1 || ForecastText.indexOf('SE WIND ') !== -1 || ForecastText.indexOf('SOUTHEAST WINDS ') !== -1 || ForecastText.indexOf('SOUTHEAST WIND ') !== -1) { - WindDirection = 'SE'; - } else if (ForecastText.indexOf('NW WINDS ') !== -1 || ForecastText.indexOf('NW WIND ') !== -1 || ForecastText.indexOf('NORTHWEST WINDS ') !== -1 || ForecastText.indexOf('NORTHWEST WIND ') !== -1) { - WindDirection = 'NW'; - } else if (ForecastText.indexOf('SW WINDS ') !== -1 || ForecastText.indexOf('SW WIND ') !== -1 || ForecastText.indexOf('SOUTHWEST WINDS ') !== -1) { - WindDirection = 'SW'; - } - - Index = -1; - if (Index === -1) { Index = ForecastText.indexOf(' WINDS AROUND '); Offset = 14; } - if (Index === -1) { Index = ForecastText.indexOf(' WIND TO '); Offset = 9; } - if (Index !== -1) { - Index += Offset; - Index2 = ForecastText.indexOf(' KT', Index); - if (Index2 === -1) Index2 = ForecastText.indexOf(' KNOT', Index); - WindSpeedHigh = parseInt(ForecastText.substr(Index, Index2 - Index)); - } else { - Index = -1; - if (Index === -1) { Index = ForecastText.indexOf(' WINDS '); Offset = 6; } - if (Index === -1) { Index = ForecastText.indexOf(' WIND '); Offset = 5;} - if (Index !== -1) { - Index += Offset; - - Index2 = ForecastText.indexOf(' TO ', Index); - if (Index2 === -1) { - Index2 = ForecastText.indexOf(' KT', Index); - if (Index2 === -1) Index2 = ForecastText.indexOf(' KNOT', Index); - WindSpeedHigh = parseInt(ForecastText.substr(Index, Index2 - Index)); - WindSpeedLow = WindSpeedHigh; - } else { - WindSpeedLow = parseInt(ForecastText.substr(Index, Index2 - Index)); - Index = Index2 + 4; - Index2 = ForecastText.indexOf(' KT', Index); - if (Index2 === -1) Index2 = ForecastText.indexOf(' KNOT', Index); - WindSpeedHigh = parseInt(ForecastText.substr(Index, Index2 - Index)); - - if (isNaN(WindSpeedLow)) { - WindSpeedLow = WindSpeedHigh; - } else if (isNaN(WindSpeedHigh)) { - WindSpeedHigh = WindSpeedLow; - } - } - } - } - - Index = -1; - if (Index === -1) { Index = ForecastText.indexOf('SEAS AROUND '); Offset = 12; } - if (Index === -1) { Index = ForecastText.indexOf('WAVES AROUND '); Offset = 13; MarineForecast.SeasOrWaves = 'WAVES'; } - if (Index !== -1) { - Index += Offset; - Index2 = ForecastText.indexOf(' FT', Index); - TideHigh = parseInt(ForecastText.substr(Index, Index2 - Index)); - TideLow = TideHigh; - } else { - Index = -1; - if (Index === -1) { Index = ForecastText.indexOf('SEAS 1 FT OR LESS'); } - if (Index === -1) { Index = ForecastText.indexOf('SEAS LESS THAN 1 FT'); } - if (Index === -1) { Index = ForecastText.indexOf('WAVES 1 FT OR LESS'); MarineForecast.SeasOrWaves = 'WAVES'; } - if (Index === -1) { Index = ForecastText.indexOf('WAVES LESS THAN 1 FT'); MarineForecast.SeasOrWaves = 'WAVES'; } - if (Index !== -1) { - TideHigh = 1; - } else { - Index = -1; - if (Index === -1) { Index = ForecastText.indexOf('SEAS '); Offset = 5; } - if (Index === -1) { Index = ForecastText.indexOf('WAVES '); Offset = 6; MarineForecast.SeasOrWaves = 'WAVES'; } - if (Index !== -1) { - Index += Offset; - - Index2 = ForecastText.indexOf(' FT OR LESS', Index); - if (Index2 !== -1) { - TideHigh = parseInt(ForecastText.substr(Index, Index2 - Index)); - TideLow = 0; - } else { - Index2 = ForecastText.indexOf(' TO ', Index); - if (Index2 === -1) { - Index2 = ForecastText.indexOf(' FT', Index); - TideHigh = parseInt(ForecastText.substr(Index, Index2 - Index)); - TideLow = TideHigh; - } else { - TideLow = parseInt(ForecastText.substr(Index, Index2 - Index)); - Index = Index2 + 4; - Index2 = ForecastText.indexOf(' FT', Index); - if (Index2 === -1) { Index2 = ForecastText.indexOf(' FEET', Index); } - TideHigh = parseInt(ForecastText.substr(Index, Index2 - Index)); - } - - if (isNaN(TideLow)) { - TideLow = TideHigh; - } else if (isNaN(TideHigh)) { - TideHigh = TideLow; - } - } - } - } - } - - TideConditions = 'LIGHT'; - - if (TideHigh > 7) { - TideConditions = 'ROUGH'; - } else if (TideHigh > 4) { - TideConditions = 'CHOPPY'; - } - - TideHighC = utils.units.FeetToMeters(TideHigh); - TideLowC = utils.units.FeetToMeters(TideLow); - WindSpeedHighC = WindSpeedHigh; - WindSpeedLowC = WindSpeedLow; - - if (TideHighC === 0 && TideHigh > 0) { - TideHighC = 1; - } - - switch (DayIndex) { - case 0: - default: - // Today/Tonight - MarineForecast.TodayDayName = DayName; - MarineForecast.TodayWindSpeedHigh = WindSpeedHigh; - MarineForecast.TodayWindSpeedLow = WindSpeedLow; - MarineForecast.TodayWindDirection = WindDirection; - MarineForecast.TodayTideLow = TideLow; - MarineForecast.TodayTideHigh = TideHigh; - MarineForecast.TodayTideConditions = TideConditions; - MarineForecast.TodayTideHighC = TideHighC; - MarineForecast.TodayTideLowC = TideLowC; - MarineForecast.TodayWindSpeedHighC = WindSpeedHighC; - MarineForecast.TodayWindSpeedLowC = WindSpeedLowC; - return true; - - case 1: - // Tomorrow - MarineForecast.TomorrowDayName = DayName; - MarineForecast.TomorrowWindSpeedHigh = WindSpeedHigh; - MarineForecast.TomorrowWindSpeedLow = WindSpeedLow; - MarineForecast.TomorrowWindDirection = WindDirection; - MarineForecast.TomorrowTideLow = TideLow; - MarineForecast.TomorrowTideHigh = TideHigh; - MarineForecast.TomorrowTideConditions = TideConditions; - MarineForecast.TomorrowTideHighC = TideHighC; - MarineForecast.TomorrowTideLowC = TideLowC; - MarineForecast.TomorrowWindSpeedHighC = WindSpeedHighC; - MarineForecast.TomorrowWindSpeedLowC = WindSpeedLowC; - return false; - } - }); - - WeatherParameters.MarineForecast = MarineForecast; - - PopulateMarineForecast(WeatherParameters); - - GetWeatherForecast(_WeatherParameters); - - }, - error: function (xhr, error, errorThrown) { - console.error('GetMarineForecast failed: ' + errorThrown); - }, - }); - - }, - error: function (xhr, error, errorThrown) { - console.error('GetMarineForecast failed: ' + errorThrown); - }, - }); -}; - -var PopulateMarineForecast = function (WeatherParameters) { - if (WeatherParameters === null || (_DontLoadGifs && WeatherParameters.Progress.WordedForecast !== LoadStatuses.Loaded)) { - return; - } - - var MarineForecast = WeatherParameters.MarineForecast; - - // Draw canvas - var canvas = canvasMarineForecast[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); - - DrawTitleText(context, 'Marine Forecast'); - - // Warning Message - if (MarineForecast.Warning !== '') { - DrawBorder(context, '#000000', 4, 100, 135, 440, 40); - DrawText(context, 'Star4000', '24pt', '#ffffff', 320, 165, MarineForecast.Warning, true, 'center'); - } - - DrawText(context, 'Star4000', '24pt', '#ffffff', 80, 250, 'WINDS:', true); - DrawText(context, 'Star4000', '24pt', '#ffffff', 80, 360, MarineForecast.SeasOrWaves + ':', true); - - // Today's Forecast - DrawText(context, 'Star4000', '24pt', '#ffff00', 280, 210, MarineForecast.TodayDayName, true, 'center'); - DrawText(context, 'Star4000', '24pt', '#ffffff', 280, 250, MarineForecast.TodayWindDirection, true, 'center'); - - var TodayWindSpeedHigh = 0; - var TodayWindSpeedLow = 0; - switch (_Units) { - case Units.English: - TodayWindSpeedHigh = MarineForecast.TodayWindSpeedHigh; - TodayWindSpeedLow = MarineForecast.TodayWindSpeedLow; - break; - default: - TodayWindSpeedHigh = MarineForecast.TodayWindSpeedHighC; - TodayWindSpeedLow = MarineForecast.TodayWindSpeedLowC; - break; - } - - var TodayWindSpeed = TodayWindSpeedHigh.toString() + 'kts'; - //if (TodayWindSpeedLow > 0) - if (TodayWindSpeedLow !== TodayWindSpeedHigh) { - TodayWindSpeed = TodayWindSpeedLow.toString() + ' - ' + TodayWindSpeed; - } - DrawText(context, 'Star4000', '24pt', '#ffffff', 280, 285, TodayWindSpeed, true, 'center'); - - DrawBorder(context, 'rgb(172, 165, 251)', '4', 205, 305, 150, 90); - - var TodayTideHigh = 0; - var TodayTideLow = 0; - var TideUnit = ''; - switch (_Units) { - case Units.English: - TodayTideHigh = MarineForecast.TodayTideHigh; - TodayTideLow = MarineForecast.TodayTideLow; - TideUnit = '\''; - break; - default: - TodayTideHigh = MarineForecast.TodayTideHighC; - TodayTideLow = MarineForecast.TodayTideLowC; - TideUnit = 'm'; - break; - } - - var TodayTide = ''; - if (TodayTideHigh > 0) { - TodayTide = TodayTideHigh.toString() + TideUnit; - //if (TodayTideLow > 0) - if (TodayTideLow !== TodayTideHigh) { - TodayTide = TodayTideLow.toString() + TideUnit + ' - ' + TodayTide; - } - } - DrawText(context, 'Star4000', '24pt', '#ffffff', 280, 340, TodayTide, true, 'center'); - - DrawText(context, 'Star4000', '24pt', '#ffffff', 280, 390, MarineForecast.TodayTideConditions, true, 'center'); - - //DrawWaves(context, 240, 340, "rgb(172, 165, 251)", "ROUGH"); - DrawWaves(context, 240, 340, 'rgb(172, 165, 251)', MarineForecast.TodayTideConditions); - - // Tomorrow's Forecast - DrawText(context, 'Star4000', '24pt', '#ffff00', 490, 210, MarineForecast.TomorrowDayName, true, 'center'); - DrawText(context, 'Star4000', '24pt', '#ffffff', 490, 250, MarineForecast.TomorrowWindDirection, true, 'center'); - - var TomorrowWindSpeedHigh = 0; - var TomorrowWindSpeedLow = 0; - switch (_Units) { - case Units.English: - TomorrowWindSpeedHigh = MarineForecast.TomorrowWindSpeedHigh; - TomorrowWindSpeedLow = MarineForecast.TomorrowWindSpeedLow; - break; - default: - TomorrowWindSpeedHigh = MarineForecast.TomorrowWindSpeedHighC; - TomorrowWindSpeedLow = MarineForecast.TomorrowWindSpeedLowC; - break; - } - - var TomorrowWindSpeed = TomorrowWindSpeedHigh.toString() + 'kts'; - //if (TomorrowWindSpeedLow > 0) - if (TomorrowWindSpeedLow !== TomorrowWindSpeedHigh) { - TomorrowWindSpeed = TomorrowWindSpeedLow.toString() + ' - ' + TomorrowWindSpeed; - } - DrawText(context, 'Star4000', '24pt', '#ffffff', 490, 285, TomorrowWindSpeed, true, 'center'); - - DrawBorder(context, 'rgb(172, 165, 251)', '4', 410, 305, 150, 90); - - var TomorrowTideHigh = 0; - var TomorrowTideLow = 0; - - switch (_Units) { - case Units.English: - TomorrowTideHigh = MarineForecast.TomorrowTideHigh; - TomorrowTideLow = MarineForecast.TomorrowTideLow; - TideUnit = '\''; - break; - default: - TomorrowTideHigh = MarineForecast.TomorrowTideHighC; - TomorrowTideLow = MarineForecast.TomorrowTideLowC; - TideUnit = 'm'; - break; - } - - var TomorrowTide = ''; - if (TomorrowTideHigh > 0) { - TomorrowTide = TomorrowTideHigh.toString() + TideUnit; - //if (TomorrowTideLow > 0) - if (TomorrowTideLow !== TomorrowTideHigh) { - TomorrowTide = TomorrowTideLow.toString() + TideUnit + ' - ' + TomorrowTide; - } - } - DrawText(context, 'Star4000', '24pt', '#ffffff', 490, 340, TomorrowTide, true, 'center'); - - DrawText(context, 'Star4000', '24pt', '#ffffff', 490, 390, MarineForecast.TomorrowTideConditions, true, 'center'); - - DrawWaves(context, 445, 340, 'rgb(172, 165, 251)', MarineForecast.TomorrowTideConditions); - - //WeatherParameters.Progress.Almanac = LoadStatuses.Loaded; - - UpdateWeatherCanvas(WeatherParameters, canvasMarineForecast); - }; - BackGroundImage.src = 'images/BackGround8_1.png'; - //BackGroundImage.src = "images/BackGround8_" + _Themes.toString() + ".png"; - -}; - -var DrawWaves = function (context, x, y, color, conditions) { - //http://www.w3schools.com/tags/canvas_arc.asp - - switch (conditions) { - case 'LIGHT': - y -= 10; - context.beginPath(); - context.arc(x, y, 35, Math.PI * 0.3, Math.PI * 0.7); - context.strokeStyle = color; - context.lineWidth = 4; - context.stroke(); - context.beginPath(); - x += 40; - context.arc(x, y, 35, Math.PI * 0.3, Math.PI * 0.7); - context.stroke(); - context.beginPath(); - x += 40; - context.arc(x, y, 35, Math.PI * 0.3, Math.PI * 0.7); - context.stroke(); - break; - - case 'CHOPPY': - context.beginPath(); - context.arc(x, y, 25, Math.PI * 0.2, Math.PI * 0.8); - context.strokeStyle = color; - context.lineWidth = 4; - context.stroke(); - context.beginPath(); - x += 40; - context.arc(x, y, 25, Math.PI * 0.2, Math.PI * 0.8); - context.stroke(); - context.beginPath(); - x += 40; - context.arc(x, y, 25, Math.PI * 0.2, Math.PI * 0.8); - context.stroke(); - break; - - case 'ROUGH': - context.beginPath(); - context.arc(x, y, 20, Math.PI * 0.1, Math.PI * 0.9); - context.strokeStyle = color; - context.lineWidth = 4; - context.stroke(); - context.beginPath(); - x += 40; - context.arc(x, y, 20, Math.PI * 0.1, Math.PI * 0.9); - context.stroke(); - context.beginPath(); - x += 40; - context.arc(x, y, 20, Math.PI * 0.1, Math.PI * 0.9); - context.stroke(); - break; - default: - } - -}; - -var GetAirQuality3 = function (WeatherParameters) { - if (!WeatherParameters.ZipCode) { - GetMarineForecast(WeatherParameters); - return; - } - - // TODO, this code does not currently execute because no zip code is provided - - var ZipCode = WeatherParameters.ZipCode; - let date = DateTime.local(); - if (date.hour >= 12) { - date = date.plus({days:1}); - } - var _Date = date.getYYYYMMDD(); - - var Url = 'http://www.airnowapi.org/aq/forecast/zipCode/?format=application/json&distance=25&API_KEY=E0E326E6-E199-4ABC-B382-0F9F9522E143'; - Url += '&zipCode=' + encodeURIComponent(ZipCode); - Url += '&date=' + encodeURIComponent(_Date); - - WeatherParameters.AirQuality = null; - - // Load the xml file using ajax - $.ajaxCORS({ - type: 'GET', - url: Url, - dataType: 'json', - crossDomain: true, - cache: false, - success: function (json) { - var maxAQI = 0; - var City = ''; - - $(json).each(function () { - if (this.AQI > maxAQI) { - City = this.ReportingArea; - maxAQI = this.AQI; - } - }); - - if (maxAQI === 0) { - GetMarineForecast(WeatherParameters); - return; - } - - var AirQuality = {}; - - AirQuality.City = City; - AirQuality.Date = date; - AirQuality.IndexValue = maxAQI; - - WeatherParameters.AirQuality = AirQuality; - - PopulateAirQuality(WeatherParameters); - - GetMarineForecast(WeatherParameters); - }, - error: function (xhr, error, errorThrown) { - console.error('GetAirQuality failed: ' + errorThrown); - - GetMarineForecast(WeatherParameters); - }, - }); -}; - - -var PopulateAirQuality = function (WeatherParameters) { - if (WeatherParameters === null || (_DontLoadGifs && WeatherParameters.Progress.WordedForecast !== LoadStatuses.Loaded)) { - return; - } - - var AirQuality = WeatherParameters.AirQuality; - - // Draw canvas - var canvas = canvasAirQuality[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, 640, 399, _SideColor1, _SideColor2); - - // Title - var DayName = AirQuality.Date.getDayName(); - DrawTitleText(context, 'Air Quality', 'For ' + DayName); - - // Hazardous - DrawBox(context, '#FF0000', 320, 90, 320, 309); - DrawTriangle(context, '#FF0000', 300, 90, 320, 90, 320, 110); - DrawText(context, 'Star4000 Small', '20pt', '#FFFFFF', 320, 105, 'HAZARDOUS', 1); - - // Very Unhealthy - DrawBox(context, '#FF8000', 320, 110, 230, 289); - DrawTriangle(context, '#FF8000', 300, 110, 320, 110, 320, 130); - DrawTriangle(context, '#FF0000', 530, 110, 550, 110, 550, 130); - DrawText(context, 'Star4000 Small', '20pt', '#FFFFFF', 320, 125, 'VERY UNHEALTHY', 1); - - // Unhealthy - DrawBox(context, '#FFB000', 320, 130, 160, 269); - DrawTriangle(context, '#FFB000', 300, 130, 320, 130, 320, 150); - DrawTriangle(context, '#FF8000', 460, 130, 480, 130, 480, 150); - DrawText(context, 'Star4000 Small', '20pt', '#FFFFFF', 320, 145, 'UNHEALTHY', 1); - - // Good - DrawBox(context, '#FFFF00', 320, 150, 70, 249); - DrawTriangle(context, '#FFFF00', 300, 150, 320, 150, 320, 170); - DrawTriangle(context, '#FFB000', 370, 150, 390, 150, 390, 170); - DrawText(context, 'Star4000 Small', '20pt', '#FFFFFF', 320, 165, 'GOOD', 1); - - // City Name - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 240, 280, AirQuality.City, 2, 'right'); - - // Air Quality Value - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 310, 280, AirQuality.IndexValue.toString(), 2, 'right'); - - // Draw Bar - var BarWidth = GetAqiWidth(AirQuality.IndexValue); - DrawHorizontalGradient(context, 315, 245, 315 + BarWidth, 295, '#404040', '#B0B0B0'); - DrawBox(context, '#000000', 315 + BarWidth - 2, 245, 2, 50); - DrawBox(context, '#FFFFFF', 315, 245, BarWidth, 2); - DrawBox(context, '#FFFFFF', 315, 245, 2, 50); - DrawBox(context, '#000000', 315, 293, BarWidth, 2); - - UpdateWeatherCanvas(WeatherParameters, canvasAirQuality); - }; - BackGroundImage.src = 'images/BackGround9_1.png'; - //BackGroundImage.src = "images/BackGround9_" + _Themes.toString() + ".png"; - -}; - -var GetAqiWidth = function (IndexValue) { - var BarWidth = 0; - - if (IndexValue <= 100) { - BarWidth = (IndexValue * 70) / 100; - } else if (IndexValue <= 200) { - //BarWidth = 70 + ((IndexValue - 100) * 160) / 200; - BarWidth = 70 + ((IndexValue - 100) * 90) / 100; - } else if (IndexValue <= 300) { - //BarWidth = 160 + ((IndexValue - 200) * 230) / 300; - BarWidth = 160 + ((IndexValue - 200) * 70) / 100; - } else if (IndexValue <= 500) { - //BarWidth = 230 + ((IndexValue - 300) * 320) / 500; - BarWidth = 230 + ((IndexValue - 300) * 90) / 200; - } - BarWidth = Math.round(BarWidth); - - return BarWidth; -}; - -var GetAqiDescription = function (IndexValue) { - var Description = 'unknown'; - - if (IndexValue <= 100) { - Description = 'good'; - } else if (IndexValue <= 200) { - Description = 'unhealthy'; - } else if (IndexValue <= 300) { - Description = 'very unhealthy'; - } else if (IndexValue <= 500) { - Description = 'hazardous'; - } - - return Description; -}; String.prototype.capitalize = function () { @@ -1481,29 +576,13 @@ $(() => { canvasProgress = $('#canvasProgress'); divProgress = $('#divProgress'); - divDopplerRadarMap = $('#divDopplerRadarMap'); canvasLocalRadar = $('#canvasLocalRadar'); - divRegionalForecastMap1 = $('#divRegionalForecastMap1'); - divRegionalForecastMap2 = $('#divRegionalForecastMap2'); canvasRegionalForecast1 = $('#canvasRegionalForecast1'); canvasRegionalForecast2 = $('#canvasRegionalForecast2'); - divRegionalCurrentMap = $('#divRegionalCurrentMap'); canvasRegionalObservations = $('#canvasRegionalObservations'); - divTemperature = $('#divTemperature'); - divStation = $('#divStation'); - divConditions = $('#divConditions'); - divHumidity = $('#divHumidity'); - divIcon = $('#divIcon'); - divDewpoint = $('#divDewpoint'); - divCeiling = $('#divCeiling'); - divVisibility = $('#divVisibility'); - divWind = $('#divWind'); - divPressure = $('#divPressure'); - divGust = $('#divGust'); - divHeatIndex = $('#divHeatIndex'); canvasCurrentWeather = $('#canvasCurrentWeather'); canvasExtendedForecast1 = $('#canvasExtendedForecast1'); @@ -1524,15 +603,10 @@ $(() => { divOutlookTemp = $('#divOutlookTemp'); divOutlookPrcp = $('#divOutlookPrcp'); - tblTravelCities = $('#tblTravelCities'); - divTravelCitiesScroll = $('#divTravelCitiesScroll'); canvasTravelForecast = $('#canvasTravelForecast'); - tblRegionalObservations = $('#tblRegionalObservations'); canvasLatestObservations = $('#canvasLatestObservations'); - audMusic = $('#audMusic'); - PopulateMusicUrls(); canvasProgress.mousemove(canvasProgress_mousemove); canvasProgress.click(canvasProgress_click); @@ -1584,275 +658,8 @@ var NavigateMenu = function () { Navigate(0); _PlayMs = 0; }; -var NavigateNext = function () { - if (_CurrentCanvasType === CanvasTypes.Progress) { - _PlayMs = 0; - } else { - _PlayMs += 10000; - } - - _IsSpeaking = false; // Force navigation - - UpdatePlayPosition(); -}; -var NavigatePrevious = function () { - if (_CurrentCanvasType === CanvasTypes.Progress) { - _PlayMs = _PlayMsOffsets.End - 10000; - } else { - _PlayMs -= 10000; - } - - _IsSpeaking = false; // Force navigation - - UpdatePlayPosition(); -}; -const NavigateReset = () => Navigate(); - -const Navigate = (offset) => { - const LocalForecastScreenTexts = _WeatherParameters.LocalForecastScreenTexts; - const Hazards = _WeatherParameters.WeatherHazardConditions.Hazards; - const $cnvTravelCitiesScroll = $('#cnvTravelCitiesScroll'); - const $cnvHazardsScroll = $('#cnvHazardsScroll'); - - if (offset === 0) { - _CurrentCanvasType = _FirstCanvasType; - } else if (offset !== undefined) { - switch (offset) { - case 1: - switch (_CurrentCanvasType) { - case CanvasTypes.LocalForecast: - if (_WeatherParameters.Progress.WordedForecast === LoadStatuses.Loaded) { - if (LocalForecastScreenTexts) { - if (_UpdateLocalForecastIndex < LocalForecastScreenTexts.length - 1) { - UpdateLocalForecast(1); - return; - } - } - } - break; - case CanvasTypes.Hazards: - if (_WeatherParameters.Progress.Hazards === LoadStatuses.Loaded && Hazards.length > 0) { - if (_UpdateHazardsY < $cnvHazardsScroll.height()) { - UpdateHazards(1); - return; - } - } - break; - - case CanvasTypes.LocalRadar: - if (_WeatherParameters.Progress.DopplerRadar === LoadStatuses.Loaded) { - if (_DopplerRadarImageIndex > 0) { - UpdateDopplarRadarImage(1); - return; - } - } - break; - default: - } - - break; - - case -1: - switch (_CurrentCanvasType) { - case CanvasTypes.LocalForecast: - if (_WeatherParameters.Progress.WordedForecast === LoadStatuses.Loaded) { - if (LocalForecastScreenTexts) { - if (_UpdateLocalForecastIndex > 0) { - UpdateLocalForecast(-1); - return; - } - } - } - break; - - case CanvasTypes.Hazards: - if (_WeatherParameters.Progress.Hazards === LoadStatuses.Loaded && Hazards.length > 0) { - if (_UpdateHazardsY > 0) { - UpdateHazards(-1); - return; - } - } - break; - - case CanvasTypes.LocalRadar: - if (_WeatherParameters.Progress.DopplerRadar === LoadStatuses.Loaded) { - if (_DopplerRadarImageIndex < (_DopplerRadarImageMax - 1)) { - UpdateDopplarRadarImage(-1); - return; - } - } - break; - default: - } - - break; - default: - } - - _CurrentCanvasType += offset; - if (_CurrentCanvasType > _LastCanvasType) { - _CurrentCanvasType = _FirstCanvasType; - } else if (_CurrentCanvasType < _FirstCanvasType) { - _CurrentCanvasType = _LastCanvasType; - } - - } - - //window.location.hash = ""; - - switch (_CurrentCanvasType) { - case CanvasTypes.Progress: - //window.location.hash = "aProgress"; - canvasProgress.scrollIntoView(); - break; - case CanvasTypes.CurrentWeather: - if (_WeatherParameters.Progress.CurrentConditions !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aCurrentWeather"; - //canvasCurrentWeather[0].scrollIntoView(); - //canvasCurrentWeather[0].scrollIntoView(true); - //$("body").scrollTop(canvasCurrentWeather.offset().top); - //canvasCurrentWeather[0].parentNode.scrollTop = canvasCurrentWeather[0].offsetTop; - canvasCurrentWeather.scrollIntoView(); - break; - case CanvasTypes.LatestObservations: - if (_WeatherParameters.Progress.NearbyConditions !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aLatestObservations"; - canvasLatestObservations.scrollIntoView(); - break; - case CanvasTypes.TravelForecast: - if (_WeatherParameters.Progress.TravelForecast !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - if (offset === 1) { - UpdateTravelCities(0); - } else if (offset === -1) { - UpdateTravelCities(Infinity); - } - - canvasTravelForecast.scrollIntoView(); - break; - case CanvasTypes.RegionalForecast1: - if (_WeatherParameters.Progress.TomorrowsRegionalMap !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aRegionalForecast"; - canvasRegionalForecast1.scrollIntoView(); - break; - case CanvasTypes.RegionalForecast2: - if (_WeatherParameters.Progress.TomorrowsRegionalMap !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aRegionalForecast"; - canvasRegionalForecast2.scrollIntoView(); - break; - case CanvasTypes.RegionalObservations: - if (_WeatherParameters.Progress.CurrentRegionalMap !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aRegionalObservations"; - canvasRegionalObservations.scrollIntoView(); - break; - case CanvasTypes.LocalForecast: - if (_WeatherParameters.Progress.WordedForecast !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - if (offset === 1) { - UpdateLocalForecast(0); - } else if (offset === -1) { - UpdateLocalForecast(Infinity); - } - //window.location.hash = "aLocalForecast"; - canvasLocalForecast.scrollIntoView(); - break; - case CanvasTypes.MarineForecast: - if (_WeatherParameters.Progress.WordedForecast !== LoadStatuses.Loaded && _WeatherParameters.MarineForecast) { - if (offset) { Navigate(offset); } return; - } - canvasMarineForecast.scrollIntoView(); - break; - case CanvasTypes.AirQuality: - if (_WeatherParameters.Progress.WordedForecast !== LoadStatuses.Loaded && _WeatherParameters.AirQuality) { - if (offset) { Navigate(offset); } return; - } - canvasAirQuality.scrollIntoView(); - break; - case CanvasTypes.ExtendedForecast1: - if (_WeatherParameters.Progress.FourDayForecast !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aExtendedForecast"; - canvasExtendedForecast1.scrollIntoView(); - break; - case CanvasTypes.ExtendedForecast2: - if (_WeatherParameters.Progress.FourDayForecast !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aExtendedForecast"; - canvasExtendedForecast2.scrollIntoView(); - break; - case CanvasTypes.Almanac: - if (_WeatherParameters.Progress.Almanac !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aAlmanac"; - canvasAlmanac.scrollIntoView(); - break; - case CanvasTypes.AlmanacTides: - if (_WeatherParameters.Progress.Almanac !== LoadStatuses.Loaded && _WeatherParameters.WeatherTides) { - if (offset) { Navigate(offset); } return; - } - //window.location.hash = "aAlmanac"; - canvasAlmanacTides.scrollIntoView(); - break; - case CanvasTypes.Outlook: - if (_WeatherParameters.Progress.Almanac !== LoadStatuses.Loaded && _WeatherParameters.Outlook) { - if (offset) { Navigate(offset); } return; - } - canvasOutlook.scrollIntoView(); - break; - case CanvasTypes.LocalRadar: - if (_WeatherParameters.Progress.DopplerRadar !== LoadStatuses.Loaded) { - if (offset) { Navigate(offset); } return; - } - if (offset === 1) { - UpdateDopplarRadarImage(0); - } else if (offset === -1) { - UpdateDopplarRadarImage(Infinity); - } - //window.location.hash = "aLocalRadar"; - canvasLocalRadar.scrollIntoView(); - break; - case CanvasTypes.Hazards: - if (_WeatherParameters.Progress.Hazards !== LoadStatuses.Loaded || Hazards.length === 0) { - if (offset) { Navigate(offset); } return; - } - if (offset === 1) { - UpdateHazards(0); - } else if (offset === -1) { - UpdateHazards(Infinity); - } - //window.location.hash = "aHazards"; - canvasHazards.scrollIntoView(); - break; - default: - } - - if (Math.floor(_CurrentPosition) !== _CurrentCanvasType) { - _CurrentPosition = _CurrentCanvasType; - } - - if (_PreviousPosition !== _CurrentPosition) { - _PreviousPosition = _CurrentPosition; - SpeakUtterance(); - } - -}; $.fn.scrollIntoView = function () { const $self = this; @@ -1963,518 +770,7 @@ var _PlayMsOffsets = { Hazards_Loaded: false, }; -var AssignPlayMsOffsets = function (CalledFromProgress) { - var LocalForecastScreenTexts = _WeatherParameters.LocalForecastScreenTexts; - var cnvHazardsScroll = $('#cnvHazardsScroll'); - var Hazards = _WeatherParameters.WeatherHazardConditions.Hazards; - var Progress = _WeatherParameters.Progress; - //CurrentWeather - _PlayMsOffsets.CurrentWeather_Start = 0; - if (Progress.CurrentConditions === LoadStatuses.Loaded) { - _PlayMsOffsets.LatestObservations_Length = 10000; - } else { - _PlayMsOffsets.LatestObservations_Length = 0; - } - _PlayMsOffsets.CurrentWeather_End = _PlayMsOffsets.CurrentWeather_Start + _PlayMsOffsets.LatestObservations_Length; - - //LatestObservations - _PlayMsOffsets.LatestObservations_Start = _PlayMsOffsets.CurrentWeather_End; - if (Progress.NearbyConditions === LoadStatuses.Loaded) { - _PlayMsOffsets.LatestObservations_Length = 10000; - } else { - _PlayMsOffsets.LatestObservations_Length = 0; - } - _PlayMsOffsets.LatestObservations_End = _PlayMsOffsets.LatestObservations_Start + _PlayMsOffsets.LatestObservations_Length; - - //TravelForecast - _PlayMsOffsets.TravelForecast_Start = _PlayMsOffsets.LatestObservations_End; - if (Progress.TravelForecast === LoadStatuses.Loaded) { - _PlayMsOffsets.TravelForecast_Length = 60000; - } else { - _PlayMsOffsets.TravelForecast_Length = 0; - } - _PlayMsOffsets.TravelForecast_End = _PlayMsOffsets.TravelForecast_Start + _PlayMsOffsets.TravelForecast_Length; - - //RegionalForecast1 - _PlayMsOffsets.RegionalForecast1_Start = _PlayMsOffsets.TravelForecast_End; - if (Progress.TomorrowsRegionalMap === LoadStatuses.Loaded) { - _PlayMsOffsets.RegionalForecast1_Length = 10000; - } else { - _PlayMsOffsets.RegionalForecast1_Length = 0; - } - _PlayMsOffsets.RegionalForecast1_End = _PlayMsOffsets.RegionalForecast1_Start + _PlayMsOffsets.RegionalForecast1_Length; - - //RegionalForecast2 - _PlayMsOffsets.RegionalForecast2_Start = _PlayMsOffsets.RegionalForecast1_End; - if (Progress.TomorrowsRegionalMap === LoadStatuses.Loaded) { - _PlayMsOffsets.RegionalForecast2_Length = 10000; - } else { - _PlayMsOffsets.RegionalForecast2_Length = 0; - } - _PlayMsOffsets.RegionalForecast2_End = _PlayMsOffsets.RegionalForecast2_Start + _PlayMsOffsets.RegionalForecast2_Length; - - //RegionalObservations - _PlayMsOffsets.RegionalObservations_Start = _PlayMsOffsets.RegionalForecast2_End; - if (Progress.CurrentRegionalMap === LoadStatuses.Loaded) { - _PlayMsOffsets.RegionalObservations_Length = 10000; - } else { - _PlayMsOffsets.RegionalObservations_Length = 0; - } - _PlayMsOffsets.RegionalObservations_End = _PlayMsOffsets.RegionalObservations_Start + _PlayMsOffsets.RegionalObservations_Length; - - //LocalForecast - _PlayMsOffsets.LocalForecast_Start = _PlayMsOffsets.RegionalObservations_End; - if (Progress.WordedForecast === LoadStatuses.Loaded) { - _PlayMsOffsets.LocalForecast_Length = LocalForecastScreenTexts.length * 10000; - } else { - _PlayMsOffsets.LocalForecast_Length = 0; - } - _PlayMsOffsets.LocalForecast_End = _PlayMsOffsets.LocalForecast_Start + _PlayMsOffsets.LocalForecast_Length; - - //Marine Forecast - _PlayMsOffsets.MarineForecast_Start = _PlayMsOffsets.LocalForecast_End; - if (Progress.WordedForecast === LoadStatuses.Loaded && _WeatherParameters.MarineForecast) { - _PlayMsOffsets.MarineForecast_Length = 10000; - } else { - _PlayMsOffsets.MarineForecast_Length = 0; - } - _PlayMsOffsets.MarineForecast_End = _PlayMsOffsets.MarineForecast_Start + _PlayMsOffsets.MarineForecast_Length; - - //Air Quality - _PlayMsOffsets.AirQuality_Start = _PlayMsOffsets.MarineForecast_End; - if (Progress.WordedForecast === LoadStatuses.Loaded && _WeatherParameters.AirQuality) { - _PlayMsOffsets.AirQuality_Length = 10000; - } else { - _PlayMsOffsets.AirQuality_Length = 0; - } - _PlayMsOffsets.AirQuality_End = _PlayMsOffsets.AirQuality_Start + _PlayMsOffsets.AirQuality_Length; - - //ExtendedForecast1 - _PlayMsOffsets.ExtendedForecast1_Start = _PlayMsOffsets.AirQuality_End; - if (Progress.FourDayForecast === LoadStatuses.Loaded) { - _PlayMsOffsets.ExtendedForecast1_Length = 10000; - } else { - _PlayMsOffsets.ExtendedForecast1_Length = 0; - } - _PlayMsOffsets.ExtendedForecast1_End = _PlayMsOffsets.ExtendedForecast1_Start + _PlayMsOffsets.ExtendedForecast1_Length; - - //ExtendedForecast2 - _PlayMsOffsets.ExtendedForecast2_Start = _PlayMsOffsets.ExtendedForecast1_End; - if (Progress.FourDayForecast === LoadStatuses.Loaded) { - _PlayMsOffsets.ExtendedForecast2_Length = 10000; - } else { - _PlayMsOffsets.ExtendedForecast2_Length = 0; - } - _PlayMsOffsets.ExtendedForecast2_End = _PlayMsOffsets.ExtendedForecast2_Start + _PlayMsOffsets.ExtendedForecast2_Length; - - //Almanac - _PlayMsOffsets.Almanac_Start = _PlayMsOffsets.ExtendedForecast2_End; - if (Progress.Almanac === LoadStatuses.Loaded) { - _PlayMsOffsets.Almanac_Length = 10000; - } else { - _PlayMsOffsets.Almanac_Length = 0; - } - _PlayMsOffsets.Almanac_End = _PlayMsOffsets.Almanac_Start + _PlayMsOffsets.Almanac_Length; - - //Almanac (Tides) - _PlayMsOffsets.AlmanacTides_Start = _PlayMsOffsets.Almanac_End; - if (Progress.Almanac === LoadStatuses.Loaded && _WeatherParameters.WeatherTides) { - _PlayMsOffsets.AlmanacTides_Length = 10000; - } else { - _PlayMsOffsets.AlmanacTides_Length = 0; - } - _PlayMsOffsets.AlmanacTides_End = _PlayMsOffsets.AlmanacTides_Start + _PlayMsOffsets.AlmanacTides_Length; - - //Outlook - _PlayMsOffsets.Outlook_Start = _PlayMsOffsets.AlmanacTides_End; - if (Progress.Almanac === LoadStatuses.Loaded && _WeatherParameters.Outlook) { - _PlayMsOffsets.Outlook_Length = 10000; - } else { - _PlayMsOffsets.Outlook_Length = 0; - } - _PlayMsOffsets.Outlook_End = _PlayMsOffsets.Outlook_Start + _PlayMsOffsets.Outlook_Length; - - //LocalRadar - _PlayMsOffsets.LocalRadar_Start = _PlayMsOffsets.Outlook_End; - if (Progress.DopplerRadar === LoadStatuses.Loaded) { - _PlayMsOffsets.LocalRadar_Length = 15000; - } else { - _PlayMsOffsets.LocalRadar_Length = 0; - } - _PlayMsOffsets.LocalRadar_End = _PlayMsOffsets.LocalRadar_Start + _PlayMsOffsets.LocalRadar_Length; - - //Hazards - _PlayMsOffsets.Hazards_Start = _PlayMsOffsets.LocalRadar_End; - if (Progress.Hazards === LoadStatuses.Loaded && Hazards.length > 0) { - _PlayMsOffsets.Hazards_Length = (((385 + cnvHazardsScroll.height()) / 385) * 13000) + 3000; - } else { - _PlayMsOffsets.Hazards_Length = 0; - } - _PlayMsOffsets.Hazards_End = _PlayMsOffsets.Hazards_Start + _PlayMsOffsets.Hazards_Length; - - //Global offsets - _PlayMsOffsets.Start = 0; - _PlayMsOffsets.End = _PlayMsOffsets.Hazards_End; - _PlayMsOffsets.Length = _PlayMsOffsets.Hazards_End; - - // Update the Play Position - if (CalledFromProgress) { - if (Progress.CurrentConditions === LoadStatuses.Loaded && _PlayMsOffsets.CurrentWeather_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.CurrentWeather_End) - //if (_PlayMs <= _PlayMsOffsets.CurrentWeather_Start - //if (_PlayMs < _PlayMsOffsets.CurrentWeather_End) - if (_CurrentCanvasType > CanvasTypes.CurrentWeather) { - _PlayMs += _PlayMsOffsets.CurrentWeather_Length; - } - _PlayMsOffsets.CurrentWeather_Loaded = true; - } - if (Progress.NearbyConditions === LoadStatuses.Loaded && _PlayMsOffsets.LatestObservations_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.LatestObservations_End) - //if (_PlayMs <= _PlayMsOffsets.LatestObservations_Start) - //if (_PlayMs < _PlayMsOffsets.LatestObservations_End) - if (_CurrentCanvasType > CanvasTypes.LatestObservations) { - _PlayMs += _PlayMsOffsets.LatestObservations_Length; - } - _PlayMsOffsets.LatestObservations_Loaded = true; - } - if (Progress.TravelForecast === LoadStatuses.Loaded && _PlayMsOffsets.TravelForecast_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.TravelForecast_End) - //if (_PlayMs <= _PlayMsOffsets.TravelForecast_Start) - //if (_PlayMs < _PlayMsOffsets.TravelForecast_End) - if (_CurrentCanvasType > CanvasTypes.TravelForecast) { - _PlayMs += _PlayMsOffsets.TravelForecast_Length; - } - _PlayMsOffsets.TravelForecast_Loaded = true; - } - if (Progress.TomorrowsRegionalMap === LoadStatuses.Loaded && _PlayMsOffsets.RegionalForecast1_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.RegionalForecast_End) - //if (_PlayMs <= _PlayMsOffsets.RegionalForecast_Start) - //if (_PlayMs < _PlayMsOffsets.RegionalForecast_End) - if (_CurrentCanvasType > CanvasTypes.RegionalForecast1) { - _PlayMs += _PlayMsOffsets.RegionalForecast1_Length; - } - _PlayMsOffsets.RegionalForecast1_Loaded = true; - } - if (Progress.TomorrowsRegionalMap === LoadStatuses.Loaded && _PlayMsOffsets.RegionalForecast2_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.RegionalForecast_End) - //if (_PlayMs <= _PlayMsOffsets.RegionalForecast_Start) - //if (_PlayMs < _PlayMsOffsets.RegionalForecast_End) - if (_CurrentCanvasType > CanvasTypes.RegionalForecast2) { - _PlayMs += _PlayMsOffsets.RegionalForecast2_Length; - } - _PlayMsOffsets.RegionalForecast2_Loaded = true; - } - if (Progress.CurrentRegionalMap === LoadStatuses.Loaded && _PlayMsOffsets.RegionalObservations_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.RegionalObservations_End) - //if (_PlayMs <= _PlayMsOffsets.RegionalObservations_Start) - //if (_PlayMs < _PlayMsOffsets.RegionalObservations_End) - if (_CurrentCanvasType > CanvasTypes.RegionalObservations) { - _PlayMs += _PlayMsOffsets.RegionalObservations_Length; - } - _PlayMsOffsets.RegionalObservations_Loaded = true; - } - if (Progress.WordedForecast === LoadStatuses.Loaded && _PlayMsOffsets.LocalForecast_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.LocalForecast_End) - //if (_PlayMs <= _PlayMsOffsets.LocalForecast_Start) - //if (_PlayMs < _PlayMsOffsets.LocalForecast_Start) - if (_CurrentCanvasType > CanvasTypes.LocalForecast) { - _PlayMs += _PlayMsOffsets.LocalForecast_Length; - } - _PlayMsOffsets.LocalForecast_Loaded = true; - } - if (Progress.WordedForecast === LoadStatuses.Loaded && _PlayMsOffsets.MarineForecast_Loaded === false && _WeatherParameters.MarineForecast) { - if (_CurrentCanvasType > CanvasTypes.MarineForecast) { - _PlayMs += _PlayMsOffsets.MarineForecast_Length; - } - _PlayMsOffsets.MarineForecast_Loaded = true; - } - if (Progress.WordedForecast === LoadStatuses.Loaded && _PlayMsOffsets.AirQuality_Loaded === false && _WeatherParameters.AirQuality) { - if (_CurrentCanvasType > CanvasTypes.AirQuality) { - _PlayMs += _PlayMsOffsets.AirQuality_Length; - } - _PlayMsOffsets.AirQuality_Loaded = true; - } - if (Progress.FourDayForecast === LoadStatuses.Loaded && _PlayMsOffsets.ExtendedForecast1_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.ExtendedForecast_End) - //if (_PlayMs <= _PlayMsOffsets.ExtendedForecast_Start) - //if (_PlayMs > _PlayMsOffsets.ExtendedForecast_Start) - if (_CurrentCanvasType > CanvasTypes.ExtendedForecast1) { - _PlayMs += _PlayMsOffsets.ExtendedForecast1_Length; - } - _PlayMsOffsets.ExtendedForecast1_Loaded = true; - } - if (Progress.FourDayForecast === LoadStatuses.Loaded && _PlayMsOffsets.ExtendedForecast2_Loaded === false) { - if (_CurrentCanvasType > CanvasTypes.ExtendedForecast2) { - _PlayMs += _PlayMsOffsets.ExtendedForecast2_Length; - } - _PlayMsOffsets.ExtendedForecast2_Loaded = true; - } - if (Progress.Almanac === LoadStatuses.Loaded && _PlayMsOffsets.Almanac_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.Almanac_End) - //if (_PlayMs <= _PlayMsOffsets.Almanac_Start) - //if (_PlayMs > _PlayMsOffsets.Almanac_Start) - if (_CurrentCanvasType > CanvasTypes.Almanac) { - _PlayMs += _PlayMsOffsets.Almanac_Length; - } - _PlayMsOffsets.Almanac_Loaded = true; - } - if (Progress.Almanac === LoadStatuses.Loaded && _PlayMsOffsets.AlmanacTides_Loaded === false && _WeatherParameters.WeatherTides) { - if (_CurrentCanvasType > CanvasTypes.AlmanacTides) { - _PlayMs += _PlayMsOffsets.AlmanacTides_Length; - } - _PlayMsOffsets.AlmanacTides_Loaded = true; - } - if (Progress.Almanac === LoadStatuses.Loaded && _PlayMsOffsets.Outlook_Loaded === false && _WeatherParameters.Outlook) { - if (_CurrentCanvasType > CanvasTypes.Outlook) { - _PlayMs += _PlayMsOffsets.Outlook_Length; - } - _PlayMsOffsets.Outlook_Loaded = true; - } - if (Progress.DopplerRadar === LoadStatuses.Loaded && _PlayMsOffsets.LocalRadar_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.LocalRadar_End) - //if (_PlayMs <= _PlayMsOffsets.LocalRadar_Start) - //if (_PlayMs > _PlayMsOffsets.LocalRadar_Start) - if (_CurrentCanvasType > CanvasTypes.LocalRadar) { - _PlayMs += _PlayMsOffsets.LocalRadar_Length; - } - _PlayMsOffsets.LocalRadar_Loaded = true; - } - if (Progress.Hazards === LoadStatuses.Loaded && _PlayMsOffsets.Hazards_Loaded === false) { - //if (_PlayMs > _PlayMsOffsets.Hazards_End) - //if (_PlayMs <= _PlayMsOffsets.Hazards_Start) - //if (_PlayMs > _PlayMsOffsets.Hazards_Start) - if (_CurrentCanvasType > CanvasTypes.Hazards) { - _PlayMs += _PlayMsOffsets.Hazards_Length; - } - _PlayMsOffsets.Hazards_Loaded = true; - } - } else { - switch (_CurrentCanvasType) { - case CanvasTypes.Progress: - _PlayMs = 0; - break; - case CanvasTypes.CurrentWeather: - _PlayMs = _PlayMsOffsets.CurrentWeather_Start; - break; - case CanvasTypes.LatestObservations: - _PlayMs = _PlayMsOffsets.LatestObservations_Start; - break; - case CanvasTypes.TravelForecast: - _PlayMs = _PlayMsOffsets.TravelForecast_Start; - break; - case CanvasTypes.RegionalForecast1: - _PlayMs = _PlayMsOffsets.RegionalForecast1_Start; - break; - case CanvasTypes.RegionalForecast2: - _PlayMs = _PlayMsOffsets.RegionalForecast2_Start; - break; - case CanvasTypes.RegionalObservations: - _PlayMs = _PlayMsOffsets.RegionalObservations_Start; - break; - case CanvasTypes.LocalForecast: - _PlayMs = _PlayMsOffsets.LocalForecast_Start; - break; - case CanvasTypes.MarineForecast: - _PlayMs = _PlayMsOffsets.MarineForecast_Start; - break; - case CanvasTypes.AirQuality: - _PlayMs = _PlayMsOffsets.AirQuality_Start; - break; - case CanvasTypes.ExtendedForecast1: - _PlayMs = _PlayMsOffsets.ExtendedForecast1_Start; - break; - case CanvasTypes.ExtendedForecast2: - _PlayMs = _PlayMsOffsets.ExtendedForecast2_Start; - break; - case CanvasTypes.Almanac: - _PlayMs = _PlayMsOffsets.Almanac_Start; - break; - case CanvasTypes.AlmanacTides: - _PlayMs = _PlayMsOffsets.AlmanacTides_Start; - break; - case CanvasTypes.Outlook: - _PlayMs = _PlayMsOffsets.Outlook_Start; - break; - case CanvasTypes.LocalRadar: - _PlayMs = _PlayMsOffsets.LocalRadar_Start; - break; - case CanvasTypes.Hazards: - _PlayMs = _PlayMsOffsets.Hazards_Start; - break; - default: - } - } - -}; - -var UpdatePlayPosition = function () { - var cnvTravelCitiesScroll = $('#cnvTravelCitiesScroll'); - var cnvHazardsScroll = $('#cnvHazardsScroll'); - var SubMs; - - var PrevPlayMs = _PlayMs; - var PrevCanvasType = _CurrentCanvasType; - var PrevPosition = _CurrentPosition; - var PrevUpdateLocalForecastIndex = _UpdateLocalForecastIndex; - - if (_PlayMs < _PlayMsOffsets.Start) { - _PlayMs = _PlayMsOffsets.End + _PlayMs; - } else if (_PlayMs >= _PlayMsOffsets.End) { - _PlayMs = _PlayMs - _PlayMsOffsets.End; - } - - if (_PlayMs >= _PlayMsOffsets.CurrentWeather_Start && _PlayMs < _PlayMsOffsets.CurrentWeather_End) { - _CurrentCanvasType = CanvasTypes.CurrentWeather; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.LatestObservations_Start && _PlayMs < _PlayMsOffsets.LatestObservations_End) { - _CurrentCanvasType = CanvasTypes.LatestObservations; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.TravelForecast_Start && _PlayMs < _PlayMsOffsets.TravelForecast_End) { - _CurrentCanvasType = CanvasTypes.TravelForecast; - _CurrentPosition = _CurrentCanvasType; - SubMs = _PlayMs - _PlayMsOffsets.TravelForecast_Start; - - - } else if (_PlayMs >= _PlayMsOffsets.RegionalForecast1_Start && _PlayMs < _PlayMsOffsets.RegionalForecast1_End) { - _CurrentCanvasType = CanvasTypes.RegionalForecast1; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.RegionalForecast2_Start && _PlayMs < _PlayMsOffsets.RegionalForecast2_End) { - _CurrentCanvasType = CanvasTypes.RegionalForecast2; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.RegionalObservations_Start && _PlayMs < _PlayMsOffsets.RegionalObservations_End) { - _CurrentCanvasType = CanvasTypes.RegionalObservations; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.LocalForecast_Start && _PlayMs < _PlayMsOffsets.LocalForecast_End) { - _CurrentCanvasType = CanvasTypes.LocalForecast; - _CurrentPosition = _CurrentCanvasType; - SubMs = _PlayMs - _PlayMsOffsets.LocalForecast_Start; - - _UpdateLocalForecastIndex = Math.floor(SubMs / 10000); - _CurrentPosition += _UpdateLocalForecastIndex / 10; - - if (_IsSpeaking) { - if (_UpdateLocalForecastIndex !== PrevUpdateLocalForecastIndex) { - _UpdateLocalForecastIndex = PrevUpdateLocalForecastIndex; - _CurrentPosition = _CurrentCanvasType; - _CurrentPosition += _UpdateLocalForecastIndex / 10; - } - } - - UpdateLocalForecast(); - } else if (_PlayMs >= _PlayMsOffsets.MarineForecast_Start && _PlayMs < _PlayMsOffsets.MarineForecast_End) { - _CurrentCanvasType = CanvasTypes.MarineForecast; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.AirQuality_Start && _PlayMs < _PlayMsOffsets.AirQuality_End) { - _CurrentCanvasType = CanvasTypes.AirQuality; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.ExtendedForecast1_Start && _PlayMs < _PlayMsOffsets.ExtendedForecast1_End) { - _CurrentCanvasType = CanvasTypes.ExtendedForecast1; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.ExtendedForecast2_Start && _PlayMs < _PlayMsOffsets.ExtendedForecast2_End) { - _CurrentCanvasType = CanvasTypes.ExtendedForecast2; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.Almanac_Start && _PlayMs < _PlayMsOffsets.Almanac_End) { - _CurrentCanvasType = CanvasTypes.Almanac; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.AlmanacTides_Start && _PlayMs < _PlayMsOffsets.AlmanacTides_End) { - _CurrentCanvasType = CanvasTypes.AlmanacTides; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.Outlook_Start && _PlayMs < _PlayMsOffsets.Outlook_End) { - _CurrentCanvasType = CanvasTypes.Outlook; - _CurrentPosition = _CurrentCanvasType; - } else if (_PlayMs >= _PlayMsOffsets.LocalRadar_Start && _PlayMs < _PlayMsOffsets.LocalRadar_End) { - _CurrentCanvasType = CanvasTypes.LocalRadar; - _CurrentPosition = _CurrentCanvasType; - SubMs = _PlayMs - _PlayMsOffsets.LocalRadar_Start; - - SubMs = SubMs % 4500; - - if (SubMs < 2000) { - _DopplerRadarImageIndex = 0; - } else { - _DopplerRadarImageIndex = (_DopplerRadarImageMax - 1) - (Math.floor((SubMs - 2000) / 500)); - } - - //_CurrentPosition += _DopplerRadarImageIndex / 10; - - UpdateDopplarRadarImage(); - } else if (_PlayMs >= _PlayMsOffsets.Hazards_Start && _PlayMs < _PlayMsOffsets.Hazards_End) { - _CurrentCanvasType = CanvasTypes.Hazards; - _CurrentPosition = _CurrentCanvasType; - - SubMs = _PlayMs - _PlayMsOffsets.Hazards_Start; - - // Wait 3 seconds and then start scrolling. - if (SubMs < 3000) { - _UpdateHazardsY = -385; - } - if (SubMs >= 3000) { - //y += 1; - _UpdateHazardsY = (3 * ((SubMs - 3000) / _PlayInterval)) - 385; - } - if (_UpdateHazardsY > cnvHazardsScroll.height()) { - _UpdateHazardsY = cnvHazardsScroll.height(); - - // Wait 10 seconds and start all over. - } - - //_CurrentPosition += Math.round(_UpdateHazardsY / 385) / 10; - - UpdateHazards(); - } - - if (_IsSpeaking) { - if (_CurrentCanvasType !== PrevCanvasType) { - _CurrentCanvasType = PrevCanvasType; - _CurrentPosition = PrevPosition; - _PlayMs = PrevPlayMs - _PlayInterval; - } - } - //console.log("_PlayMs=" + _PlayMs); - - - Navigate(); - - -}; - -var NavigatePlayToggle = function () { - - _IsPlaying = !(_IsPlaying); - - if (_PlayIntervalId) { - window.clearInterval(_PlayIntervalId); - _PlayIntervalId = null; - } - - if (_IsPlaying) { - - _PlayIntervalId = window.setInterval(function () { - if (_WeatherParameters.Progress.GetTotalPercentage() !== 100) { - return; - } - - UpdatePlayPosition(); - _PlayMs += _PlayInterval; - - }, _PlayInterval); - //NavigateNext(); - } else { - //if (_PlayIntervalId) - //{ - // window.clearInterval(_PlayIntervalId); - // _PlayIntervalId = null; - //} - } - - if (_CallBack) _CallBack({ Status: 'ISPLAYING', Value: _IsPlaying }); - -}; - -var IsPlaying = function () { - return _IsPlaying; -}; var canvasProgress_mousemove = function (e) { canvasProgress.css('cursor', ''); @@ -2809,426 +1105,8 @@ Number.prototype.pad = function(size) { -const PopulateAlmanacInfo = async (WeatherParameters) => { - if (WeatherParameters === null || (_DontLoadGifs && WeatherParameters.Progress.Almanac !== LoadStatuses.Loaded)) return; - const info = WeatherParameters.AlmanacInfo; - // Draw canvas - const canvas = canvasAlmanac[0]; - const context = canvas.getContext('2d'); - - // load all images in parallel - const [FullMoonImage, LastMoonImage, NewMoonImage, FirstMoonImage, BackGroundImage] = await Promise.all([ - utils.loadImg('images/2/Full-Moon.gif'), - utils.loadImg('images/2/Last-Quarter.gif'), - utils.loadImg('images/2/New-Moon.gif'), - utils.loadImg('images/2/First-Quarter.gif'), - utils.loadImg('images/BackGround3_1.png'), - ]); - - 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, 640, 190, _SideColor1, _SideColor2); - - DrawTitleText(context, 'Almanac', 'Astronomical'); - - const Today = luxon.DateTime.local(); - const Tomorrow = Today.plus({days: 1}); - DrawText(context, 'Star4000', '24pt', '#FFFF00', 320, 120, Today.toLocaleString({weekday: 'long'}), 2, 'center'); - DrawText(context, 'Star4000', '24pt', '#FFFF00', 500, 120, Tomorrow.toLocaleString({weekday: 'long'}), 2, 'center'); - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 70, 150, 'Sunrise:', 2); - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 270, 150, luxon.DateTime.fromJSDate(info.sun[0].sunrise).toLocaleString(luxon.DateTime.TIME_SIMPLE).toLowerCase(), 2); - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 450, 150, luxon.DateTime.fromJSDate(info.sun[1].sunrise).toLocaleString(luxon.DateTime.TIME_SIMPLE).toLowerCase(), 2); - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 70, 180, ' Sunset:', 2); - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 270, 180, luxon.DateTime.fromJSDate(info.sun[0].sunset).toLocaleString(luxon.DateTime.TIME_SIMPLE).toLowerCase(), 2); - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 450, 180, luxon.DateTime.fromJSDate(info.sun[1].sunset).toLocaleString(luxon.DateTime.TIME_SIMPLE).toLowerCase(), 2); - - DrawText(context, 'Star4000', '24pt', '#FFFF00', 70, 220, 'Moon Data:', 2); - - - info.moon.forEach((MoonPhase, Index) => { - const date = MoonPhase.date.toLocaleString({month: 'short', day: 'numeric'}); - - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 120+Index*130, 260, MoonPhase.phase, 2, 'center'); - DrawText(context, 'Star4000', '24pt', '#FFFFFF', 120+Index*130, 390, date, 2, 'center'); - - const image = (() => { - switch (MoonPhase.phase) { - case 'Full': - return FullMoonImage; - case 'Last': - return LastMoonImage; - case 'New': - return NewMoonImage; - case 'First': - default: - return FirstMoonImage; - } - })(); - context.drawImage(image, 75+Index*130, 270); - }); - - WeatherParameters.Progress.Almanac = LoadStatuses.Loaded; - - UpdateWeatherCanvas(WeatherParameters, canvasAlmanac); - - -}; - - - - -const ShowDopplerMap = async (WeatherParameters) => { - - - - let OffsetY; - let OffsetX; - let SourceXY; - let contextWorker; - - const cnvDopplerMapId = 'cnvDopplerRadarMap'; - const cnvRadarWorkerId = 'cnvRadarWorker'; - - // Clear the current image. - divDopplerRadarMap.empty(); - - let src = 'images/4000RadarMap2.jpg'; - if (WeatherParameters.State === 'HI') src = 'images/HawaiiRadarMap2.png'; - const img = await utils.loadImg(src); - console.log('Doppler Image Loaded'); - - divDopplerRadarMap.html(``); - const $cnvDopplerMap = $(`#${cnvDopplerMapId}`); - $cnvDopplerMap.attr('width', '640'); // For Chrome. - $cnvDopplerMap.attr('height', '367'); // For Chrome. - const context = $cnvDopplerMap[0].getContext('2d'); - - const $cnvRadarWorker = $(`#${cnvRadarWorkerId}`); - OffsetX = 120; - OffsetY = 69; - if (WeatherParameters.State === 'HI') { - $cnvRadarWorker.attr('width', '600'); // For Chrome. - $cnvRadarWorker.attr('height', '571'); // For Chrome. - SourceXY = GetXYFromLatitudeLongitudeHI(WeatherParameters.Latitude, WeatherParameters.Longitude, OffsetX, OffsetY); - } else { - $cnvRadarWorker.attr('width', '2550'); // For Chrome. - $cnvRadarWorker.attr('height', '1600'); // For Chrome. - OffsetX *= 2; - OffsetY *= 2; - SourceXY = GetXYFromLatitudeLongitudeDoppler(WeatherParameters.Latitude, WeatherParameters.Longitude, OffsetX, OffsetY); - } - $cnvRadarWorker.css('display', 'none'); - contextWorker = $cnvRadarWorker[0].getContext('2d'); - - // Draw them onto the map. - context.drawImage(img, SourceXY.x, SourceXY.y, (OffsetX * 2), (OffsetY * 2), 0, 0, 640, 367); - - const baseUrl = 'https://radar.weather.gov/Conus/RadarImg/'; - - const RadarContexts = []; - - try { - // get a list of available radars - const radarHtml = await $.ajaxCORS({ - type: 'GET', - url: baseUrl, - dataType: 'text', - crossDomain: true, - }); - - // convert to an array of gif urls - const $list = $(radarHtml); - const gifs = $list.find('a[href]').map((i,elem) => elem.innerHTML).get(); - - // filter for selected urls - let filter = /^Conus_\d/; - if (WeatherParameters.State === 'HI') filter = /hawaii_\d/; - - // get the last few images - const urlsFull = gifs.filter(gif => gif.match(filter)); - const urls = urlsFull.slice(-_DopplerRadarImageMax); - - // Load the most recent doppler radar images. - const RadarImages = await Promise.all(urls.map(async (url, idx) => { - // create destination context - const id = 'cnvRadar' + idx.toString(); - let RadarContext = $(`#${id}`); - if (!RadarContext[idx]) { - $('body').append(``); - RadarContext = $(`#${id}`); - RadarContext.attr('width', '640'); // For Chrome. - RadarContext.attr('height', '367'); // For Chrome. - RadarContext.css('display', 'none'); - } - RadarContexts.push(RadarContext); - - // get the image - const blob = await $.ajaxCORS({ - type: 'GET', - url: baseUrl + url, - xhrFields: { - responseType: 'blob', - }, - crossDomain: true, - }); - - // assign to an html image element - return await utils.loadImg(blob); - })); - - RadarImages.forEach((radarImg, idx) => { - - const RadarContext = RadarContexts[idx][0].getContext('2d'); - contextWorker.clearRect(0, 0, contextWorker.canvas.width, contextWorker.canvas.height); - - SmoothingEnabled(contextWorker, false); - - if (WeatherParameters.State === 'HI') { - contextWorker.drawImage(radarImg, 0, 0, 571, 600); - } else { - contextWorker.drawImage(radarImg, 0, 0, 2550, 1600); - } - - let RadarOffsetX; - let RadarOffsetY; - let RadarSourceXY; - let RadarSourceX; - let RadarSourceY; - if (WeatherParameters.State === 'HI') { - RadarOffsetX = 120; - RadarOffsetY = 69; - RadarSourceXY = GetXYFromLatitudeLongitudeHI(WeatherParameters.Latitude, WeatherParameters.Longitude, OffsetX, OffsetY); - RadarSourceX = RadarSourceXY.x; - RadarSourceY = RadarSourceXY.y; - } else { - RadarOffsetX = 117; - RadarOffsetY = 60; - RadarSourceXY = GetXYFromLatitudeLongitudeDoppler(WeatherParameters.Latitude, WeatherParameters.Longitude, OffsetX, OffsetY); - RadarSourceX = RadarSourceXY.x / 2; - RadarSourceY = RadarSourceXY.y / 2; - } - - // Draw them onto the map. - RadarContext.clearRect(0, 0, RadarContext.canvas.width, RadarContext.canvas.height); - - SmoothingEnabled(RadarContext, false); - - RadarContext.drawImage(contextWorker.canvas, RadarSourceX, RadarSourceY, (RadarOffsetX * 2), (RadarOffsetY * 2.33), 0, 0, 640, 367); - RemoveDopplerRadarImageNoise(RadarContext); - }); - - console.log('Doppler Radar Images Loaded'); - - WeatherParameters.DopplerRadarInfo = { - RadarContexts: RadarContexts, - RadarImage: img, - RadarMapContext: context, - RadarSourceX: SourceXY.x, - RadarSourceY: SourceXY.y, - OffsetY: OffsetY, - OffsetX: OffsetX, - }; - - // draw the background image - const RadarContext = RadarContexts[0][0].getContext('2d'); - context.drawImage(img, SourceXY.x, SourceXY.y, (OffsetX * 2), (OffsetY * 2), 0, 0, 640, 367); - MergeDopplerRadarImage(context, RadarContext); - - - // Draw canvas - { - const BackGroundImage = await utils.loadImg('images/BackGround4_1.png'); - - const canvas = canvasLocalRadar[0]; - const context = canvas.getContext('2d'); - context.drawImage(BackGroundImage, 0, 0); - - // Title - DrawText(context, 'Arial', 'bold 28pt', '#ffffff', 175, 65, 'Local', 2); - DrawText(context, 'Arial', 'bold 28pt', '#ffffff', 175, 100, 'Radar', 2); - - DrawText(context, 'Arial', 'bold 18pt', '#ffffff', 390, 49, 'PRECIP', 2); - DrawText(context, 'Arial', 'bold 18pt', '#ffffff', 298, 73, 'Light', 2); - DrawText(context, 'Arial', 'bold 18pt', '#ffffff', 517, 73, 'Heavy', 2); - - let x = 362; - const y = 52; - DrawBox(context, '#000000', x - 2, y - 2, 154, 28); - DrawBox(context, 'rgb(49, 210, 22)', x, y, 17, 24); x += 19; - DrawBox(context, 'rgb(28, 138, 18)', x, y, 17, 24); x += 19; - DrawBox(context, 'rgb(20, 90, 15)', x, y, 17, 24); x += 19; - DrawBox(context, 'rgb(10, 40, 10)', x, y, 17, 24); x += 19; - DrawBox(context, 'rgb(196, 179, 70)', x, y, 17, 24); x += 19; - DrawBox(context, 'rgb(190, 72, 19)', x, y, 17, 24); x += 19; - DrawBox(context, 'rgb(171, 14, 14)', x, y, 17, 24); x += 19; - DrawBox(context, 'rgb(115, 31, 4)', x, y, 17, 24); x += 19; - - DrawBox(context, 'rgb(143, 73, 95)', 318, 83, 32, 24); - DrawBox(context, 'rgb(250, 122, 232)', 320, 85, 28, 20); - DrawText(context, 'Arial', 'bold 18pt', '#ffffff', 355, 105, '= Incomplete Data', 2); - - window.setInterval(() => { - context.drawImage($cnvDopplerMap[0], 0, 0, 640, 367, 0, 113, 640, 367); - UpdateWeatherCanvas(WeatherParameters, canvasLocalRadar); - }, 100); - WeatherParameters.Progress.DopplerRadar = LoadStatuses.Loaded; - } - - } catch (e) { - console.error('Unable to load radar'); - console.error(e); - WeatherParameters.Progress.DopplerRadar = LoadStatuses.Failed; - } - - -}; - - - - -const UpdateDopplarRadarImage = (offset) => { - switch (offset) { - case undefined: - break; - case 0: - _DopplerRadarImageIndex = _DopplerRadarImageMax - 1; - break; - case Infinity: - _DopplerRadarImageIndex = 0; - break; - default: - _DopplerRadarImageIndex -= offset; - if (_DopplerRadarImageIndex > _DopplerRadarImageMax - 1) _DopplerRadarImageIndex = 0; - if (_DopplerRadarImageIndex < 0) _DopplerRadarImageIndex = _DopplerRadarImageMax - 1; - break; - } - - const RadarContexts = _WeatherParameters.DopplerRadarInfo.RadarContexts; - const img = _WeatherParameters.DopplerRadarInfo.RadarImage; - const context = _WeatherParameters.DopplerRadarInfo.RadarMapContext; - const SourceX = _WeatherParameters.DopplerRadarInfo.RadarSourceX; - const SourceY = _WeatherParameters.DopplerRadarInfo.RadarSourceY; - const OffsetY = _WeatherParameters.DopplerRadarInfo.OffsetY; - const OffsetX = _WeatherParameters.DopplerRadarInfo.OffsetX; - - const RadarContext = RadarContexts[_DopplerRadarImageIndex][0].getContext('2d'); - context.drawImage(img, SourceX, SourceY, (OffsetX * 2), (OffsetY * 2), 0, 0, 640, 367); - MergeDopplerRadarImage(context, RadarContext); -}; - -const RemoveDopplerRadarImageNoise = (RadarContext) => { - const RadarImageData = RadarContext.getImageData(0, 0, RadarContext.canvas.width, RadarContext.canvas.height); - - // examine every pixel, - // change any old rgb to the new-rgb - for (let i = 0; i < RadarImageData.data.length; i += 4) { - // i + 0 = red - // i + 1 = green - // i + 2 = blue - // i + 3 = alpha (0 = transparent, 255 = opaque) - let [R, G, B, A] = RadarImageData.data.slice(i,i+4); - - // is this pixel the old rgb? - if ((R === 1 && G === 159 && B === 244) - || (R >= 200 && G >= 200 && B >= 200) - || (R === 4 && G === 233 && B === 231) - || (R === 3 && G === 0 && B === 244)) { - // Transparent - R = 0; - G = 0; - B = 0; - A = 0; - } else if (R === 2 && G === 253 && B === 2) { - // Light Green 1 - R = 49; - G = 210; - B = 22; - A = 255; - } else if (R === 1 && G === 197 && B === 1) { - // Light Green 2 - R = 0; - G = 142; - B = 0; - A = 255; - } else if (R === 0 && G === 142 && B === 0) { - // Dark Green 1 - R = 20; - G = 90; - B = 15; - A = 255; - } else if (R === 253 && G === 248 && B === 2) { - // Dark Green 2 - R = 10; - G = 40; - B = 10; - A = 255; - } else if (R === 229 && G === 188 && B === 0) { - // Yellow - R = 196; - G = 179; - B = 70; - A = 255; - } else if (R === 253 && G === 139 && B === 0) { - // Orange - R = 190; - G = 72; - B = 19; - A = 255; - } else if (R === 212 && G === 0 && B === 0) { - // Red - R = 171; - G = 14; - B = 14; - A = 255; - } else if (R === 188 && G === 0 && B === 0) { - // Brown - R = 115; - G = 31; - B = 4; - A = 255; - } - - // store new values - RadarImageData.data[i] = R; - RadarImageData.data[i + 1] = G; - RadarImageData.data[i + 2] = B; - RadarImageData.data[i + 3] = A; - } - - // rewrite the image - RadarContext.putImageData(RadarImageData, 0, 0); -}; - -const MergeDopplerRadarImage = (MapContext, RadarContext) => { - const MapImageData = MapContext.getImageData(0, 0, MapContext.canvas.width, MapContext.canvas.height); - const RadarImageData = RadarContext.getImageData(0, 0, RadarContext.canvas.width, RadarContext.canvas.height); - - // examine every pixel, - // change any old rgb to the new-rgb - for (let i = 0; i < RadarImageData.data.length; i += 4) { - // i + 0 = red - // i + 1 = green - // i + 2 = blue - // i + 3 = alpha (0 = transparent, 255 = opaque) - - // is this pixel the old rgb? - if ((MapImageData.data[i] < 116 && MapImageData.data[i + 1] < 116 && MapImageData.data[i + 2] < 116)) { - // Transparent - RadarImageData.data[i] = 0; - RadarImageData.data[i + 1] = 0; - RadarImageData.data[i + 2] = 0; - RadarImageData.data[i + 3] = 0; - } - } - - RadarContext.putImageData(RadarImageData, 0, 0); - MapContext.drawImage(RadarContext.canvas, 0, 0); -}; const Progress = function (e) { const WeatherParameters = e.WeatherParameters; @@ -3337,8 +1215,6 @@ const Progress = function (e) { __DrawText('Local Radar', WeatherParameters.Progress.DopplerRadar); __DrawText('Hazardous Weather', WeatherParameters.Progress.Hazards); - UpdateWeatherCanvas(WeatherParameters, $(canvas)); - }; this.GetTotalPercentage = function() { @@ -3405,366 +1281,6 @@ const Progress = function (e) { }; -const SmoothingEnabled = (context, enable) => { - context.imageSmoothingEnabled = enable; - context.webkitImageSmoothingEnabled = enable; - context.mozImageSmoothingEnabled = enable; - context.msImageSmoothingEnabled = enable; - context.oImageSmoothingEnabled = enable; -}; - -const UpdateWeatherCanvases = function (WeatherParameters) { - // skip if parameters not loaded - if (WeatherParameters === null) return; - - WeatherParameters.WeatherCanvases.forEach((WeatherCanvas) => { - // find the foreground canvas - // Attempt to save battery/cpu. - if (document.elementFromPoint(0, 0) !== WeatherCanvas[0]) return; - UpdateWeatherCanvas(WeatherParameters, WeatherCanvas); - }); - - if (WeatherParameters.Progress.GetTotalPercentage() === 100) { - _UpdateWeatherCurrentConditionCounterMs += _UpdateWeatherUpdateMs; - _UpdateCustomScrollTextMs += _UpdateWeatherUpdateMs; - } -}; - -const UpdateWeatherCanvas = (WeatherParameters, Canvas) => { - let OkToDrawCurrentConditions = true; - let OkToDrawNoaaImage = true; - let OkToDrawCurrentDateTime = true; - let OkToDrawLogoImage = true; - let OkToDrawCustomScrollText = false; - let bottom = undefined; - - const context = Canvas[0].getContext('2d'); - - // visibility tests - if (_ScrollText !== '') OkToDrawCustomScrollText = true; - if (Canvas[0] === canvasAlmanac[0]) OkToDrawNoaaImage = false; - if (Canvas[0] === canvasAlmanacTides[0]) OkToDrawNoaaImage = false; - if (Canvas[0] === canvasOutlook[0]) OkToDrawNoaaImage = false; - if (Canvas[0] === canvasMarineForecast[0])OkToDrawNoaaImage = false; - if (Canvas[0] === canvasAirQuality[0]) OkToDrawNoaaImage = false; - if (Canvas[0] === canvasTravelForecast[0]) OkToDrawNoaaImage = false; - if (Canvas[0] === canvasRegionalForecast1[0])OkToDrawNoaaImage = false; - if (Canvas[0] === canvasRegionalForecast2[0]) OkToDrawNoaaImage = false; - if (Canvas[0] === canvasRegionalObservations[0]) OkToDrawNoaaImage = false; - if (Canvas[0] === canvasLocalRadar[0]) { - OkToDrawCurrentConditions = false; - OkToDrawCurrentDateTime = false; - OkToDrawNoaaImage = false; - OkToDrawCustomScrollText = false; - } - if (Canvas[0] === canvasHazards[0]) { - OkToDrawNoaaImage = false; - bottom = true; - OkToDrawLogoImage = false; - } - // draw functions - if (OkToDrawCurrentDateTime) DrawCurrentDateTime(context, bottom); - if (OkToDrawLogoImage) DrawLogoImage(context); - if (OkToDrawNoaaImage) DrawNoaaImage(context); - if (OkToDrawCurrentConditions) DrawCurrentConditions(WeatherParameters, context); - if (OkToDrawCustomScrollText) DrawCustomScrollText(WeatherParameters, context); -}; - -const DrawCurrentDateTime = (context, bottom) => { - // test if needed - if (_WeatherParameters === null || _WeatherParameters.TimeZone === undefined) return; - - const font = 'Star4000 Small'; - const size = '24pt'; - const color = '#ffffff'; - const shadow = 2; - - // Clear the date and time area. - if (bottom) { - DrawBox(context, 'rgb(25, 50, 112)', 0, 389, 640, 16); - } else { - context.drawImage(canvasBackGroundDateTime[0], 0, 0, 175, 60, 410, 30, 175, 60); - } - - // Get the current date and time. - let now = new Date(); - now = utils.calc.DateToTimeZone(now, _WeatherParameters.TimeZone); - - //time = "11:35:08 PM"; - let h = now.getHours(); - let m = now.getMinutes(); - let s = now.getSeconds(); - let time = ''; - let x; - let y; - let date; - - if (_Units === Units.English) { - if (h < 10) { - if (h === 0) { - time = '12'; - } else { - time += ' ' + h.toString(); - } - } else if (h > 12) { - if (h - 12 < 10) { - time += ' ' + (h - 12).toString(); - } else { - time += (h - 12).toString(); - } - } else { - time += h.toString(); - } - } else if (_Units === Units.Metric) { - if (h < 10) { - time += ' ' + h.toString(); - } else { - time += h.toString(); - } - } - - time += ':'; - if (m < 10) time += '0'; - time += m.toString() + ':'; - if (s < 10) time += '0'; - time += s.toString() + ' '; - - if (_Units === Units.English) { - if (h >= 12) { - time += 'PM'; - } else { - time += 'AM'; - } - } - - if (bottom) { - x = 400; - y = 402; - } else { - x = 410; - y = 65; - } - if (_Units === Units.Metric) { - x += 45; - } - - DrawText(context, font, size, color, x, y, time, shadow); //y += 20; - - if (_Units === Units.English) { - date = ' '; - const W = now.getDayShortName().toUpperCase(); - date += W + ' '; - const M = now.getMonthShortName().toUpperCase(); - date += M + ' '; - const D = now.getDate(); - if (D < 10) date += ' '; - //date += " " + D.toString(); - date += D.toString(); - } else { - date = ' '; - const W = now.getDayShortName().toUpperCase(); - date += W + ' '; - const D = now.getDate(); - if (D < 10) date += ' '; - date += D.toString(); - const M = now.getMonthShortName().toUpperCase(); - date += ' ' + M; - } - - if (bottom) { - x = 55; - y = 402; - } else { - x = 410; - y = 85; - } - DrawText(context, font, size, color, x, y, date, shadow); -}; - -const DrawNoaaImage = async (context) => { - // load the image and store locally - if (!DrawNoaaImage.image) { - DrawNoaaImage.image = utils.loadImg('images/noaa5.gif'); - } - // wait for the image to load completely - const img = await DrawNoaaImage.image; - context.drawImage(img, 356, 39); -}; - -const DrawLogoImage = async (context) => { - // load the image and store locally - if (!DrawLogoImage.image) { - DrawLogoImage.image = utils.loadImg('images/Logo3.png'); - } - // wait for the image load completely - const img = await DrawLogoImage.image; - context.drawImage(img, 50, 30, 85, 67); -}; - -var DrawCurrentConditions = function (WeatherParameters, context) { - var Humidity; - var DewPoint; - var Temperature; - var TemperatureUnit; - var HeatIndex; - var WindChill; - var Pressure; - var PressureDirection; - var WindSpeed; - var WindDirection; - var WindGust; - var WindUnit; - var Visibility; - var VisibilityUnit; - var Ceiling; - var CeilingUnit; - var PrecipitationTotal; - var PrecipitationTotalUnit; - - var font, size, color, x, y, shadow; - var text; - - font = 'Star4000'; - size = '24pt'; - color = '#ffffff'; - shadow = 2; - x = 70; - y = 430; - - if (WeatherParameters.Progress.GetTotalPercentage() !== 100) { - return; - } - - // Clear the date and time area. - context.drawImage(canvasBackGroundCurrentConditions[0], 0, 0, 640, 75, 0, 405, 640, 75); - - var WeatherCurrentConditions = WeatherParameters.WeatherCurrentConditions; - var WeatherMonthlyTotals = WeatherParameters.WeatherMonthlyTotals; - - switch (_Units) { - case Units.English: - Temperature = WeatherCurrentConditions.Temperature; - TemperatureUnit = 'F'; - HeatIndex = WeatherCurrentConditions.HeatIndex; - WindChill = WeatherCurrentConditions.WindChill; - Humidity = WeatherCurrentConditions.Humidity; - DewPoint = WeatherCurrentConditions.DewPoint; - Pressure = WeatherCurrentConditions.Pressure; - PressureDirection = WeatherCurrentConditions.PressureDirection; - WindSpeed = WeatherCurrentConditions.WindSpeed; - WindGust = WeatherCurrentConditions.WindGust; - WindDirection = WeatherCurrentConditions.WindDirection; - WindUnit = ' MPH'; - VisibilityUnit = ' mi.'; - Visibility = WeatherCurrentConditions.Visibility; - Ceiling = WeatherCurrentConditions.Ceiling; - CeilingUnit = ' ft.'; - PrecipitationTotal = WeatherMonthlyTotals.PrecipitationTotal; - PrecipitationTotalUnit = ' in'; - break; - - case Units.Metric: - Temperature = WeatherCurrentConditions.TemperatureC; - TemperatureUnit = 'C'; - HeatIndex = WeatherCurrentConditions.HeatIndexC; - WindChill = WeatherCurrentConditions.WindChillC; - Humidity = WeatherCurrentConditions.Humidity; - DewPoint = WeatherCurrentConditions.DewPointC; - Pressure = WeatherCurrentConditions.PressureC; - PressureDirection = WeatherCurrentConditions.PressureDirection; - WindSpeed = WeatherCurrentConditions.WindSpeedC; - WindGust = WeatherCurrentConditions.WindGustC; - WindDirection = WeatherCurrentConditions.WindDirection; - WindUnit = ' KPH'; - VisibilityUnit = ' km.'; - Visibility = WeatherCurrentConditions.VisibilityC; - Ceiling = WeatherCurrentConditions.CeilingC; - CeilingUnit = ' m.'; - PrecipitationTotal = WeatherMonthlyTotals.PrecipitationTotalC; - PrecipitationTotalUnit = ' cm'; - break; - default: - } - - if (_UpdateWeatherCurrentConditionCounterMs >= 4000) { - _UpdateWeatherCurrentConditionCounterMs = 0; - _UpdateWeatherCurrentConditionType++; - if (_UpdateWeatherCurrentConditionType > CurrentConditionTypes.MonthPrecipitation) { - _UpdateWeatherCurrentConditionType = CurrentConditionTypes.Title; - } - } - - switch(_UpdateWeatherCurrentConditionType) { - case CurrentConditionTypes.Title: - text = 'Conditions at ' + WeatherCurrentConditions.StationName.substr(0, 20); // mjb 06/01/19 - break; - case CurrentConditionTypes.Conditions: - text = WeatherCurrentConditions.Conditions; - break; - case CurrentConditionTypes.Temperature: - text = 'Temp: ' + Temperature + String.fromCharCode(176) + TemperatureUnit; - if (HeatIndex !== Temperature) { - text += ' '; - text += 'Heat Index: ' + HeatIndex + String.fromCharCode(176) + TemperatureUnit; - } else if (WindChill !== '' && WindChill < Temperature) { - text += ' '; - text += 'Wind Chill: ' + WindChill + String.fromCharCode(176) + TemperatureUnit; - } - break; - case CurrentConditionTypes.HumidityDewpoint: - text = 'Humidity: ' + Humidity + '%'; - text += ' '; - text += 'Dewpoint: ' + DewPoint + String.fromCharCode(176) + TemperatureUnit; - break; - case CurrentConditionTypes.BarometricPressure: - text = 'Barometric Pressure: ' + Pressure + ' ' + PressureDirection; - break; - case CurrentConditionTypes.Wind: - if (WindSpeed > 0) { - text = 'Wind: ' + WindDirection + ' ' + WindSpeed + WindUnit; - } else if (WindSpeed === 'NA') { - text = 'Wind: NA'; - } else { - text = 'Wind: Calm'; - } - if (WindGust !== '') { - text += ' '; - text += 'Gusts to ' + WindGust; - } - break; - case CurrentConditionTypes.VisibilityCeiling: - text = 'Visib: ' + parseInt(Visibility).toString() + VisibilityUnit; - text += ' '; - text += 'Ceiling: ' + (Ceiling === '' ? 'Unlimited' : Ceiling + CeilingUnit); - break; - case CurrentConditionTypes.MonthPrecipitation: - if (PrecipitationTotal.toString() === '') { - _UpdateWeatherCurrentConditionCounterMs += 4000; - DrawCurrentConditions(WeatherParameters, context); - return; - } - - // mjb 10/02/19 Begin - //text = WeatherMonthlyTotals.MonthName + " Precipitation: " + PrecipitationTotal.toString() + PrecipitationTotalUnit; - - if (PrecipitationTotal.toString() === 'T') { - text = WeatherMonthlyTotals.MonthName + ' Precipitation: Trace'; - } else { - text = WeatherMonthlyTotals.MonthName + ' Precipitation: ' + PrecipitationTotal.toString() + PrecipitationTotalUnit; - } - - // mjb 10/02/19 End - break; - default: - } - - // Draw the current condition. - DrawText(context, font, size, color, x, y, text, shadow); - - //_UpdateWeatherCurrentConditionCounterMs += _UpdateWeatherUpdateMs; - //console.log(_UpdateWeatherUpdateMs); -}; - const DrawCustomScrollText = (WeatherParameters, context) => { const font = 'Star4000'; const size = '24pt'; @@ -3797,1095 +1313,6 @@ const DrawCustomScrollText = (WeatherParameters, context) => { }; -let _CallBack = null; - -var SetCallBack = (e) => _CallBack = e.CallBack; - -const Units = { - English: 0, - Metric: 1, -}; -var _Units = Units.English; - -var _ScrollText = ''; - -var _DontLoadGifs = false; -var _RefreshGifs = false; - -var AssignUnits = (e) => { - switch (e.Units) { - case 'ENGLISH': - _Units = Units.English; - break; - case 'METRIC': - _Units = Units.Metric; - break; - default: - } - - RefreshSegments(); -}; - -const RefreshSegments = () => { - _DontLoadGifs = true; - - if (_WeatherParameters) _WeatherParameters.Progress.DrawProgress(); - - PopulateCurrentConditions(_WeatherParameters); - PopulateRegionalObservations(_WeatherParameters); - PopulateExtendedForecast(_WeatherParameters, 1); - PopulateExtendedForecast(_WeatherParameters, 2); - PopulateAlmanacInfo(_WeatherParameters); - PopulateTideInfo(_WeatherParameters); - PopulateOutlook(_WeatherParameters); - PopulateMarineForecast(_WeatherParameters); - PopulateAirQuality(_WeatherParameters); - PopulateTravelCities(_WeatherParameters); - ShowRegionalMap(_WeatherParameters, true); - ShowRegionalMap(_WeatherParameters, false, true); - ShowRegionalMap(_WeatherParameters); - PopulateLocalForecast(_WeatherParameters); - PopulateHazardConditions(_WeatherParameters); - UpdateWeatherCanvases(_WeatherParameters); - - _DontLoadGifs = false; - - _RefreshGifs = true; - window.setTimeout(() => _RefreshGifs = false, 200); -}; - -var AudioPlayToggle = () => { - _IsAudioPlaying = !(_IsAudioPlaying); - - if (_IsAudioPlaying) { - _AudioPlayIntervalId = window.setIntervalWorker(function () { - if (_WeatherParameters.Progress.GetTotalPercentage() !== 100) return; - - window.clearIntervalWorker(_AudioPlayIntervalId); - _AudioPlayIntervalId = null; - - if (_AudioContext === null && audMusic.attr('src') === '') { - LoadAudio(GetNextMusicUrl()); - return; - } - PlayAudio(); - - }, _AudioPlayInterval); - } else { - if (_AudioPlayIntervalId) { - window.clearIntervalWorker(_AudioPlayIntervalId); - _AudioPlayIntervalId = null; - } - - //audio.pause(); - PauseAudio(); - } - - if (_CallBack) _CallBack({ Status: 'ISAUDIOPLAYING', Value: _IsAudioPlaying }); - -}; - -const IsAudioPlaying = () => { - return _IsAudioPlaying; -}; - -const audMusic_OnError = () => { - //RefreshStateOfMusicAudio(); -}; - -const RefreshStateOfMusicAudio = () => { - const IsAudioPlaying = _IsAudioPlaying; - - if (window.AudioContext) { - _IsAudioPlaying = (_AudioContext.state === 'running' && _AudioDuration !== 0); - } else { - var audio = audMusic[0]; - _IsAudioPlaying = (audio.paused === false && _AudioDuration !== 0); - } - - if (IsAudioPlaying !== _IsAudioPlaying) { - if (_CallBack) _CallBack({ Status: 'ISAUDIOPLAYING', Value: _IsAudioPlaying }); - } -}; - -const AudioOnTimeUpdate = () => { - if (window.AudioContext) { - _AudioCurrentTime = _AudioContext.currentTime; - } else { - //audio.currentTime - _AudioCurrentTime = audMusic[0].currentTime; - } - - if (_IsAudioPlaying) { - const EndingOffsetInSeconds = 3; - let VolumeDecrementBy = 0.0; - const IntervalMs = 50; - - VolumeDecrementBy = 1 / ((EndingOffsetInSeconds * 1000) / IntervalMs); - - if (_AudioCurrentTime >= (_AudioDuration - EndingOffsetInSeconds)) { - if (!_AudioFadeOutIntervalId) { - _AudioFadeOutIntervalId = window.setIntervalWorker(function () { - var volume = VolumeAudio(); - volume -= VolumeDecrementBy; - VolumeAudio(volume); - - if (volume <= 0) { - window.clearIntervalWorker(_AudioFadeOutIntervalId); - _AudioFadeOutIntervalId = null; - - if (_IsAudioPlaying) { - LoadAudio(GetNextMusicUrl()); - } - } - }, IntervalMs); - - } - } - } - -}; - -const PopulateMusicUrls = () => { - _MusicUrls = []; - _MusicUrls.push('Audio/Andrew Korus - Hello There.mp3'); - _MusicUrls.push('Audio/Ficara - Stormy Weather.mp3'); - _MusicUrls.push('Audio/Incognito - Larc En Ciel De Miles.mp3'); - _MusicUrls.push('Audio/Ozzie Ahlers - Fingerpainting.mp3'); - _MusicUrls.push('Audio/Ray Obiedo - Blue Kiss.mp3'); - _MusicUrls.push('Audio/Richard Tyznik - Hi Times.mp3'); - _MusicUrls.push('Audio/Torcuato Mariano - Ocean Way.mp3'); - _MusicUrls.push('Audio/Gota - All Alone.mp3'); - _MusicUrls.push('Audio/Ficara - High Tides Of Maui.mp3'); - _MusicUrls.push('Audio/Chris Camozzi - Swing Shift.mp3'); - _MusicUrls.push('Audio/Brian Hughes - StringBean.mp3'); - _MusicUrls.push('Audio/Brian Hughes - Postcard From Brazil.mp3'); - _MusicUrls.push('Audio/Brian Hughes - One 2 One.mp3'); - _MusicUrls.push('Audio/Brian Hughes - Here We Go.mp3'); - _MusicUrls.push('Audio/Brian Hughes - Three Graces.mp3'); - _MusicUrls.push('Audio/Ficara - Friends Forever.mp3'); - _MusicUrls.push('Audio/Physical Therapy - What The Flush.mp3'); - _MusicUrls.push('Audio/Trammell Starks - The Blizzard Song.mp3'); - _MusicUrls.push('Audio/Terry Coleman - Just Groovin.mp3'); - _MusicUrls.push('Audio/Terry Coleman - Autumn Dance.mp3'); - _MusicUrls.push('Audio/Terry Coleman - Amazed.mp3'); - _MusicUrls.push('Audio/Ray Obiedo - Sienna.mp3'); - _MusicUrls.push('Audio/Incognito - Sunchild.mp3'); - _MusicUrls.push('Audio/Ficara - Gliding.mp3'); - _MusicUrls.push('Audio/Ficara - Craig.mp3'); - _MusicUrls.push('Audio/Eddie Reasoner - Sea Breeze.mp3'); - _MusicUrls.push('Audio/Chris Camozzi - My Dancing Heart.mp3'); - _MusicUrls.push('Audio/Chris Camozzi - Suede.mp3'); - _MusicUrls.push('Audio/Joe Sample - Rainbow Seeker.mp3'); - _MusicUrls.push('Audio/Norman Brown - Celebration.mp3'); - _MusicUrls.push('Audio/Wayne Gerard - Aint She Sweet.mp3'); - _MusicUrls.push('Audio/Wayman Tisdale - Brazilia.mp3'); - _MusicUrls.push('Audio/The Rippingtons - In Another Life.mp3'); - _MusicUrls.push('Audio/The Rippingtons - Life In The Tropics.mp3'); - _MusicUrls.push('Audio/Chris Camozzi - Hangin Out.mp3'); - _MusicUrls.push('Audio/Bryan Savage - Two Cool.mp3'); - _MusicUrls.push('Audio/Trammell Starks - 50 Below.mp3'); - _MusicUrls.push('Audio/Trammell Starks - After Midnight.mp3'); - _MusicUrls.push('Audio/Trammell Starks - After The Rain.mp3'); - _MusicUrls.push('Audio/Trammell Starks - All I Need To Know.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Autumn Blue.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Better Than Nothing.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Bobbys Theme.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Broken Record.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Crazy Pianos.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Desert Nights.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Here Comes The Rain.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Im So Dizzy.mp3'); - _MusicUrls.push('Audio/Trammell Starks - If You Only Knew.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Just For The Moment.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Midnight Rain.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Pier 32.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Rainbeat.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Road Trip.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Rollercoaster Ride.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Round And Round.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Season On Edge.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Slightly Blued.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Someday.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Something About You.mp3'); - _MusicUrls.push('Audio/Trammell Starks - The End.mp3'); - _MusicUrls.push('Audio/Trammell Starks - The Last Song.mp3'); - _MusicUrls.push('Audio/Trammell Starks - The Mist.mp3'); - _MusicUrls.push('Audio/Trammell Starks - The Only One For Me.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Under The Influence.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Ups And Downs.mp3'); - _MusicUrls.push('Audio/Trammell Starks - Water Colors.mp3'); - _MusicUrlsTemp = _MusicUrls.slice(0); -}; - -const GetNextMusicUrl = () => { - if (_MusicUrlsTemp.length < 1) { _MusicUrlsTemp = _MusicUrls.slice(0); } - const index = Math.floor(Math.random() * _MusicUrlsTemp.length); - const item = _MusicUrlsTemp[index]; - _MusicUrlsTemp.splice(index, 1); - return item; -}; - -const LoadAudio = async (Url) => { - if (_AudioRefreshIntervalId) { - window.clearIntervalWorker(_AudioRefreshIntervalId); - _AudioRefreshIntervalId = null; - } - - if (window.AudioContext) { - if (_AudioContext) { - _AudioContext.close(); - _AudioContext = null; - } - if (_AudioBufferSource) { - _AudioBufferSource.stop(); - _AudioBufferSource = null; - } - _AudioContext = new AudioContext(); - _AudioDuration = 0; - _AudioCurrentTime = 0; - - const audioData = await $.ajax({ - type: 'GET', - url: Url, - xhr: () => { - const xhr = new XMLHttpRequest(); - xhr.responseType = 'arraybuffer'; - return xhr; - }, - }); - - //decode the loaded data - _AudioContext.decodeAudioData(audioData, (buffer) => { - //create a source node from the buffer - _AudioBufferSource = _AudioContext.createBufferSource(); - _AudioBufferSource.buffer = buffer; - - _AudioDuration = buffer.duration; - _AudioCurrentTime = 0; - - //create a gain node - _AudioGain = _AudioContext.createGain(); - _AudioBufferSource.connect(_AudioGain); - _AudioGain.connect(_AudioContext.destination); - _AudioGain.gain.value = 1.00; - - _AudioBufferSource.start(); - _AudioContext.resume(); - - _AudioRefreshIntervalId = window.setIntervalWorker(function () { - AudioOnTimeUpdate(); - RefreshStateOfMusicAudio(); - }, 500); - }); - - - } else { - var audio = audMusic[0]; - - PauseAudio(); - - _AudioDuration = 0; - _AudioCurrentTime = 0; - - audio.volume = 1.00; - audio.oncanplaythrough = () => { - _AudioDuration = audio.duration; - _AudioCurrentTime = 0; - - PlayAudio(); - - _AudioRefreshIntervalId = window.setIntervalWorker(() => { - AudioOnTimeUpdate(); - RefreshStateOfMusicAudio(); - }, 500); - - }; - audio.src = Url; - audio.load(); - } -}; - -const PlayAudio = () => { - if (window.AudioContext) { - if (_AudioDuration !== 0) { - _AudioContext.resume(); - } - } else { - var audio = audMusic[0]; - audio.play(); - } -}; - -const PauseAudio = () => { - if (window.AudioContext) { - if (_AudioDuration !== 0) { - //_AudioBufferSource.stop(); - _AudioContext.suspend(); - } - } else { - var audio = audMusic[0]; - audio.pause(); - } -}; - -const VolumeAudio = (vol) => { - let volume = -1; - - if (window.AudioContext) { - if (_AudioGain) { - if (vol !== undefined) { - _AudioGain.gain.value = vol; - } - - volume =_AudioGain.gain.value; - } - } else { - let audio = audMusic[0]; - if (vol !== undefined) { - audio.volume = vol; - } - - volume = audio.volume; - } - - return volume; -}; - -var NarrationPlayToggle = () => { - _IsNarrationPlaying = !(_IsNarrationPlaying); - let _NarrationPlayIntervalId; - - if (_IsNarrationPlaying) { - if (!window.speechSynthesis) { - _IsNarrationPlaying = false; - return; - } - - if (_OperatingSystem === OperatingSystems.iOS) { - _IsNarrationPlaying = false; - return; - } - - _NarrationPlayIntervalId = window.setIntervalWorker(() => { - - window.clearIntervalWorker(_NarrationPlayIntervalId); - _NarrationPlayIntervalId = null; - - _Utterance = new SpeechSynthesisUtterance(); - - _Utterance.lang = 'en-US'; - _Utterance.volume = 1.0; - _Utterance.rate = 0.9; - _Utterance.pitch = 1.0; - SpeakUtterance(); - - }, 100); - } else { - if (_NarrationPlayIntervalId) { - window.clearIntervalWorker(_NarrationPlayIntervalId); - _NarrationPlayIntervalId = null; - } - if (window.speechSynthesis.speaking) { - window.speechSynthesis.cancel(); - } - _IsSpeaking = false; - } - - if (_CallBack) _CallBack({ Status: 'ISNARRATIONPLAYING', Value: _IsNarrationPlaying }); - -}; - -var IsNarrationPlaying = () => _IsNarrationPlaying; - -const SpeakUtterance = () => { - if (_IsNarrationPlaying === false) return; - - const CurrentUtteranceId = new Date().getTime(); - _CurrentUtteranceId = CurrentUtteranceId; - - if (window.speechSynthesis.speaking) window.speechSynthesis.cancel(); - - const Text = GetNarrationText(); - if (Text === '') return; - - console.log(`Speak Utterance: '${Text}'`); - - const Sentences = Text.split('.'); - let SentenceIndex = -1; - - const SpeakNextSentence = () => { - if (_IsNarrationPlaying === false) { - console.log('_IsNarrationPlaying === false.'); - _IsSpeaking = false; - return; - } - - if (CurrentUtteranceId !== _CurrentUtteranceId) { - console.log(`CurrentUtteranceId (${CurrentUtteranceId}) !== _CurrentUtteranceId (${_CurrentUtteranceId})`); - return; - } - - SentenceIndex++; - if (SentenceIndex > Sentences.length - 1) { - console.log('Narration Finished.'); - _IsSpeaking = false; - return; - } - - const Sentence = Sentences[SentenceIndex]; - - _CurrentUtterance = new SpeechSynthesisUtterance(); - _CurrentUtterance.text = Sentence; - _CurrentUtterance.onend = SpeakNextSentence; - _CurrentUtterance.rate = _Utterance.rate; - _CurrentUtterance.pitch = _Utterance.pitch; - _CurrentUtterance.volume = _Utterance.volume; - - window.speechSynthesis.speak(_CurrentUtterance); - console.log(`Speaking '${Sentence}'`); - _IsSpeaking = true; - }; - - setTimeout(SpeakNextSentence, 500); - -}; - -const GetNarrationText = () => { - const CanvasType = Math.floor(_CurrentPosition); - const SubCanvasType = Math.round2((_CurrentPosition - CanvasType), 1) * 10; - - let Text = ''; - - switch (CanvasType) { - case CanvasTypes.CurrentWeather: - {const WeatherCurrentConditions = _WeatherParameters.WeatherCurrentConditions; - - - let Temperature = WeatherCurrentConditions.Temperature; - let HeatIndex = WeatherCurrentConditions.HeatIndex; - let WindChill = WeatherCurrentConditions.WindChill; - let Humidity = WeatherCurrentConditions.Humidity; - let DewPoint = WeatherCurrentConditions.DewPoint; - let Pressure = WeatherCurrentConditions.Pressure; - let PressureDirection = WeatherCurrentConditions.PressureDirection; - let PressureUnit = ' inches '; - let WindSpeed = WeatherCurrentConditions.WindSpeed; - let WindGust = WeatherCurrentConditions.WindGust; - let WindDirection = WeatherCurrentConditions.WindDirection; - let WindUnit = ' miles per hour '; - let VisibilityUnit = ' miles '; - let Visibility = WeatherCurrentConditions.Visibility; - let Ceiling = WeatherCurrentConditions.Ceiling; - let CeilingUnit = ' feet '; - if (_Units === Units.Metric) { - Temperature = WeatherCurrentConditions.TemperatureC.toString(); - HeatIndex = WeatherCurrentConditions.HeatIndexC.toString(); - WindChill = WeatherCurrentConditions.WindChillC.toString(); - Humidity = WeatherCurrentConditions.Humidity.toString(); - DewPoint = WeatherCurrentConditions.DewPointC.toString(); - Pressure = WeatherCurrentConditions.PressureC.toString(); - PressureDirection = WeatherCurrentConditions.PressureDirection; - PressureUnit = ' millibars '; - WindSpeed = WeatherCurrentConditions.WindSpeedC.toString(); - WindGust = WeatherCurrentConditions.WindGustC.toString(); - WindDirection = WeatherCurrentConditions.WindDirection; - WindUnit = ' kilometers per hour '; - VisibilityUnit = ' kilometers '; - Visibility = WeatherCurrentConditions.VisibilityC.toString(); - Ceiling = WeatherCurrentConditions.CeilingC.toString(); - CeilingUnit = ' meters '; - - } - - Text += `The current conditions at ${WeatherCurrentConditions.StationName}. `; - Text += WeatherCurrentConditions.Conditions + '. '; - Text += Temperature.toString().replaceAll('.', ' point ') + ' degrees '; - - if (HeatIndex !== Temperature) { - Text += 'with a heat index of ' + HeatIndex.toString().replaceAll('.', ' point ') + ' degrees '; - } else if (WindChill !== '' && WindChill < Temperature) { - Text += 'with a wind chill of ' + WindChill.toString().replaceAll('.', ' point ') + ' degrees'; - } - Text += '. '; - - if (WindSpeed > 0) { - Text += 'Winds ' + GetWindDirectionWords(WindDirection) + ' at ' + WindSpeed + WindUnit; - } else if (WindSpeed === 'NA') { - Text += 'Winds are not available '; - } else { - Text += 'Winds are calm '; - } - if (WindGust !== '') { - Text += ' gusts to ' + WindGust; - } - Text += '. '; - - Text += 'Humidity is ' + Humidity.toString() + ' percent. '; - Text += 'Dewpoint is ' + DewPoint.toString().replaceAll('.', ' point ') + ' degrees. '; - - Text += 'Ceiling is ' + (Ceiling === '' ? 'Unlimited' : Ceiling + CeilingUnit) + '. '; - Text += 'Visibility is ' + parseInt(Visibility).toString() + VisibilityUnit + '. '; - - Text += 'Barometric Pressure is ' + Pressure.replaceAll('.', ' point ') + ' ' + PressureUnit + ' and '; - switch (PressureDirection) { - case 'R': - Text += 'rising'; - break; - case 'F': - Text += 'falling'; - break; - default: - } - Text += '. ';} - - break; - - case CanvasTypes.LatestObservations: - {const WeatherCurrentRegionalConditions = _WeatherParameters.WeatherCurrentRegionalConditions; - const SortedArray = WeatherCurrentRegionalConditions.SortedArray; - - Text += 'Latest observations for the following cities. '; - - $(SortedArray).each(function () { - const WeatherCurrentCondition = this; - - - let Temperature = WeatherCurrentCondition.Temperature; - let WindSpeed = WeatherCurrentCondition.WindSpeed; - let WindUnit = ' miles per hour '; - - if (_Units === Units.Metric) { - Temperature = Math.round(WeatherCurrentCondition.TemperatureC); - WindSpeed = WeatherCurrentCondition.WindSpeedC; - WindUnit = ' kilometers per hour '; - } - - Text += WeatherCurrentCondition.StationName + ' '; - Text += WeatherCurrentCondition.Conditions + '. '; - Text += Temperature.toString().replaceAll('.', ' point ') + ' degrees '; - - if (WeatherCurrentCondition.WindSpeed > 0) { - Text += ' with Winds ' + GetWindDirectionWords(WeatherCurrentCondition.WindDirection) + ' at ' + WindSpeed.toString() + ' ' + WindUnit + ' '; - } else { - Text += ' with Calm Winds '; - } - - Text += '. '; - - });} - - break; - - case CanvasTypes.ExtendedForecast1: - case CanvasTypes.ExtendedForecast2: - { const WeatherExtendedForecast = _WeatherParameters.WeatherExtendedForecast; - - Text += 'Extended Forecast. '; - - let LBound; - let UBound; - switch (CanvasType) { - case CanvasTypes.ExtendedForecast1: - LBound = 0; - UBound = 2; - break; - case CanvasTypes.ExtendedForecast2: - LBound = 3; - UBound = 5; - break; - default: - } - - $(WeatherExtendedForecast.Day).each(function (Index) { - if (Index < LBound || Index > UBound) return true; - - const Day = this; - let MinimumTemperature = Day.MinimumTemperature; - let MaximumTemperature = Day.MaximumTemperature; - - if (_Units === Units.Metric) { - MinimumTemperature = Math.round(Day.MinimumTemperatureC); - MaximumTemperature = Math.round(Day.MaximumTemperatureC); - } - - Text += Day.DayName + ' '; - Text += Day.Conditions + '. '; - Text += ' with a high of ' + MaximumTemperature.toString().replaceAll('.', ' point ') + ' '; - Text += ' and a low of ' + MinimumTemperature.toString().replaceAll('.', ' point ') + ' '; - Text += '. '; - }); - } - break; - - case CanvasTypes.Almanac: - { const AlmanacInfo = _WeatherParameters.AlmanacInfo; - const Today = DateTime.local(); - const Tomorrow = Today.plus({days: 1}); - - if (isNaN(AlmanacInfo.TodaySunRise)) { - Text += 'No sunrise for ' + Today.getDayName() + ' '; - } else { - Text += 'Sunrise for ' + Today.getDayName() + ' is at ' + AlmanacInfo.TodaySunRise.getFormattedTime() + ' '; - } - if (isNaN(AlmanacInfo.TodaySunSet)) { - Text += 'no setset. '; - } else { - Text += 'sunset is at ' + AlmanacInfo.TodaySunSet.getFormattedTime() + '. '; - } - - if (isNaN(AlmanacInfo.TomorrowSunRise)) { - Text += 'No sunrise for ' + Tomorrow.getDayName() + ' '; - } else { - Text += 'Sunrise for ' + Tomorrow.getDayName() + ' is at ' + AlmanacInfo.TomorrowSunRise.getFormattedTime() + ' '; - } - if (isNaN(AlmanacInfo.TomorrowSunSet)) { - Text += 'no setset. '; - } else { - Text += 'sunset is at ' + AlmanacInfo.TomorrowSunSet.getFormattedTime() + '. '; - } - - AlmanacInfo.MoonPhases.forEach(MoonPhase => { - switch (MoonPhase.Phase) { - case 'Full': - Text += 'Full moon '; - break; - case 'Last': - Text += 'Last quarter '; - break; - case 'New': - Text += 'New moon '; - break; - case 'First': - Text += 'First quarter '; - break; - default: - } - Text += 'is on ' + MoonPhase.Date.getMonthName() + ' ' + MoonPhase.Date.getDate().toString() + '. '; - }); - - Text += '. '; - - break;} - - case CanvasTypes.AlmanacTides: - { - const AlmanacInfo = _WeatherParameters.AlmanacInfo; - const WeatherTides = _WeatherParameters.WeatherTides; - let TideCounter = 0; - - WeatherTides.forEach(WeatherTide => { - Text += WeatherTide.StationName.toLowerCase() + ' Tides. '; - - TideCounter = 0; - Text += 'Low tides at '; - WeatherTide.TideTypes.forEach((TideType, Index) => { - if (TideType !== 'low') return true; - - let TideTime = WeatherTide.TideTimes[Index]; - let TideDay = WeatherTide.TideDays[Index]; - - if (_Units === Units.Metric) { - TideTime = utils.calc.TimeTo24Hour(TideTime); - } - TideDay = _DayLongNames[TideDay]; - - Text += TideDay + ' at ' + TideTime; - if (TideCounter === 0) { - Text += ' and '; - } else { - Text += '. '; - } - TideCounter++; - }); - - TideCounter = 0; - Text += 'High tides at '; - WeatherTide.TideTypes.forEach((TideType, Index) => { - if (TideType !== 'high') return true; - - let TideTime = WeatherTide.TideTimes[Index]; - let TideDay = WeatherTide.TideDays[Index]; - - if (_Units === Units.Metric) { - TideTime = utils.calc.TimeTo24Hour(TideTime); - } - TideDay = _DayLongNames[TideDay]; - - Text += TideDay + ' at ' + TideTime; - if (TideCounter === 0) { - Text += ' and '; - } else { - Text += '. '; - } - TideCounter++; - }); - - }); - - if (isNaN(AlmanacInfo.TodaySunRise)) { - Text += 'No sunrise for today '; - } else { - Text += 'Sunrise for today is at ' + AlmanacInfo.TodaySunRise.getFormattedTime() + ' '; - } - if (isNaN(AlmanacInfo.TodaySunSet)) { - Text += ' and no setset. '; - } else { - Text += ' and sunset is at ' + AlmanacInfo.TodaySunSet.getFormattedTime() + '. '; - } - } - break; - - case CanvasTypes.Outlook: - {const Outlook = _WeatherParameters.Outlook; - - Text += 'Your 30 day outlook from mid ' + _MonthLongNames[Outlook.From] + ' to mid ' + _MonthLongNames[Outlook.To] + '. '; - Text += 'Temperatures are expected to be ' + GetOutlookDescription(Outlook.Temperature) + '. '; - Text += 'Precipitation is expected to be ' + GetOutlookDescription(Outlook.Precipitation) + '. '; - } - break; - - case CanvasTypes.MarineForecast: - {const MarineForecast = _WeatherParameters.MarineForecast; - let WindSpeed; - let Tide; - - Text += 'Marine Forecast. '; - - if (MarineForecast.Warning !== '') { - Text += MarineForecast.Warning + '. '; - } - - Text += MarineForecast.TodayDayName; - - switch (_Units) { - case Units.English: - WindSpeed = MarineForecast.TodayWindSpeedHigh.toString() + ' knots.'; - if (MarineForecast.TodayWindSpeedLow !== MarineForecast.TodayWindSpeedHigh) { - WindSpeed = MarineForecast.TodayWindSpeedLow.toString() + ' to ' + WindSpeed; - } - break; - default: - WindSpeed = MarineForecast.TodayWindSpeedHighC.toString() + ' knots.'; - if (MarineForecast.TodayWindSpeedLowC !== MarineForecast.TodayWindSpeedHighC) { - WindSpeed = MarineForecast.TodayWindSpeedLowC.toString() + ' to ' + WindSpeed; - } - break; - } - Text += ' winds ' + GetWindDirectionWords(MarineForecast.TodayWindDirection) + ' at ' + WindSpeed; - - switch (_Units) { - case Units.English: - Tide = MarineForecast.TodayTideHigh.toString() + ' feet. '; - if (MarineForecast.TodayTideLow !== MarineForecast.TodayTideHigh) { - Tide = MarineForecast.TodayTideLow.toString() + ' to ' + Tide; - } - break; - default: - Tide = MarineForecast.TodayTideHighC.toString() + ' meters. '; - if (MarineForecast.TodayTideLowC !== MarineForecast.TodayTideHighC) { - Tide = MarineForecast.TodayTideLowC.toString() + ' to ' + Tide; - } - break; - } - Text += ' ' + MarineForecast.SeasOrWaves.capitalize() + ' at ' + Tide; - - - Text += MarineForecast.TomorrowDayName; - - switch (_Units) { - case Units.English: - WindSpeed = MarineForecast.TomorrowWindSpeedHigh.toString() + ' knots. '; - if (MarineForecast.TomorrowWindSpeedLow !== MarineForecast.TomorrowWindSpeedHigh) { - WindSpeed = MarineForecast.TomorrowWindSpeedLow.toString() + ' to ' + WindSpeed; - } - break; - default: - WindSpeed = MarineForecast.TomorrowWindSpeedHighC.toString() + ' knots. '; - if (MarineForecast.TomorrowWindSpeedLowC !== MarineForecast.TomorrowWindSpeedHighC) { - WindSpeed = MarineForecast.TomorrowWindSpeedLowC.toString() + ' to ' + WindSpeed; - } - break; - } - Text += ' winds ' + GetWindDirectionWords(MarineForecast.TomorrowWindDirection) + ' at ' + WindSpeed; - - switch (_Units) { - case Units.English: - Tide = MarineForecast.TomorrowTideHigh.toString() + ' feet. '; - if (MarineForecast.TomorrowTideLow !== MarineForecast.TomorrowTideHigh) { - Tide = MarineForecast.TomorrowTideLow.toString() + ' to ' + Tide; - } - break; - default: - Tide = MarineForecast.TomorrowTideHighC.toString() + ' meters. '; - if (MarineForecast.TomorrowTideLowC !== MarineForecast.TomorrowTideHighC) { - Tide = MarineForecast.TomorrowTideLowC.toString() + ' to ' + Tide; - } - break; - } - Text += ' ' + MarineForecast.SeasOrWaves.capitalize() + ' at ' + Tide; - } - break; - - case CanvasTypes.AirQuality: - {const AirQuality = _WeatherParameters.AirQuality; - - Text = 'Air quality forecast for ' + AirQuality.Date.getDayName() + '. '; - Text += AirQuality.City + ', ' + GetAqiDescription(AirQuality.IndexValue) + ' with an air quality index of ' + AirQuality.IndexValue.toString() + '.'; - } - break; - - case CanvasTypes.RegionalForecast1: - case CanvasTypes.RegionalForecast2: - { const Today = new Date(); - var addDays = 0; - var IsNightTime; - var RegionalForecastCities; - - if (CanvasType === CanvasTypes.RegionalForecast2) { - RegionalForecastCities = _WeatherParameters.RegionalForecastCities2; - - if (Today.getHours() >= 12) { - // Tomorrow's daytime forecast - addDays = 1; - Today.setHours(0, 0, 0, 0); - IsNightTime = false; - } else { - // Todays's nighttime forecast - if (Today.getHours() === 0) { - // Prevent Midnight from causing the wrong icons to appear. - Today.setHours(1, 0, 0, 0); - } - IsNightTime = true; - } - } else { - RegionalForecastCities = _WeatherParameters.RegionalForecastCities1; - - if (Today.getHours() >= 12) { - // Todays's nighttime forecast - // Prevent Midnight from causing the wrong icons to appear. - Today.setHours(1, 0, 0, 0); - IsNightTime = true; - } else { - // Today's daytime forecast - if (Today.getHours() === 0) { - // Prevent Midnight from causing the wrong icons to appear. - Today.setHours(1, 0, 0, 0); - } - IsNightTime = false; - } - } - - const Tomorrow = Today.addDays(addDays); - var DayName = Tomorrow.getDayName(); - - Text += 'Regional forecast for ' + DayName + (IsNightTime ? ' Night ' : '') + ' for the following cities. '; - - $(RegionalForecastCities).each(function () { - var RegionalForecastCity = this; - - var RegionalCity = RegionalForecastCity.RegionalCity; - var weatherTravelForecast = RegionalForecastCity.weatherTravelForecast; - - // City Name - Text += RegionalCity.Name + ' '; - Text += weatherTravelForecast.Conditions + ' '; - - // Temperature - if (IsNightTime) { - var MinimumTemperature; - if (_Units === Units.English) { - MinimumTemperature = weatherTravelForecast.MinimumTemperature.toString(); - } else { - MinimumTemperature = Math.round(weatherTravelForecast.MinimumTemperatureC).toString(); - } - Text += ' with a low of ' + MinimumTemperature.toString().replaceAll('.', ' point ') + '. '; - } else { - var MaximumTemperature; - if (_Units === Units.English) { - MaximumTemperature = weatherTravelForecast.MaximumTemperature.toString(); - } else { - MaximumTemperature = Math.round(weatherTravelForecast.MaximumTemperatureC).toString(); - } - Text += ' with a high of ' + MaximumTemperature.toString().replaceAll('.', ' point ') + '. '; - } - }); - - Text += '. '; - } - break; - - case CanvasTypes.RegionalObservations: - Text += 'Regional Observations for the following cities. '; - - $(_WeatherParameters.RegionalObservationsCities).each(function () { - var RegionalObservationsCity = this; - - var RegionalCity = RegionalObservationsCity.RegionalCity; - var weatherCurrentConditions = RegionalObservationsCity.weatherCurrentConditions; - - // City Name - Text += RegionalCity.Name + ' '; - Text += weatherCurrentConditions.Conditions + ' '; - - // Temperature - var Temperature; - if (_Units === Units.English) { - Temperature = weatherCurrentConditions.Temperature.toString(); - } else { - Temperature = Math.round(weatherCurrentConditions.TemperatureC).toString(); - } - Text += Temperature.toString().replaceAll('.', ' point ') + '. '; - - }); - - Text += '. '; - - break; - - case CanvasTypes.LocalForecast: - var LocalForecastScreenTexts = _WeatherParameters.LocalForecastScreenTexts; - var UpdateLocalForecastIndex = SubCanvasType; - Text = LocalForecastScreenTexts[UpdateLocalForecastIndex]; - Text = GetVerboseText(Text); - Text = Text.toLowerCase(); - break; - - case CanvasTypes.LocalRadar: - Text = 'Your local radar.'; - break; - - case CanvasTypes.TravelForecast: - var TravelCities = _WeatherParameters.TravelCities; - var UpdateTravelCitiesIndex = SubCanvasType; - - if (UpdateTravelCitiesIndex === 0) { - //Text += "Travel Forecast for " + TravelCities[0].WeatherTravelForecast.DayName + " for the following cities. "; - Text += 'Travel Forecast for ' + GetTravelCitiesDayName(TravelCities) + ' for the following cities. '; - } - - //for (var Index = (UpdateTravelCitiesIndex * 3) ; Index <= ((UpdateTravelCitiesIndex * 3) + 3) - 1; Index++) - $(TravelCities).each(function () { - var TravelCity = this; - var WeatherTravelForecast = TravelCity.WeatherTravelForecast; - - Text += TravelCity.Name + ' '; - - if (WeatherTravelForecast && WeatherTravelForecast.Icon !== 'images/r/') { - Text += WeatherTravelForecast.Conditions + ' '; - - var MinimumTemperature; - var MaximumTemperature; - - switch (_Units) { - case Units.English: - MinimumTemperature = WeatherTravelForecast.MinimumTemperature.toString(); - MaximumTemperature = WeatherTravelForecast.MaximumTemperature.toString(); - break; - - default: - MinimumTemperature = Math.round(WeatherTravelForecast.MinimumTemperatureC).toString(); - MaximumTemperature = Math.round(WeatherTravelForecast.MaximumTemperatureC).toString(); - break; - } - - Text += ' with high of ' + MaximumTemperature.replaceAll('.', ' point ') + ' '; - Text += ' and low of ' + MinimumTemperature.replaceAll('.', ' point ') + ' '; - } else { - Text += ' No travel data available '; - } - Text += '. '; - }); - - break; - - case CanvasTypes.Hazards: - var WeatherHazardConditions = _WeatherParameters.WeatherHazardConditions; - - switch (_Units) { - case Units.English: - Text = WeatherHazardConditions.HazardsText; - break; - - default: - Text = WeatherHazardConditions.HazardsTextC; - break; - } - - Text = GetVerboseText(Text); - Text = Text.toLowerCase(); - - break; - default: - } - - return Text; -}; - -const GetVerboseText = (Text) => { - Text = ' ' + Text; - Text = Text.replaceAll('\n', ' '); - Text = Text.replaceAll('*', ' '); - - Text = Text.replaceAll(' MPH', ' MILES PER HOUR'); - Text = Text.replaceAll(' KPH', ' KILOMETERS PER HOUR'); - Text = Text.replaceAll(' IN.', ' INCHES '); - Text = Text.replaceAll(' CM.', ' CENTIMETERS '); - - Text = Text.replaceAll(' EST', ' EASTERN STANDARD TIME'); - Text = Text.replaceAll(' CST', ' CENTRAL STANDARD TIME'); - Text = Text.replaceAll(' MST', ' MOUNTAIN STANDARD TIME'); - Text = Text.replaceAll(' PST', ' PACIFIC STANDARD TIME'); - Text = Text.replaceAll(' AST', ' ALASKA STANDARD TIME'); - Text = Text.replaceAll(' AKST', ' ALASKA STANDARD TIME'); - Text = Text.replaceAll(' HST', ' HAWAII STANDARD TIME'); - - //'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety - Text = Text.replaceAll(' -0S', ' MINUS SINGLE DIGITS '); - Text = Text.replaceAll(' -10S', ' MINUS TEENS '); - Text = Text.replaceAll(' -20S', ' MINUS TWENTIES '); - Text = Text.replaceAll(' -30S', ' MINUS THIRTIES '); - Text = Text.replaceAll(' -40S', ' MINUS FORTIES '); - Text = Text.replaceAll(' -50S', ' MINUS FIFTIES '); - Text = Text.replaceAll(' -60S', ' MINUS SIXTIES '); - Text = Text.replaceAll(' -70S', ' MINUS SEVENTIES '); - Text = Text.replaceAll(' -80S', ' MINUS EIGHTIES '); - Text = Text.replaceAll(' -90S', ' MINUS NINETIES '); - Text = Text.replaceAll(' 0S', ' SINGLE DIGITS '); - Text = Text.replaceAll(' 10S', ' TEENS '); - Text = Text.replaceAll(' 20S', ' TWENTIES '); - Text = Text.replaceAll(' 30S', ' THIRTIES '); - Text = Text.replaceAll(' 40S', ' FORTIES '); - Text = Text.replaceAll(' 50S', ' FIFTIES '); - Text = Text.replaceAll(' 60S', ' SIXTIES '); - Text = Text.replaceAll(' 70S', ' SEVENTIES '); - Text = Text.replaceAll(' 80S', ' EIGHTIES '); - Text = Text.replaceAll(' 90S', ' NINETIES '); - Text = Text.replaceAll(' 100S', ' HUNDREDS '); - Text = Text.replaceAll(' 110S', ' HUNDRED TEENS '); - Text = Text.replaceAll(' 120S', ' HUNDRED TWENTIES '); - Text = Text.replaceAll(' 130S', ' HUNDRED THIRTIES '); - Text = Text.replaceAll(' 140S', ' HUNDRED FORTIES '); - Text = Text.replaceAll(' 150S', ' HUNDRED FIFTIES '); - Text = Text.replaceAll(' 160S', ' HUNDRED SIXTIES '); - Text = Text.replaceAll(' 170S', ' HUNDRED SEVENTIES '); - Text = Text.replaceAll(' 180S', ' HUNDRED EIGHTIES '); - Text = Text.replaceAll(' 190S', ' HUNDRED NINETIES '); - - return Text; -}; - -const GetWindDirectionWords = (WindDirection) => { - var Words = WindDirection; - - Words = Words.replaceAll('N', 'North '); - Words = Words.replaceAll('S', 'South '); - Words = Words.replaceAll('E', 'East '); - Words = Words.replaceAll('W', 'West '); - - return Words; -}; - const AssignScrollText = (e) => { _ScrollText = e.ScrollText; _UpdateCustomScrollTextMs = 0;