/* NOTES
Please make sure to check CSS settings to see the external libraries loaded here, such as Open Props
https://open-props.style
*/
@import url("https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&family=Maven+Pro:wght@400;700&family=Oswald:wght@200;700&display=swap");
:root {
--main-color1: var(--teal-9);
--main-color2: var(--gray-9);
--main-color3: #f0f4b5;
--font1: "Maven Pro", sans-serif;
--font2: "DM Serif Display", sans-serif;
--mainBG: linear-gradient(
to right top,
var(--teal-9),
#004d7a,
#008793,
#00bf72,
#a8eb12
);
--radius-value-1: 1.25rem;
--radius-value-2: 0px 0px .75rem .75rem;
--box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
}
body {
background-color: #000;
}
h1 {
font-family: var(--font1);
color: var(--teal-9);
font-size: 2.6rem;
font-weight: 700;
margin: 0;
padding: .3rem;
text-align: center;
text-shadow: -1px -1px 1px rgba(255,255,255,.1), 1px 1px 1px rgba(0,0,0,.5);
}
div.leaflet-popup-content h1 {
color: var(--main-color2);
font-size: 2.25rem;
line-height: 2.5rem;
font-weight: normal !important;
}
:where(h2, h3) {
color: var(--main-color1);
font-family: var(--font2);
margin: 0;
padding: 1rem;
}
h2 {
color: white;
padding: 0.5rem;
margin: 0;
background-color: rgba(0 0 0 /0.3);
border-radius: var(--radius-value-1);
}
h3 {
color: var(--main-color3);
font-weight: 400;
}
h3:first-letter {
text-transform: uppercase;
}
p {
color: white;
font-family: var(--font1);
margin: 0.25rem;
font-size: 1.15rem;
line-height: 1.14rem;
}
div.leaflet-popup-content p {
color: var(--main-color1);
margin: 0;
text-align: center;
}
div#currentWeather p,
div#details p {
margin-bottom: .5rem;
}
p span.myDataHighlights
{
color: var(--main-color3);
}
main
{
margin: 0 auto;
}
section.mainContainer {
margin-top: 1rem;
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-gap: 1rem;
}
/* div.leaflet-popup-content-wrapper
{
margin: .5rem;
background-color:rgba(255 255 255 /.64) ;
position: relative;
top: 10px!important;
}
.leaflet-popup-tip-container {
}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup
{
margin-top: 1rem;
} */
div#map {
width: 100%;
max-width: 90rem;
height: 300px;
border-radius: var(--radius-value-1);
}
div#currentConditionsHeader {
margin-bottom: 2rem;
border-radius: var(--radius-value-1);
padding: .3rem;
box-shadow: 0 2px 6px rgba(0,0,0,0.5), inset 0 1px rgba(255,255,255,0.3), inset 0 10px rgba(255,255,255,0.2), inset 0 10px 20px rgba(255,255,255,0.25), inset 0 -15px 30px rgba(0,0,0,0.3);
}
div#details {
border: 1px solid rgba(0 0 0/1);
padding: 1rem;
width: 100%;
max-width: 36rem;
background-image: var(--mainBG);
border-radius: var(--radius-value-1);
}
div.currentConditions {
text-transform: capitalize;
}
img.myWeatherIcon {
float: left;
width: 100%;
height: auto;
max-width: 3rem;
margin-top:0rem;
margin-right: 1rem;
margin-bottom: 0rem;
border-radius: var(--radius-value);
padding: .2rem;
box-shadow: var(--box-shadow);
}
@media (min-width: 768px)
{
section.mainContainer {
grid-template-columns: repeat(2, 1fr);
}
div#details {
max-width: 48rem;
}
// NOTES
// Please make sure to check JS settings to see the external libraries loaded here, such as Leaflet
// https://leafletjs.com/
// What is a timestamp? Unix timestamps are the number of seconds elapsed since 01-01-1970 00:00:00 UTC - generally it should be equal everywhere.
// https://stackoverflow.com/questions/221294/how-do-i-get-a-timestamp-in-javascript
console.clear();
$(document).ready(function () {
// run this function as soon as the page has completely loaded:
drawMyMap(); // this function is created below
});
function myUNIXconverter(my_IP_data, ampm) {
let unix_timestamp = my_IP_data;
// Here we create a new JavaScript Date object based on the timestamp.
// Pro tip: see how we multiply the timestamp by 1000 so that the argument is in milliseconds, not seconds:
var date = new Date(unix_timestamp * 1000);
// Year from the timestamp
var my_year = date.getFullYear();
// Hours from the timestamp
var hours = date.getHours();
// Gives us a 24-hour day with no 13 o'clock:
if (hours > 11) {
hours = hours - 12;
}
// Minutes from the timestamp
var minutes = "0" + date.getMinutes();
// Seconds from the timestamp
var seconds = "0" + date.getSeconds();
var formattedTime = hours + ":" + minutes.substr(-2); // Will display time in 10:30:23 format
return formattedTime + ampm;
}
// /////////////////////
// Get My IP ADDRESS ///
// /////////////////////
// Here I use an external API which determines my IP address and related information about my location then returns it to me as JSON:
function drawMyMap(my_IP_data) {
$.getJSON("https://ipapi.co/json/", function (my_IP_data) {
console.log("Received data:", my_IP_data); // For testing
// go through the received data and create variables as needed:
var ip = my_IP_data.ip;
var myLatitude = my_IP_data.latitude;
var myLongitude = my_IP_data.longitude;
var region = my_IP_data.region;
var city = my_IP_data.city;
var postal = my_IP_data.postal;
var myZoom = "14";
var myLatLong = [myLatitude, myLongitude];
var map = L.map("map").setView(myLatLong, myZoom);
// Here, I load "tiles" from a mapping API called Leaflet //
L.tileLayer("https://{s}.tile.osm.org/{z}/{x}/{y}.png", {
attribution: "© JWC "
}).addTo(map);
L.marker(myLatLong)
.addTo(map)
.bindPopup(
'<div id="currentWeather"></div><p>' + city + ", " + region + "</p>"
)
.openPopup();
///////////////////////
// WEATHER ////////////
///////////////////////
// Now I use a weather API: https://openweathermap.org/current#current_JSON
// REMEMBER: you need to add your own (free) API key to get this to show the weather.
// See: https://openweathermap.org/appid#:~:text=The%20API%20key%20is%20all,additional%20API%20keys%20if%20needed.%205c83aa0632e9e1a99ec3d9c6902ebc41
var myKey = "5c83aa0632e9e1a99ec3d9c6902ebc41";
var unit = "imperial";
var weatherUrl =
"https://api.openweathermap.org/data/2.5/weather?forecast&zip=" +
postal +
"&appid=" +
myKey +
"&units=" +
unit;
// If there *is* a zip code, made an AJAX call to the wetaher API and request data as jsonp:
if (postal) {
$.ajax({
url: weatherUrl,
type: "GET",
dataType: "jsonp",
success: function (my_weather_data) {
var widget = show_the_weather(my_weather_data);
$("#currentWeather").html(widget); // NOTE: "currentWeather" is a div created in the map widget, above
}
});
}
});
}
// Get the weather values from the returned weather data array:
function show_the_weather(my_weather_data) {
var initialTemperature = Math.round(my_weather_data.main.temp);
var feels_like = Math.round(my_weather_data.main.feels_like);
var temp_max = Math.round(my_weather_data.main.temp_max);
var temp_min = Math.round(my_weather_data.main.temp_min);
var humidity = Math.round(my_weather_data.main.humidity);
var wind = Math.round(my_weather_data.wind.speed);
var wind_direction = Math.round(my_weather_data.wind.deg);
var wind_gust = Math.round(my_weather_data.wind.gust);
console.log(wind_gust);
let wind_gust_text = "";
if (wind_gust) {
wind_gust_text =
', gusting to <span class="myDataHighlights">' + wind_gust + "</span>";
} else {
wind_gust_text = "";
}
// https://uni.edu/storm/Wind%20Direction%20slide.pdf:
if (wind_direction == 150 || wind_direction == 160) {
wind_direction = "SE";
} else if (
wind_direction == 350 ||
wind_direction == 360 ||
wind_direction == 10
) {
wind_direction = "N";
} else if (wind_direction == 20 || wind_direction == 30) {
wind_direction = "N NE";
} else if (wind_direction == 40 || wind_direction == 50) {
wind_direction = "NE";
} else if (wind_direction == 60 || wind_direction == 70) {
wind_direction = "E NE";
} else if (
wind_direction == 80 ||
wind_direction == 90 ||
wind_direction == 100
) {
wind_direction = "E";
} else if (wind_direction == 110 || wind_direction == 120) {
wind_direction = "E SE";
} else if (wind_direction == 130 || wind_direction == 140) {
wind_direction = "SE";
} else if (wind_direction == 150 || wind_direction == 160) {
wind_direction = "S SE";
} else if (
wind_direction == 170 ||
wind_direction == 180 ||
wind_direction == 190
) {
wind_direction = "S";
} else if (wind_direction == 200 || wind_direction == 210) {
wind_direction = "S SW";
} else if (wind_direction == 220 || wind_direction == 230) {
wind_direction = "SW";
} else if (wind_direction == 240 || wind_direction == 250) {
wind_direction = "W SW";
} else if (
wind_direction == 260 ||
wind_direction == 270 ||
wind_direction == 280
) {
wind_direction = "W";
} else if (wind_direction == 290 || wind_direction == 300) {
wind_direction = "W NW";
} else if (wind_direction == 310 || wind_direction == 320) {
wind_direction = "NW";
} else if (wind_direction == 330 || wind_direction == 340) {
wind_direction = "N NW";
} else {
wind_direction = "";
}
var sunrise = myUNIXconverter(my_weather_data.sys.sunrise, "am");
var sunset = myUNIXconverter(my_weather_data.sys.sunset, "pm");
var currentConditions = my_weather_data.weather[0].main;
var currentConditionLocation = my_weather_data.name;
var currentConditionDescription = my_weather_data.weather[0].description;
console.log(currentConditionDescription);
switch (currentConditionDescription) {
case "clear sky":
var weatherConditionsIcon = "https://openweathermap.org/img/wn/01n.png";
break;
case "few clouds":
var weatherConditionsIcon = "https://openweathermap.org/img/wn/02n.png";
break;
case "broken clouds":
var weatherConditionsIcon = "https://openweathermap.org/img/wn/04n.png";
break;
case "scattered clouds":
case "overcast clouds":
var weatherConditionsIcon = "https://openweathermap.org/img/wn/03n.png";
break;
case "rain":
case "shower rain":
case "moderate rain":
case "light rain":
var weatherConditionsIcon =
"https://openweathermap.org/img/wn/09n@2x.png";
break;
case "thunderstorm":
var weatherConditionsIcon =
"https://openweathermap.org/img/wn/11n@2x.png";
break;
case "snow":
var weatherConditionsIcon =
"https://openweathermap.org/img/wn/13n@2x.png";
break;
case "mist":
var weatherConditionsIcon =
"https://openweathermap.org/img/wn/50n@2x.png";
break;
default:
var weatherConditionsIcon =
"https://openweathermap.org/img/wn/50n@2x.png";
break;
}
console.log(weatherConditionsIcon);
// Use jQuery to populate the "details" div with our concatenated data:
$("#details").html(
'<div id="currentConditionsHeader">' +
'<h2 class="currentConditions">' +
currentConditions +
"</h2>" +
'<img src="' +
weatherConditionsIcon +
'" class="myWeatherIcon"/>' +
'<h3 class="currentConditions">' +
currentConditionDescription +
" in the " +
currentConditionLocation +
" area</h3></div>" +
'<p>It\'s <span class="myDataHighlights"> ' +
initialTemperature +
'</span> degrees outside (it feels like <span class="myDataHighlights">' +
feels_like +
'</span>, due to <span class="myDataHighlights">' +
humidity +
"%</span> humidity.)</p>" +
'<p>Wind is <span class="myDataHighlights">' +
wind_direction +
'</span> @ <span class="myDataHighlights">' +
wind +
" mph</span>" +
wind_gust_text +
".</p>" +
'<p>Today it\'s likely to get as high as <span class="myDataHighlights">' +
temp_max +
'</span>, with a low of <span class="myDataHighlights">' +
temp_min +
"</span>.</p>" +
'<p>Sunrise @ <span class="myDataHighlights">' +
sunrise +
'</span>, sunset @ <span class="myDataHighlights">' +
sunset +
"</span>."
);
// write to the log so we can confirm our rec'd data
console.log(my_weather_data);
return "<h1><strong> " + initialTemperature + "°</strong></h1>";
}