Skip to content

Instantly share code, notes, and snippets.

@adamabernathy
Last active June 27, 2017 16:34
Show Gist options
  • Save adamabernathy/4f869da2251eaf92c49a1667d2b75ab3 to your computer and use it in GitHub Desktop.
Save adamabernathy/4f869da2251eaf92c49a1667d2b75ab3 to your computer and use it in GitHub Desktop.
Scrolling Weather Ticker
<html>
<head>
<title>Scrolling Weather Ticker</title>
<style>
@-webkit-keyframes ticker {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
@keyframes ticker {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
/* Ticker container */
.ticker-wrapper {
position: fixed;
width: 100%;
overflow: hidden;
height: 4rem;
background-color: rgba(40, 44, 52, 0.9);
padding-left: 100%;
padding-bottom: 1em;
}
/* Ticker item list container */
.ticker {
display: inline-block;
height: 4em;
line-height: 4em;
white-space: nowrap;
padding-right: 100%;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-name: ticker;
animation-name: ticker;
-webkit-animation-duration: 30s;
animation-duration: 30s;
}
/* Ticker items */
.ticker-item {
display: inline-block;
padding: 0 2rem;
font-size: 2rem;
color: rgba(129, 195, 118, 1);
}
</style>
</head>
<body>
<h1>Simple weather ticker</h1>
<p>This application demonstrates how to use the SynopticLabs Latest API with modern ES6 JavaScript.</p>
<div id="app-container" class="ticker-wrapper">
<!-- Don't put anything here -->
</div>
</body>
<!-- Include the fetch() polyfill just in case legacy browsers are in play -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.min.js"></script>
<script>
(function () {
'use strict';
// While this script uses ES6 syntax and tricks, you can easily convert it to ES5 for
// compatability if needed with Babel at https://babeljs.io/ .
let state = { // Application state controller.
haveData: false,
api: {
apiBaseURL: 'https://api.mesowest.net/v2/',
service: 'stations/latest',
// Any valid SL Latest API argument can be used here. For this case we are
// just using three weather stations. You could use 'network' instead to see
// a group of stations; i.e. instead of 'stid' use 'network=153'
parameters: { token: 'dev', stid: 'wbb,hol,kslc', units: 'english' },
requestURL: ''
},
tickerRefreshInterval: 60000 // in milliseconds so 1 sec = 1000ms.
};
// Application storage container.
let store = {};
worker(state.api.service, state.api.parameters);
setInterval(() => {
removeElementById('__scroll-items');
worker(state.api.service, state.api.parameters);
}, state.tickerRefreshInterval);
/**
* Main worker function. Requests data from webservice then controls the application update.
* @param {string} baseURL - Base URL of web service to use, assumes SL Mesonet Webservices.
* @param {object} apiParameters - Any valid parameter for the specified SL Mesonet Webservice.
*/
function worker(baseURL, apiParameters) {
// Fetch data from the Mesonet API.
getData(baseURL, apiParameters)
.then((data) => {
// If successful then create the list items to append to the 'ticker'
// console.log(data)
addEntryToMarquee(data);
}).catch((error) => {
console.error('Unexepected error has occured\n', error);
})
}
function addEntryToMarquee(data) {
let $container = document.getElementById('app-container');
let $scrollItems = document.createElement('DIV');
$scrollItems.classList.add('ticker');
$scrollItems.id = '__scroll-items';
data.STATION.map((k) => {
let $item = document.createElement('DIV');
$item.innerHTML = `${k.STID} Air Temp: ${k.OBSERVATIONS.air_temp_value_1.value} <sup>&deg;</sup>F`;
$item.classList.add('ticker-item');
$scrollItems.appendChild($item);
})
$container.appendChild($scrollItems);
}
function removeElementById(id) {
if (document.getElementById(id)) {
let el = document.getElementById(id);
return el.parentNode.removeChild(el);
} else {
return null;
}
}
function serializeURLArgs(obj) {
let str = ['?'];
for (let p in obj) {
if (obj.hasOwnProperty(p)) { str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p])); }
}
return str.join('&');
}
function getData(baseURL = '', args = {}) {
return new Promise((resolve, reject) => {
state.api.requestURL = state.api.apiBaseURL + baseURL + serializeURLArgs(args);
fetch(state.api.requestURL)
.then((response) => { return response.json(); })
.then((data) => {
store.data = data;
state.haveData = true;
resolve(data);
})
.catch((error) => reject(error));
});
}
}());
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment