Created
May 20, 2011 08:58
-
-
Save por/982591 to your computer and use it in GitHub Desktop.
This file contains 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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | |
<meta http-equiv="refresh" content="3600" /> | |
<title>Scrobble Map</title> | |
<link rel="stylesheet" href="scrobblemap.css" type="text/css" media="screen" title="no title" charset="utf-8"> | |
</head> | |
<body> | |
<div id="map3d"></div> | |
<script src="http://cdn.last.fm/prototyping/scrobblemap/mootools-1.2.4-core.js"></script> | |
<script src="http://cdn.last.fm/prototyping/scrobblemap/mootools-1.2.4.4-more.js"></script> | |
<script src="http://www.google.com/jsapi?key=ABQIAAAAef4neLxKbGqqMWYSo_SV8BTm1w6-I7rkOK_FGHRvVLZcy0O7EhQeEyUSqJjgTzCZH93mE14rYLfiuQ"></script> | |
<script src="scrobblemap3D.js"></script> | |
<script> | |
// Simple transition | |
/* | |
var map = new ScrobbleMap3D("map3d"); | |
map.addEvent('onViewChangeBegin', map.hideBalloon.bind(map)); | |
map.addEvent('onViewChangeEnd', map.showBalloon.bind(map)); | |
map.addEvent('onShowScrobble', function(scrobble) { | |
this.setPoint(scrobble); | |
}.bind(map)); | |
map.addEvent('onSetPoint', function() { | |
this.getView(this.options.defaultView); | |
}.bind(map)); | |
map.start(); | |
*/ | |
// Complex transition | |
var map = new ScrobbleMap3D("map3d", { | |
showStatusBar: false, | |
scrobbleInterval: 10000, | |
waitUntilLoaded: true | |
}); | |
var views = [ | |
{ altitude: 0, heading: -65, tilt: 65, range: 1500 }, | |
{ altitude: 0, heading: 115, tilt: 70, range: 2800 }, | |
{ altitude: 0, heading: 45, tilt: 60, range: 2000 }, | |
{ altitude: 0, heading: -95, tilt: 65, range: 2500 } | |
]; | |
map.addEvent('onShowScrobble', function(scrobble) { | |
this.setPoint(scrobble); | |
}.bind(map)); | |
map.addEvent('onSetPoint', function() { | |
this.addEvent('onViewChangeBegin', function() { | |
this.removeEvents('onViewChangeBegin'); | |
this.hideBalloon(); | |
}); | |
this.addEvent('onViewChangeEnd', function() { | |
this.removeEvents('onViewChangeEnd'); | |
this.addEvent('onViewChangeEnd', function() { | |
this.removeEvents('onViewChangeEnd'); | |
this.showBalloon(); | |
}); | |
var rand = $random(0, views.length-1); | |
var view = views[rand]; | |
this.getView(view); | |
}); | |
this.getView({ | |
altitude: 0, | |
heading: 0, | |
tilt: 0, | |
range: 5000000 | |
}); | |
}.bind(map)); | |
map.start(); | |
</script> | |
</body> |
This file contains 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
[{"user":"mrspeppa","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/63086423.jpg","track":{"artist":"Michael Jackson","name":"They Don't Care About Us"},"location":{"city":"Police","countrycode":"PL","latitude":53.5499992371,"longitude":14.5666999817},"timestamp":"1305882819"},{"user":"kitsune_arisa","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/61490441.jpg","track":{"artist":"In Flames","name":"Leeches"},"location":{"city":"Tomsk","countrycode":"RU","latitude":56.5,"longitude":84.9666976929},"timestamp":"1305883132"},{"user":"xtran","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/4471011.jpg","track":{"artist":"Action Biker","name":"Dance To Keep From Crying"},"location":{"city":"Kista","countrycode":"SE","latitude":59.4500007629,"longitude":17.9167003632},"timestamp":"1305883058"},{"user":"henrynavarre","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/62700273.jpg","track":{"artist":"The Pillows","name":"Hybrid Rainbow"},"location":{"city":"Chaska","countrycode":"US","latitude":44.8054008484,"longitude":-93.6248016357},"timestamp":"1305883074"},{"user":"mykkyr","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/52491325.jpg","track":{"artist":"Grant Hart","name":"You're the Reflection of the Moon on the Water"},"location":{"city":"","countrycode":"FI","latitude":64,"longitude":26},"timestamp":"1305882869"},{"user":"Amazon1969","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/6654115.jpg","track":{"artist":"The Bar-Kays","name":"Humpin'"},"location":{"city":"Utrecht","countrycode":"NL","latitude":52.0833015442,"longitude":5.13329982758},"timestamp":"1305882898"},{"user":"Gatsby0202","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/44332461.jpg","track":{"artist":"Fink","name":"Move On Me"},"location":{"city":"Oxford","countrycode":"GB","latitude":51.75,"longitude":-1.25},"timestamp":"1305882989"},{"user":"xJonnyx","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/45523249.jpg","track":{"artist":"Bon Iver","name":"Hinnom, TX"},"location":{"city":"Manchester","countrycode":"GB","latitude":53.5,"longitude":-2.21670007706},"timestamp":"1305883125"},{"user":"Candlelight89","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/62865905.gif","track":{"artist":"Malcolm Lincoln","name":"Uu Monica"},"location":{"city":"Pobiedziska","countrycode":"PL","latitude":52.4667015076,"longitude":17.2999992371},"timestamp":"1305882869"},{"user":"bluekey","image":"http:\/\/userserve-ak.last.fm\/serve\/126s\/723289.jpg","track":{"artist":"Cold War Kids","name":"Out Of The Wilderness"},"location":{"city":"Vancouver","countrycode":"CA","latitude":49.25,"longitude":-123.133300781},"timestamp":"1305882837"}] |
This file contains 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
html, body { | |
margin: 0; | |
padding: 0; | |
height: 100%; | |
width: 100%; | |
overflow: hidden; | |
background-color: transparent; | |
} | |
body { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
font-size: 18px; | |
line-height: 24px; | |
} | |
p, h2 { | |
margin: 0; | |
padding: 0; | |
} | |
#map3d { | |
background-color: transparent; | |
height: 100%; | |
width: 100%; | |
} | |
#mapOverlay { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
} | |
.scrobbleballoon { | |
padding: 10px 10px 10px 166px; | |
color: #111; | |
text-shadow: 0 1px 0 #fff; | |
} | |
.scrobbleballoon .user-image { | |
margin: 0 0 10px -156px; | |
display: inline; | |
float: left; | |
border: 5px solid white; | |
-webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2); | |
} | |
.scrobbleballoon .title { | |
font-size: 30px; | |
margin-bottom: 0.5em; | |
display: block; | |
} | |
.trackname, | |
.artistname { | |
font-weight: bold; | |
} | |
.location { | |
color: #666; | |
} | |
#scrobbleCounter { | |
color: #eee; | |
float: right; | |
position: absolute; | |
font-size: 40px; | |
color: #eee; | |
} |
This file contains 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
/** | |
* Scrobble Map 3D | |
* @author Tim ([email protected]) | |
* @version 0.1 | |
* | |
* Requires: | |
* <script type="text/javascript" src="http://cdn.last.fm/prototyping/scrobblemap/mootools-1.2.4-core.js"></script> | |
* <script type="text/javascript" src="http://cdn.last.fm/prototyping/scrobblemap/mootools-1.2.4.4-more.js"></script> | |
* <script src="http://www.google.com/jsapi?key=ABQIAAAAef4neLxKbGqqMWYSo_SV8BTm1w6-I7rkOK_FGHRvVLZcy0O7EhQeEyUSqJjgTzCZH93mE14rYLfiuQ"></script> | |
*/ | |
var ScrobbleMap3D = new Class({ | |
Implements: [Options, Events], | |
ge: null, | |
placemark: null, | |
la: null, | |
balloon: null, | |
scrobbleInterval: null, | |
scrobbleQueue: [], | |
settings: { | |
scrobbleStream: 'sample_data.json', | |
placemarkIcon: 'http://static.last.fm/prototyping/scrobblemap/scrobblepin.png', | |
logo: { | |
href: 'http://static.last.fm/prototyping/scrobblemap/lastfm-logo-white.png', | |
width: 100, | |
height: 30 | |
}, | |
balloon: { | |
maxWidth: 500, | |
minWidth: 500, | |
backgroundColor: '#eeeeee', | |
closeButtonEnabled: false | |
} | |
}, | |
options: { | |
language: "en-GB", | |
layers: [ | |
// "LAYER_BORDERS", | |
"LAYER_TERRAIN", | |
"LAYER_BUILDINGS" | |
], | |
showNavigation: false, | |
showStatusBar: false, | |
showOverviewMap: false, | |
showScaleLegend: false, | |
showAtmosphere: true, | |
showSun: false, | |
flyToSpeed: 1, | |
scrobbleInterval: 10000, // ms | |
defaultView: { | |
altitude: 0, | |
heading: 0, | |
tilt: 45, | |
range: 1000000 | |
}, | |
waitUntilLoaded: false | |
}, | |
initialize: function(container, options) { | |
// Set container | |
this.container = container; | |
// Set options | |
this.setOptions(options); | |
// Initialize Google Earth API | |
google.load("earth", "1"); | |
google.setOnLoadCallback(this.init.bind(this)); | |
}, | |
init: function() { | |
// Create Google Earth instance | |
google.earth.createInstance(this.container, this.initCB.bind(this), this.failCB.bind(this)); | |
}, | |
initCB: function(instance) { | |
this.ge = instance; | |
this.ge.getWindow().setVisibility(true); | |
// Initialize layers | |
this.options.layers.each(function(item, index){ | |
var layer = eval("this.ge." + item); | |
this.ge.getLayerRoot().enableLayerById(layer, true); | |
}, this); | |
// Options | |
this.ge.getNavigationControl().setVisibility(this.options.showNavigation); // Navigation | |
this.ge.getOptions().setStatusBarVisibility(this.options.showStatusBar); // Status bar | |
this.ge.getOptions().setOverviewMapVisibility(this.options.showOverviewMap); // Overview map | |
this.ge.getOptions().setScaleLegendVisibility(this.options.showScaleLegend); // Scale legend | |
this.ge.getOptions().setAtmosphereVisibility(this.options.showAtmosphere); // Atmosphere | |
this.ge.getSun().setVisibility(this.options.showSun); // Sun | |
// Fly to speed | |
this.ge.getOptions().setFlyToSpeed(this.options.flyToSpeed); | |
// Create logo overlay | |
this.createLogoOverlay(); | |
// Initialize placemark | |
this.createPlacemark(); | |
// Initialize camera | |
this.la = this.ge.createLookAt(''); | |
// Create balloon | |
this.createBalloon(); | |
// Load scrobblestream | |
this.getMoreScrobbles(); | |
// Add listeners | |
google.earth.addEventListener(this.ge.getView(), 'viewchangebegin', this.viewChangeBeginHandler.bind(this)); | |
google.earth.addEventListener(this.ge.getView(), 'viewchangeend', this.viewChangeEndHandler.bind(this)); | |
}, | |
failCB: function() { | |
console.log('FAIL'); | |
}, | |
createLogoOverlay: function() { | |
// Create the ScreenOverlay | |
var screenOverlay = this.ge.createScreenOverlay(''); | |
// Specify a path to the image and set as the icon | |
var icon = this.ge.createIcon(''); | |
icon.setHref(this.settings.logo.href); | |
screenOverlay.setIcon(icon); | |
// Set the ScreenOverlay’s position in the window | |
screenOverlay.getOverlayXY().setXUnits(this.ge.UNITS_PIXELS); | |
screenOverlay.getOverlayXY().setYUnits(this.ge.UNITS_PIXELS); | |
screenOverlay.getOverlayXY().setX(this.settings.logo.width/2+10); | |
screenOverlay.getOverlayXY().setY(this.settings.logo.height/2+10); | |
// Set the overlay’s size in pixels | |
screenOverlay.getSize().setXUnits(this.ge.UNITS_PIXELS); | |
screenOverlay.getSize().setYUnits(this.ge.UNITS_PIXELS); | |
screenOverlay.getSize().setX(this.settings.logo.width); | |
screenOverlay.getSize().setY(this.settings.logo.height); | |
// Add the ScreenOverlay to Earth | |
this.ge.getFeatures().appendChild(screenOverlay); | |
}, | |
createPlacemark: function() { | |
// Initialize placemark | |
this.placemark = this.ge.createPlacemark(''); | |
// Create a style map. | |
var styleMap = this.ge.createStyleMap(''); | |
// Create normal style for style map. | |
var normalStyle = this.ge.createStyle(''); | |
var normalIcon = this.ge.createIcon(''); | |
normalIcon.setHref(this.settings.placemarkIcon); | |
normalStyle.getIconStyle().setIcon(normalIcon); | |
normalStyle.getIconStyle().setScale(2.0); | |
styleMap.setNormalStyle(normalStyle); | |
// Apply stylemap to placemark. | |
this.placemark.setStyleSelector(styleMap); | |
// Add the placemark to Earth | |
this.ge.getFeatures().appendChild(this.placemark); | |
}, | |
createBalloon: function() { | |
this.balloon = this.ge.createHtmlStringBalloon(''); | |
this.balloon.setMinWidth(this.settings.balloon.minWidth); | |
this.balloon.setMaxWidth(this.settings.balloon.maxWidth); | |
this.balloon.setCloseButtonEnabled(this.settings.balloon.closeButtonEnabled); | |
this.balloon.setBackgroundColor(this.settings.balloon.backgroundColor); | |
}, | |
showScrobble: function() { | |
// retrieve more scrobbles if the queue is empty or down to the last few | |
if (this.scrobbleQueue.length == 0 || this.scrobbleQueue.length == 2) { | |
this.getMoreScrobbles(); | |
} | |
if (this.scrobbleQueue.length == 0) { | |
return; | |
} | |
// Be nice and only start when everything has finished loading | |
if (this.options.waitUntilLoaded) { | |
if(this.isLoading()) { | |
console.log('loading...'); | |
this.stop(); | |
this.start.delay(1000, this); | |
return; | |
} | |
} | |
scrobble = this.scrobbleQueue.shift(); | |
this.fireEvent('onShowScrobble', [scrobble]); | |
}, | |
getMoreScrobbles: function() { | |
new Request.JSON({ | |
url: this.settings.scrobbleStream, | |
onComplete: this.getMoreScrobblesCallback.bind(this) | |
}).send(); | |
}, | |
getMoreScrobblesCallback: function(obj) { | |
// wipe out any cached scrobbles | |
this.scrobbleQueue = []; | |
// just take the first 10 or we’ll be too out of date | |
for (var i = 0, ilen = 10; i < ilen; i++) { | |
this.scrobbleQueue.push(obj[i]); | |
} | |
}, | |
setPoint: function(scrobble) { | |
var user = scrobble.user; | |
var image = scrobble.image; | |
var trackname = scrobble.track.name; | |
var artistname = scrobble.track.artist; | |
var cityname = scrobble.location.city; | |
var countrycode = scrobble.location.countrycode; | |
var html = '<div class="scrobbleballoon"><img src="'+ image +'" height="126" width="126" alt="' + user + '" class="user-image" /><h2 class="title">'+ user +'</h2><p class="listeningto"><span class="artistname">' + artistname + '</span> – <span class="trackname">' + trackname + '</span></p><p class="location">Scrobbling now in ' + cityname + ' (' + countrycode + ')' + '</p></div>'; | |
// this.placemark.setName(user); | |
// this.placemark.setDescription(html); | |
this.balloon.setContentString(html); | |
this.balloon.setFeature(this.placemark); | |
var latitude = scrobble.location.latitude; | |
var longitude = scrobble.location.longitude | |
// Set the placemark’s location | |
var point = this.ge.createPoint(''); | |
point.setLatitude(latitude); | |
point.setLongitude(longitude); | |
this.placemark.setGeometry(point); | |
this.fireEvent('onSetPoint'); | |
}, | |
getView: function(view) { | |
var point = this.placemark.getGeometry(); | |
var latitude = point.getLatitude(); | |
var longitude = point.getLongitude(); | |
this.la.set( | |
latitude, | |
longitude, | |
view.altitude, | |
this.ge.ALTITUDE_RELATIVE_TO_GROUND, | |
view.heading, | |
view.tilt, | |
view.range | |
); | |
this.ge.getView().setAbstractView(this.la); | |
}, | |
start: function() { | |
this.showScrobble(); | |
$clear(this.scrobbleInterval); // just in case | |
this.scrobbleInterval = this.showScrobble.periodical(this.options.scrobbleInterval, this); | |
}, | |
stop: function() { | |
$clear(this.scrobbleInterval); | |
}, | |
hideBalloon: function() { | |
thisge.setBalloon(null); | |
}, | |
showBalloon: function() { | |
if(this.balloon.getContentString() != ''){ | |
this.ge.setBalloon(this.balloon); | |
} | |
}, | |
viewChangeBeginHandler: function() { | |
this.fireEvent('onViewChangeBegin'); | |
}, | |
viewChangeEndHandler: function() { | |
this.fireEvent('onViewChangeEnd'); | |
}, | |
getStreamingPercent: function() { | |
return this.ge.getStreamingPercent(); | |
}, | |
isLoading: function() { | |
var pct = map.getStreamingPercent(); | |
return (pct < 100); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment