<head>
<meta charset="UTF-8">
<title>Weather</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="header">
<h1>Weather</h1>
<ul class="menu">
<li><a href="https://www.youtube.com/channel/UCYSm9G0x1Da2WE2lWSA4ivA?view_as=subscriber">Youtube</a></li>
<li><a href="https://vk.com/davidk1ng">VKontakte</a></li>
<li><a href="https://www.instagram.com/d_avi_d/">Instagram</a></li>
</ul>
</div>
<div class="container">
<input type="text" class="city" required="">
<div class="error"></div>
<button class="button" onclick="buttonClicked()">Get Weather</button>
<div class="weather">
<div class="forecast">
<div class="day">
<img src="" alt="" class="icon">
<h2 class="temp">0°</h2>
<h4 class="date">12 Apr</h4>
<h6 class="weather_desc">Cloudly</h6>
</div>
<div class="day">
<img src="" alt="" class="icon">
<h2 class="temp">1°</h2>
<h4 class="date">12 Apr</h4>
<h6 class="weather_desc">Cloudly</h6>
</div>
<div class="day">
<img src="" alt="" class="icon">
<h2 class="temp">2°</h2>
<h4 class="date">12 Apr</h4>
<h6 class="weather_desc">Cloudly</h6>
</div>
<div class="day">
<img src="" alt="" class="icon">
<h2 class="temp">3°</h2>
<h4 class="date">12 Apr</h4>
<h6 class="weather_desc">Cloudly</h6>
</div>
<div class="day">
<img src="" alt="" class="icon">
<h2 class="temp">4°</h2>
<h4 class="date">12 Apr</h4>
<h6 class="weather_desc">Cloudly</h6>
</div>
</div>
</div>
</div>
<script src="scripts/script.js"></script>
</body>
</html>
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,500;1,300;1,600&display=swap');
:root {
--WHITE: #FFF;
--BLACK: #000;
--LIGHT_GRAY: #777;
--DARK_GRAY: #333;
}
* {
padding: 0;
margin: 0;
font-family: 'Montserrat', sans-serif;
outline: none;
text-transform: uppercase;
text-decoration: none;
list-style-type: none;
box-sizing: border-box;
text-align: center;
}
body {
background: linear-gradient(45deg, #006cff, #9379ff, #4effd6);
background-size: 500% 1000%;
animation: body_ga 10s ease infinite;
}
@keyframes body_ga {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.container {
width: 80vw;
margin: 0 auto;
}
.header {
padding-top: .5em;
background: #333;
font-size: 3vw;
color: var(--LIGHT_GRAY);
transition: all .1s;
}
.header:hover {
padding: .5em 0;
}
.header:hover .menu {
opacity: 1;
}
.menu {
display: flex;
justify-content: space-around;
/* position: relative;*/
top: 4vh;
opacity: 0;
transition: all .2s;
}
.menu li a, p {
color: var(--LIGHT_GRAY);
font-size: 25px;
font-weight: 700;
cursor: pointer;
}
.city {
margin: 2vh 0;
padding: 1em 2em;
width: 100%;
border-radius: 100vh;
border: 2px solid rgba(0,0,0,0);
text-align: left;
transition: all .2s;
}
.city:focus {
border: 2px solid #3b3b5b;
color: var(--BLACK);
}
.error {
background: rgba(255, 177, 0, 0.5);
color: #FFF;
margin-bottom: 2vh;
padding: 1em;
border-radius: .5em;
display: none;
font-weight: 700;
}
@keyframes emergence {
0% {
opacity: 0;
margin-top: -60px;
}
100% {
opacity: 1;
margin-top: 0;
}
}
@keyframes disappearance {
0% {
opacity: 1;
margin-top: 0;
}
100% {
opacity: 0;
margin-top: -60px;
}
}
.button {
padding: .7em .7em;
width: 100%;
border: none;
border-radius: .8em;
background: linear-gradient(to right, #F600FF, #0078FF);
background-size: 100% 100%;
color: var(--WHITE);
font-weight: 700;
font-size: 20px;
transition: all .5s;
}
.button:hover {
background: linear-gradient(45deg, #F600FF, #FF7979, #0078FF);
background-size: 500% 500%;
animation: button_ga 8s ease infinite;
}
@keyframes button_ga{
0% {
background-position: 0 50%:
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}
.button:active {
background: var(--BLACK);
border-radius: 0;
}
.weather {
margin: 3em 0;
}
@keyframes change {
0% {
margin-top: 0px;
}
50% {
margin-top: 50px;
opacity: 0;
}
51% {
margin-top: -50px;
}
100% {
margin-top: 0;
opacity: 1;
}
}
.forecast {
display: flex;
justify-content: space-between;
}
.day {
width: 15vw;
height: 13em;
padding: .3em;
background: var(--DARK_GRAY);
border-radius: .8em;
color: var(--WHITE);
animation: none;
word-wrap: break-word;
}
'use strict';
let city = document.querySelector(".city");
let error = document.querySelector(".error");
let descValue = undefined;
let i = 1;
function buttonClicked() {
if (city.value == "") {
error.textContent = "Please enter your city before click the button.";
error.style.display = "block";
error.style.animation = "emergence .5s cubic-bezier(0, .50, .50, 1)";
error.style.opacity = 1;
} else {
fetch('https://api.openweathermap.org/data/2.5/forecast?q=' + city.value + '&appid=44be5522c6a2f5037fb0939a51589ddd')
.then(response => response.json())
.then(data => {
let date = new Date(data['list'][0]['dt_txt']);
for (i=0;i<=4;i++) {
let day = document.querySelectorAll(".day");
let date = day[i].querySelector(".date");
let temp = day[i].querySelector(".temp");
let desc = day[i].querySelector(".weather_desc");
let icon = day[i].querySelector(".icon");
let dateValue = new Date(data['list'][i*8]['dt_txt']);
day[i].style.animation = "change .5s cubic-bezier(0, .70, .30, 1)";
temp.textContent = Math.floor(data['list'][i]['main']['temp']) - 273 + "°";
date.textContent = dateValue.getDate() + " " + dateValue.toLocaleString('en-us', {month: 'short'});
desc.textContent = data['list'][i]['weather'][0]['description'];
icon.setAttribute("Src", "http://openweathermap.org/img/wn/" + data['list'][i]['weather'][0]['icon'] + "@2x.png");
setTimeout('day[i].removeAttribute("style")', 500);
}
error.style.animation = "disappearance .5s cubic-bezier(0, .50, .50, 1)";
setTimeout('error.style.display = "none"', 500);
})
.catch(err => {
error.textContent = "You entered the wrong city!";
error.style.display = "block";
error.style.animation = "emergence .5s cubic-bezier(0, .50, .50, 1)";
error.style.opacity = 1;
})
}
};
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.