A Pen by Michael Berry on CodePen.
Last active
August 12, 2016 21:56
-
-
Save michaeljberry/b04edbe80c311a1619c51641b942232d to your computer and use it in GitHub Desktop.
LocalWeather
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- 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>°</div> | |
| <button id="fahrenheit" disabled>°F</button> | <button id="celsius">°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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $(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(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @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; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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