Skip to content

Instantly share code, notes, and snippets.

@charlottetan
Last active October 10, 2016 21:15
Show Gist options
  • Save charlottetan/6c7a2468eea203988eec5f83b3949b57 to your computer and use it in GitHub Desktop.
Save charlottetan/6c7a2468eea203988eec5f83b3949b57 to your computer and use it in GitHub Desktop.
Hey, is it raining in Seattle?
<div id="tempWrapper">
<div id="temp">19</div>
<div id="unit">F</div>
</div>
<div class="icon unknown hidden">
<div class="text">?</div>
</div>
<div class="icon thunderstorm hidden">
<div class="cloud"></div>
<div class="lightning">
<div class="bolt"></div>
<div class="bolt"></div>
</div>
</div>
<div class="icon rainy">
<div class="cloud"></div>
<div class="rain"></div>
</div>
<div class="icon snowy hidden">
<div class="cloud"></div>
<div class="snow">
<div class="flake"></div>
<div class="flake"></div>
</div>
</div>
<div class="icon atmosphere hidden">
<div class="cloud grey"></div>
</div>
<div class="icon sunny hidden">
<div class="sun">
<div class="rays"></div>
</div>
</div>
<div class="icon cloudy hidden">
<div class="cloud"></div>
<div class="cloud"></div>
</div>
<div id="city" contenteditable>Seattle</div>
$(function() {
var $city = $('#city');
var unit = 'imperial';
var lastData = {};
var weatherApiKey = 'd2ae6d25c09549f38d8feed1d116c580';
var weatherApi = 'http://api.openweathermap.org/data/2.5/weather?callback=?';
var startPos;
// seattle
var lat = 47.6097;
var lon = -122.3331;
var geoOptions = {
maximumAge: 5 * 60 * 1000,
timeout: 10 * 1000
}
var printResults = function(data) {
if (data) {
lastData = data;
}
$("#city").text(lastData.name);
$("#temp").text(lastData.main.temp.toFixed(0));
$(".icon").addClass('hidden');
var weatherCode = parseInt(lastData.weather[0].id, 10);
console.log(weatherCode);
if (weatherCode < 300) {
$(".thunderstorm").removeClass('hidden');
} else if (weatherCode < 600) {
$(".rainy").removeClass('hidden');
} else if (weatherCode < 700) {
$(".snowy").removeClass('hidden');
} else if (weatherCode < 800) {
$(".atmosphere").removeClass('hidden');
} else if (weatherCode < 801) {
$(".sunny").removeClass('hidden');
} else if (weatherCode < 900) {
$(".cloudy").removeClass('hidden');
} else {
$(".unknown").removeClass('hidden');
}
};
var getWeather = function(lat, lon, q) {
var city = $city.text();
$city.text(city + ' (Loading...)');
var weatherData = {
appid: weatherApiKey,
units: unit
};
if (q) {
weatherData.q = q;
} else {
weatherData.lat = lat;
weatherData.lon = lon;
}
$.getJSON(weatherApi, weatherData, printResults);
};
var geoSuccess = function(position) {
startPos = position;
lat = startPos.coords.latitude;
lon = startPos.coords.longitude;
getWeather(lat, lon);
};
var geoError = function(error) {
console.log('Error occurred. Error code: ' + error.code);
// error.code can be:
// 0: unknown error
// 1: permission denied
// 2: position unavailable (error response from location provider)
// 3: timed out
// ignore it and use the default lat and lon
getWeather(lat, lon);
};
var searchByLocation = function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
} else {
getWeather(lat, lon);
}
};
var searchByCity = function(event) {
var esc = event.which == 27;
var enter = event.which == 13;
var ele = event.target;
if (esc) {
resetCity();
} else if (enter) {
event.preventDefault();
var city = $city.text();
getWeather(null, null, city);
ele.blur();
}
};
var resetCity = function() {
$city.text(lastData.name).blur();
};
var changeUnit = function() {
var $temp = $("#temp");
var $unit = $('#unit');
var currentTemp = parseFloat($temp.text());
var newTemp = 0;
//°C x 9/5 + 32 = °F
// (°F - 32) x 5/9 = °C
if (unit === 'imperial') {
newTemp = (currentTemp - 32) * 5 / 9;
unit = 'metric';
$unit.text('C');
} else {
newTemp = currentTemp * 9 / 5 + 32;
unit = 'imperial';
$unit.text('F');
}
$temp.text(newTemp.toFixed(0));
}
$("#city").keydown(searchByCity).focusout(resetCity);
$("#unit").click(changeUnit);
searchByLocation();
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
$stroke-color: #161616;
$bg-color: #fff;
$accent-color: #0cf;
body {
max-width: 42em;
padding: 2em;
margin: 0 auto;
color: $stroke-color;
font-family: sans-serif;
text-align: center;
background-color: $bg-color;
}
[contenteditable] {
display: inline-block;
position: relative;
padding: 0.3em;
border: 3px solid transparent;
border-radius: 2rem;
&:focus {
border-color: $accent-color;
outline-width: 0;
&:after {
content: '';
}
}
&:hover:after {
position: absolute;
content: '(click to edit)';
color: $accent-color;
font-family: sans-serif;
margin-left: 1em;
width: 10rem;
text-align: left;
}
}
#city {
display: block;
font-size: 1.2em;
width: 14rem;
margin: -2.5em auto 0;
cursor: pointer;
z-index: 5;
}
#tempWrapper {
display: inline-block;
font-size: 8em;
position: relative;
height: 8rem;
width: 40%;
z-index: 5;
#temp {
top: -70%;
right: 1.2em;
position: absolute;
}
#unit {
top: -70%;
right: 0.4em;
position: absolute;
cursor: pointer;
color: $accent-color;
user-select: none;
&:hover {
color: lighten($accent-color, 30%);
}
}
}
.icon {
position: relative;
width: 30%;
height: 10em;
font-size: 2em; /* control icon size here */
left: 0;
display: inline-block;
}
.hidden {
display: none;
}
.text {
position: absolute;
top: 50%;
left: 50%;
width: 3.6875em;
height: 3.6875em;
margin: -0.5em -1.84375em;
background: $bg-color;
border-radius: 50%;
font-size: 5em;
}
.cloud {
position: absolute;
z-index: 1;
top: 50%;
left: 50%;
width: 3.6875em;
height: 3.6875em;
margin: -1.84375em;
background: $bg-color;
border-radius: 50%;
box-shadow:
-2.1875em 0.6875em 0 -0.6875em $bg-color,
2.0625em 0.9375em 0 -0.9375em $bg-color,
0 0 0 0.375em $stroke-color,
-2.1875em 0.6875em 0 -0.3125em $stroke-color,
2.0625em 0.9375em 0 -0.5625em $stroke-color;
&:after {
content: '';
position: absolute;
bottom: 0;
left: -0.5em;
display: block;
width: 4.5625em;
height: 1em;
background: $bg-color;
box-shadow: 0 0.4375em 0 -0.0625em $stroke-color;
}
:nth-child(2) {
z-index: 0;
background: $stroke-color;
box-shadow:
-2.1875em 0.6875em 0 -0.6875em $stroke-color,
2.0625em 0.9375em 0 -0.9375em $stroke-color,
0 0 0 0.375em $stroke-color,
-2.1875em 0.6875em 0 -0.3125em $stroke-color,
2.0625em 0.9375em 0 -0.5625em $stroke-color;
opacity: 0.3;
transform: scale(0.5) translate(6em, -3em);
animation: cloud 4s linear infinite;
&:after { background: $stroke-color; }
}
&.grey {
background: lighten($stroke-color, 70%);
box-shadow:
-2.1875em 0.6875em 0 -0.6875em lighten($stroke-color, 70%),
2.0625em 0.9375em 0 -0.9375em lighten($stroke-color, 70%),
0 0 0 0.375em lighten($stroke-color, 70%),
-2.1875em 0.6875em 0 -0.3125em lighten($stroke-color, 70%),
2.0625em 0.9375em 0 -0.5625em lighten($stroke-color, 70%);
&:after {
background: lighten($stroke-color, 70%);
box-shadow: 0 0.4375em 0 -0.0625em lighten($stroke-color, 70%);
}
}
}
.sun {
position: absolute;
top: 50%;
left: 50%;
width: 2.5em;
height: 2.5em;
margin: -1.25em;
background: $bg-color;
border-radius: 50%;
box-shadow: 0 0 0 0.375em $stroke-color;
animation: spin 12s infinite linear;
}
.rays {
position: absolute;
top: -2em;
left: 50%;
display: block;
width: 0.375em;
height: 1.125em;
margin-left: -0.1875em;
background: $stroke-color;
border-radius: 0.25em;
box-shadow: 0 5.375em $stroke-color;
}
.rays:before,
.rays:after {
content: '';
position: absolute;
top: 0em;
left: 0em;
display: block;
width: 0.375em;
height: 1.125em;
transform: rotate(60deg);
transform-origin: 50% 3.25em;
background: $stroke-color;
border-radius: 0.25em;
box-shadow: 0 5.375em $stroke-color;
}
.rays:before {
transform: rotate(120deg);
}
.cloud + .sun {
margin: -2em 1em;
}
.rain,
.lightning,
.snow {
position: absolute;
z-index: 2;
top: 50%;
left: 50%;
width: 3.75em;
height: 3.75em;
margin: 0.375em 0 0 -2em;
background: $bg-color;
}
.rain:after {
content: '';
position: absolute;
z-index: 2;
top: 50%;
left: 50%;
width: 1.125em;
height: 1.125em;
margin: -1em 0 0 -0.25em;
background: $accent-color;
border-radius: 100% 0 60% 50% / 60% 0 100% 50%;
box-shadow:
0.625em 0.875em 0 -0.125em rgba($stroke-color,0.2),
-0.875em 1.125em 0 -0.125em rgba($stroke-color,0.2),
-1.375em -0.125em 0 rgba($stroke-color,0.2);
transform: rotate(-28deg);
animation: rain 3s linear infinite;
}
.bolt {
position: absolute;
top: 50%;
left: 50%;
margin: -0.25em 0 0 -0.125em;
color: $stroke-color;
opacity: 0.3;
animation: lightning 2s linear infinite;
}
.bolt:nth-child(2) {
width: 0.5em;
height: 0.25em;
margin: -1.75em 0 0 -1.875em;
transform: translate(2.5em, 2.25em);
opacity: 0.2;
animation: lightning 1.5s linear infinite;
}
.bolt:before,
.bolt:after {
content: '';
position: absolute;
z-index: 2;
top: 50%;
left: 50%;
margin: -1.625em 0 0 -1.0125em;
border-top: 1.25em solid transparent;
border-right: 0.75em solid;
border-bottom: 0.75em solid;
border-left: 0.5em solid transparent;
transform: skewX(-10deg);
}
.bolt:after {
margin: -0.25em 0 0 -0.25em;
border-top: 0.75em solid;
border-right: 0.5em solid transparent;
border-bottom: 1.25em solid transparent;
border-left: 0.75em solid;
transform: skewX(-10deg);
}
.bolt:nth-child(2):before {
margin: -0.75em 0 0 -0.5em;
border-top: 0.625em solid transparent;
border-right: 0.375em solid;
border-bottom: 0.375em solid;
border-left: 0.25em solid transparent;
}
.bolt:nth-child(2):after {
margin: -0.125em 0 0 -0.125em;
border-top: 0.375em solid;
border-right: 0.25em solid transparent;
border-bottom: 0.625em solid transparent;
border-left: 0.375em solid;
}
.flake:before,
.flake:after {
content: '\2744';
position: absolute;
top: 50%;
left: 50%;
margin: -1.025em 0 0 -1.0125em;
color: $stroke-color;
list-height: 1em;
opacity: 0.2;
animation: spin 8s linear infinite reverse;
}
.flake:after {
margin: 0.125em 0 0 -1em;
font-size: 1.5em;
opacity: 0.4;
animation: spin 14s linear infinite;
}
.flake:nth-child(2):before {
margin: -0.5em 0 0 0.25em;
font-size: 1.25em;
opacity: 0.2;
animation: spin 10s linear infinite;
}
.flake:nth-child(2):after {
margin: 0.375em 0 0 0.125em;
font-size: 2em;
opacity: 0.4;
animation: spin 16s linear infinite reverse;
}
/* Animations */
@keyframes spin {
100% { transform: rotate(360deg); }
}
@keyframes cloud {
0% { opacity: 0; }
50% { opacity: 0.3; }
100% {
opacity: 0;
transform: scale(0.5) translate(-200%, -3em);
}
}
@keyframes rain {
0% {
background: $accent-color;
box-shadow:
0.625em 0.875em 0 -0.125em rgba($stroke-color,0.2),
-0.875em 1.125em 0 -0.125em rgba($stroke-color,0.2),
-1.375em -0.125em 0 $accent-color;
}
25% {
box-shadow:
0.625em 0.875em 0 -0.125em rgba($stroke-color,0.2),
-0.875em 1.125em 0 -0.125em $accent-color,
-1.375em -0.125em 0 rgba($stroke-color,0.2);
}
50% {
background: rgba($stroke-color,0.3);
box-shadow:
0.625em 0.875em 0 -0.125em $accent-color,
-0.875em 1.125em 0 -0.125em rgba($stroke-color,0.2),
-1.375em -0.125em 0 rgba($stroke-color,0.2);
}
100% {
box-shadow:
0.625em 0.875em 0 -0.125em rgba($stroke-color,0.2),
-0.875em 1.125em 0 -0.125em rgba($stroke-color,0.2),
-1.375em -0.125em 0 $accent-color;
}
}
@keyframes lightning {
45% {
color: $stroke-color;
background: $stroke-color;
opacity: 0.2;
}
50% {
color: $accent-color;
background: $accent-color;
opacity: 1;
}
55% {
color: $stroke-color;
background: $stroke-color;
opacity: 0.2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment