Skip to content

Instantly share code, notes, and snippets.

@michaeljberry
Last active August 12, 2016 21:56
Show Gist options
  • Select an option

  • Save michaeljberry/b04edbe80c311a1619c51641b942232d to your computer and use it in GitHub Desktop.

Select an option

Save michaeljberry/b04edbe80c311a1619c51641b942232d to your computer and use it in GitHub Desktop.
LocalWeather
<!-- Credit for 3D clouds:
https://www.clicktorelease.com/blog/how-to-make-clouds-with-css-3d
-->
<div id="viewport">
<div id="world">
</div>
</div>
<div id="content">
<div>
<div id="city">City</div>
<div id="currentTime">CurrentTime</div>
<div id="today">Today</div>
<div id="weekday">Weekday</div>
<div id="humidity">Humidity</div>
<div id="pressure">Pressure</div>
<div id="temperature">Temperature</div><div>&deg;</div>
<button id="fahrenheit" disabled>&deg;F</button> | <button id="celsius">&deg;C</button>
<div id="sunrise">Sunrise</div>
<div id="sunset">Sunset</div>
<div id="windSpeed">WindSpeed</div>
<div id="windDirection">WindDirection</div>
</div>
<!--<button id="getWeather">Get Weather</button>-->
<i class="wi" id="icon"></i>
</div>
$(document).ready(function(){
//$('#getWeather').on('click', function(){
if(navigator.geolocation){
var url = 'http://api.openweathermap.org/data/2.5/weather';
var lat = '';
var long = '';
navigator.geolocation.getCurrentPosition(function(position){
lat = position.coords.latitude;
long = position.coords.longitude;
url += '?lat=' + lat + '&lon=' + long + '&APPID=' + api;
$.ajax({
type: "GET",
url: url,
dataType: "json",
success: function(results){
var weather = results;
var id = weather.weather[0].id;
var city = weather.name;
$('#city').text(city);
var sunrise = weather.sys.sunrise;
var sunriseTime = new Date(unixToSeconds(sunrise));
sunriseTime = addZero(sunriseTime.getHours())
+ ':' + addZero(sunriseTime.getMinutes())
+ ':' + addZero(sunriseTime.getSeconds());
$('#sunrise').text(sunriseTime);
var sunset = weather.sys.sunset;
var sunsetTime = new Date(unixToSeconds(sunset));
sunsetTime = addZero(sunsetTime.getHours())
+ ':' + addZero(sunsetTime.getMinutes())
+ ':' + addZero(sunsetTime.getSeconds());
$('#sunset').text(sunsetTime);
var current = weather.dt;
var currentTime = new Date(unixToSeconds(current));
var time = addZero(currentTime.getHours())
+ ':' + addZero(currentTime.getMinutes())
+ ':' + addZero(currentTime.getSeconds());
$('#currentTime').text(time);
var today = (currentTime.getMonth()+1) + '/' + currentTime.getDate() + '/' + currentTime.getFullYear();
$('#today').text(today);
var weekday = weekdays[currentTime.getDay()];
$('#weekday').text(weekday);
var timeOfDay = nightOrDay(current, sunrise, sunset);
var icon = whichIcon(id, timeOfDay, weatherIconMap);
$('#icon').addClass('wi-' + icon);
var humidity = weather.main.humidity;
$('#humidity').text(humidity + '%');
var pressure = weather.main.pressure;
$('#pressure').text(pressure + '');
var temperature = weather.main.temp;
var tempC = kToC(temperature);
var tempF = cToF(tempC);
$('#temperature').text(tempF);
var description = weather.weather[0].description;
var windSpeed = weather.wind.speed;
$('#windSpeed').text(windSpeed);
var windDirection = degreeToDirection(weather.wind.deg);
$('#windDirection').text(windDirection);
var cloudiness = weather.clouds.all;
},
error: function(XMLHttpRequest, status, errorThrown){
console.log(errorThrown);
alert('Error');
}
});
});
}
//});
$('#fahrenheit').on('click', function(e){
var temp = parseInt($('#temperature').text());
if($('#fahrenheit').is(':disabled')){
alert('The temperature is already in Fahrenheit.');
}else{
var newTemp = cToF(temp);
$('#temperature').text(newTemp);
$('#celsius').prop('disabled', false);
$('#fahrenheit').prop('disabled', true);
}
});
$('#celsius').on('click', function(e){
var temp = parseInt($('#temperature').text());
if($('#celsius').is(':disabled')){
alert('The temperature is already in Celsius.');
}else{
var newTemp = fToC(temp);
$('#temperature').text(newTemp);
$('#fahrenheit').prop('disabled', false);
$('#celsius').prop('disabled', true);
}
});
});
function whichIcon(id, timeOfDay, weatherIconMap){
var test = timeOfDay + '-' + id;
return weatherIconMap.hasOwnProperty(test) ? weatherIconMap[test] : weatherIconMap[id];
}
function nightOrDay(currentTime, sunrise, sunset){
return (currentTime < sunset && currentTime > sunrise) ? 'day' : 'night';
}
function kToC(k){
return Math.round(k - 273.15);
}
function fToC(f){
return Math.round((f - 32) * 5/9);
}
function cToF(c){
return Math.round((c * 9/5) + 32);
}
function addZero(value){
return value < 10 ? '0'+ value : value;
}
function unixToSeconds(value){
return value * 1000;
}
function degreeToDirection(d){
var deg = parseInt((d/22.5)+.5);
var dirArray = ["N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"];
return dirArray[(deg % 16)];
}
var api = "e02952dced6b53bb8c1d1a60b4f014e6";
var weekdays = {
'0': 'Sunday',
'1': 'Monday',
'2': 'Tuesday',
'3': 'Wednesday',
'4': 'Thursday',
'5': 'Friday',
'6': 'Saturday'
};
var weatherIconMap = {
"200": "thunderstorm",
"201": "thunderstorm",
"202": "thunderstorm",
"210": "lightning",
"211": "lightning",
"212": "lightning",
"221": "lightning",
"230": "thunderstorm",
"231": "thunderstorm",
"232": "thunderstorm",
"300": "sprinkle",
"301": "sprinkle",
"302": "rain",
"310": "rain-mix",
"311": "rain",
"312": "rain",
"313": "showers",
"314": "rain",
"321": "sprinkle",
"500": "sprinkle",
"501": "rain",
"502": "rain",
"503": "rain",
"504": "rain",
"511": "rain-mix",
"520": "showers",
"521": "showers",
"522": "showers",
"531": "storm-showers",
"600": "snow",
"601": "snow",
"602": "sleet",
"611": "rain-mix",
"612": "rain-mix",
"615": "rain-mix",
"616": "rain-mix",
"620": "rain-mix",
"621": "snow",
"622": "snow",
"701": "showers",
"711": "smoke",
"721": "day-haze",
"731": "dust",
"741": "fog",
"761": "dust",
"762": "dust",
"771": "cloudy-gusts",
"781": "tornado",
"800": "day-sunny",
"801": "cloudy-gusts",
"802": "cloudy-gusts",
"803": "cloudy-gusts",
"804": "cloudy",
"900": "tornado",
"901": "storm-showers",
"902": "hurricane",
"903": "snowflake-cold",
"904": "hot",
"905": "windy",
"906": "hail",
"957": "strong-wind",
"day-200": "day-thunderstorm",
"day-201": "day-thunderstorm",
"day-202": "day-thunderstorm",
"day-210": "day-lightning",
"day-211": "day-lightning",
"day-212": "day-lightning",
"day-221": "day-lightning",
"day-230": "day-thunderstorm",
"day-231": "day-thunderstorm",
"day-232": "day-thunderstorm",
"day-300": "day-sprinkle",
"day-301": "day-sprinkle",
"day-302": "day-rain",
"day-310": "day-rain",
"day-311": "day-rain",
"day-312": "day-rain",
"day-313": "day-rain",
"day-314": "day-rain",
"day-321": "day-sprinkle",
"day-500": "day-sprinkle",
"day-501": "day-rain",
"day-502": "day-rain",
"day-503": "day-rain",
"day-504": "day-rain",
"day-511": "day-rain-mix",
"day-520": "day-showers",
"day-521": "day-showers",
"day-522": "day-showers",
"day-531": "day-storm-showers",
"day-600": "day-snow",
"day-601": "day-sleet",
"day-602": "day-snow",
"day-611": "day-rain-mix",
"day-612": "day-rain-mix",
"day-615": "day-rain-mix",
"day-616": "day-rain-mix",
"day-620": "day-rain-mix",
"day-621": "day-snow",
"day-622": "day-snow",
"day-701": "day-showers",
"day-711": "smoke",
"day-721": "day-haze",
"day-731": "dust",
"day-741": "day-fog",
"day-761": "dust",
"day-762": "dust",
"day-781": "tornado",
"day-800": "day-sunny",
"day-801": "day-cloudy-gusts",
"day-802": "day-cloudy-gusts",
"day-803": "day-cloudy-gusts",
"day-804": "day-sunny-overcast",
"day-900": "tornado",
"day-902": "hurricane",
"day-903": "snowflake-cold",
"day-904": "hot",
"day-906": "day-hail",
"day-957": "strong-wind",
"night-200": "night-alt-thunderstorm",
"night-201": "night-alt-thunderstorm",
"night-202": "night-alt-thunderstorm",
"night-210": "night-alt-lightning",
"night-211": "night-alt-lightning",
"night-212": "night-alt-lightning",
"night-221": "night-alt-lightning",
"night-230": "night-alt-thunderstorm",
"night-231": "night-alt-thunderstorm",
"night-232": "night-alt-thunderstorm",
"night-300": "night-alt-sprinkle",
"night-301": "night-alt-sprinkle",
"night-302": "night-alt-rain",
"night-310": "night-alt-rain",
"night-311": "night-alt-rain",
"night-312": "night-alt-rain",
"night-313": "night-alt-rain",
"night-314": "night-alt-rain",
"night-321": "night-alt-sprinkle",
"night-500": "night-alt-sprinkle",
"night-501": "night-alt-rain",
"night-502": "night-alt-rain",
"night-503": "night-alt-rain",
"night-504": "night-alt-rain",
"night-511": "night-alt-rain-mix",
"night-520": "night-alt-showers",
"night-521": "night-alt-showers",
"night-522": "night-alt-showers",
"night-531": "night-alt-storm-showers",
"night-600": "night-alt-snow",
"night-601": "night-alt-sleet",
"night-602": "night-alt-snow",
"night-611": "night-alt-rain-mix",
"night-612": "night-alt-rain-mix",
"night-615": "night-alt-rain-mix",
"night-616": "night-alt-rain-mix",
"night-620": "night-alt-rain-mix",
"night-621": "night-alt-snow",
"night-622": "night-alt-snow",
"night-701": "night-alt-showers",
"night-711": "smoke",
"night-721": "day-haze",
"night-731": "dust",
"night-741": "night-fog",
"night-761": "dust",
"night-762": "dust",
"night-781": "tornado",
"night-800": "night-clear",
"night-801": "night-alt-cloudy-gusts",
"night-802": "night-alt-cloudy-gusts",
"night-803": "night-alt-cloudy-gusts",
"night-804": "night-alt-cloudy",
"night-900": "tornado",
"night-902": "hurricane",
"night-903": "snowflake-cold",
"night-904": "hot",
"night-906": "night-alt-hail",
"night-957": "strong-wind"
};
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelRequestAnimationFrame = window[vendors[x]+
'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}())
/*
Defining our variables
world and viewport are DOM elements,
worldXAngle and worldYAngle are floats that hold the world rotations,
d is an int that defines the distance of the world from the camera
*/
/*
objects is an array of cloud bases
layers is an array of cloud layers
*/
var objects = [],
layers = [],
//textures = [],
world = document.getElementById('world'),
viewport = document.getElementById('viewport'),
d = 0,
p = 400,
worldXAngle = 0,
worldYAngle = 0;
viewport.style.webkitPerspective = p;
viewport.style.MozPerspective = p;
viewport.style.oPerspective = p;
viewport.style.perspective = p;
generate();
/*
Creates a single cloud base: a div in world
that is translated randomly into world space.
Each axis goes from -256 to 256 pixels.
*/
function createCloud(){
var div = document.createElement('div');
div.className = 'cloudBase';
var x = 256 - (Math.random() * 512);
var y = 256 - (Math.random() * 512);
var z = 256 - (Math.random() * 512);
var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px )';
div.style.webkitTransform = t;
div.style.MozTransform = t;
div.style.OTransform= t;
div.style.transform = t;
world.appendChild(div);
for(var j= 0; j < 5 + Math.round(Math.random() * 10); j++){
var cloud = document.createElement('div');
//cloud.style.opacity = 0;
//var src = 'https://storage.googleapis.com/saperemarketing-michael/cloud.png';
//(function(img){img.addEventListener('load', function(){
// img.style.opacity = .8;
//})})(cloud);
//cloud.setAttribute('src', src);
cloud.className = 'cloudLayer';
var x = 256 - (Math.random() * 512);
var y = 256 - (Math.random() * 512);
var z = 100 - (Math.random() * 200);
var a = Math.random() * 360;
var s = .25 + Math.random();
x *= .2;
y *= 2;
cloud.data = {
x: x,
y: y,
z: z,
a: a,
s: s,
speed: .1 * Math.random()
};
var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px ) rotateZ( ' + a + 'deg ) scale( ' + s + ' ) ';
cloud.style.webkitTransform = t;
cloud.style.MozTransform = t;
cloud.style.OTransform = t;
cloud.style.transform = t;
div.appendChild(cloud);
layers.push(cloud);
}
return div;
}
/*
Event Listener to transform mouse position into angles
from -180 to 180 degrees, both vertically and horizontally
*/
window.addEventListener('mousewheel', onContainerMouseWheel);
window.addEventListener('DOMMouseScroll', onContainerMouseWheel);
window.addEventListener('mousemove', function(e){
worldYAngle = -(.5 - (e.clientX / window.innerWidth)) * 180;
worldXAngle = (.5 - (e.clientY / window.innerHeight)) * 180;
updateView();
});
/*
Clears the DOM of previous clouds bases
and generates a new set of cloud bases
*/
function generate(){
//objects = [];
if(world.hasChildNodes()){
while(world.childNodes.length >= 1){
world.removeChild(world.firstChild);
}
}
for(var j = 0; j < 5; j++){
objects.push(createCloud());
}
}
/*
Changes the transform property of world to be
translated in the Z axis by d pixels,
rotated in the X axis by worldXAngle degrees and
rotated in the Y axis by worldYAngle degrees.
*/
function updateView(){
var t = 'translateZ( ' + d + 'px ) rotateX( ' + worldXAngle + 'deg) rotateY( ' + worldYAngle + 'deg)';
world.style.webkitTransform = t;
world.style.MozTransform = t;
world.style.OTransform = t;
world.style.transform = t;
}
function onContainerMouseWheel(event){
event = event ? event : window.event;
d = d - (event.detail ? event.detail * -5 : event.wheelDelta / 8);
updateView();
}
/*
Iterate layers[], update the rotation and apply the inverse transformation currently applied to the world.
Notive the order in which rotations are applied
*/
function update(){
for(var j = 0; j < layers.length; j++){
var oppX = -window.worldXAngle;
var oppY = -window.worldYAngle;
var layer = layers[j];
layer.data.a += layer.data.speed;
var t = 'translateX(' + layer.data.x + 'px) translateY(' + layer.data.y + 'px) translateZ(' + layer.data.z + 'px) rotateY(' + oppY + 'deg) rotateX(' + oppX + 'deg) scale(' + layer.data.s + ')'; // rotateZ(' + layer.data.a + 'deg)
layer.style.webkitTransform = t;
layer.style.MozTransform = t;
layer.style.OTransform = t;
layer.style.transform = t;
}
requestAnimationFrame(update);
}
update();
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
@font-face{
font-family: 'weather';
src: url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/font/weathericons-regular-webfont.eot') format('embedded-opentype');
src: url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/font/weathericons-regular-webfont.svg') format('svg'),
url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/font/weathericons-regular-webfont.ttf') format('truetype'),
url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/font/weathericons-regular-webfont.woff') format('woff'),
url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/font/weathericons-regular-webfont.woff2');
}
body{
background: #222;
color: #fff;
}
#viewport{
bottom: 0;
left: 0;
overflow: hidden;
perspective: 400;
position: absolute;
right: 0;
top: 0;
}
#world{
background-color: rgba(255, 0, 0, 0.2);
height: 512px;
left: 50%;
margin-left: -256px;
margin-top: -256px;
position: absolute;
top: 50%;
transform-style: preserve-3d;
width: 512px;
}
.cloudBase{
background-color: rgba(255, 0, 255, 0.5);
height: 20px;
left: 256px;
margin-left: -10px;
margin-top: -10px;
position: absolute;
top: 256px;
width: 20px;
}
.cloudLayer{
background-color: rgba(0, 255, 255, 0.1);
height: 256px;
left: 50%;
margin-left: -128px;
margin-top: -128px;
position: absolute;
top: 50%;
width: 256px;
}
#content{
padding: 0 auto;
}
.weather{
font-family: weather;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment