mapsb/static/js/app.js

277 lines
7.9 KiB
JavaScript
Raw Normal View History

2016-01-26 08:53:03 +00:00
window.app = (function() {
var that = {},
coords,
map,
marker,
2016-01-26 10:20:40 +00:00
username = localStorage.username || 'Anonymous',
color = randomColor(),
userlist,
2016-01-26 08:53:03 +00:00
users = [],
zoomLevel = 23;
window.onload = setup();
document.body && window.onload();
function createUser(data) {
var user = {
id: data.id,
name: data.name,
2016-01-26 10:20:40 +00:00
color: data.color,
2016-01-26 08:53:03 +00:00
};
2016-01-26 10:20:40 +00:00
if (!user.color) {
user.color = [255, 0, 0];
}
2016-01-26 08:53:03 +00:00
users.push(user);
2016-01-26 10:20:40 +00:00
if(coords) {
update({
name: username,
color: color,
coords: coords
});
}
updateUserList();
2016-01-26 08:53:03 +00:00
return user;
}
function getUserById(id) {
return users.filter(function(user) {
return user.id == id;
})[0];
}
function initMap() {
2016-01-26 10:20:40 +00:00
navigator.geolocation.watchPosition(updateLocation, locationError, {
enableHighAccuracy: true
});
2016-01-26 08:53:03 +00:00
}
function joinRoom(room) {
if(that.room) {
post(['leave', that.room]);
}
users.forEach(function(user) {
if (user.marker) {
map.removeLayer(user.marker);
}
});
users = [];
that.room = room;
post(['join', that.room]);
if (coords) {
update({
name: username,
coords: coords
});
} else {
initMap();
}
2016-01-26 10:20:40 +00:00
updateUserList();
2016-01-26 08:53:03 +00:00
}
function locationError(err) {
console.log(err);
}
function post(data) {
that.ws.send(JSON.stringify(data));
}
function randomColor() {
2016-01-26 10:20:40 +00:00
var colors = [
[128, 0, 0],
[0, 128, 0],
[0, 0, 128],
[128, 128, 0],
[0, 128, 128],
[128, 0, 128],
[128, 64, 0],
[64, 128, 0],
[0, 128, 64],
[0, 64, 128],
[64, 0, 128],
[128, 0, 64]
];
return colors[Math.floor(Math.random() * 12)];
2016-01-26 08:53:03 +00:00
}
function randomName() {
var name = '';
while(name.length < 14) {
name += String.fromCharCode('A'.charCodeAt(0) + Math.floor(Math.random() * 25));
}
return name;
}
function removeUser(id) {
var user = getUserById(id);
if (user) {
if (user.marker) {
map.removeLayer(user.marker);
}
users = users.filter(function(user) {
user.id != id;
});
}
}
function setup() {
var host = (document.location.protocol == 'http:' ? 'ws' : 'wss') + '://' + document.location.host;
that.ws = new WebSocket(host + '/ws');
that.ws.onopen = function () {
window.onhashchange = function() {
var name = document.location.hash.slice(1);
if (name) {
document.title = '#' + name;
joinRoom(name);
} else {
document.location.href = '#' + randomName();
}
}
window.onhashchange();
};
that.ws.onmessage = function (event) {
var data = JSON.parse(event.data);
if (data[0] == 'leave') {
removeUser(data[1]);
} else if (data[0] == 'update') {
data[2].id = data[1];
2016-01-26 11:17:10 +00:00
updateUser(data[2]);
2016-01-26 08:53:03 +00:00
}
};
that.ws.onclose = function (event) {
setTimeout(function() {
setup();
}, 1000);
};
}
function update(data) {
post(['update', that.room, data]);
}
function updateLocation(loc) {
coords = [loc.coords.latitude, loc.coords.longitude];
var options = {
2016-01-26 10:20:40 +00:00
title: username,
icon: L.icon({
iconUrl: MarkerIcon({
label: username[0],
color: [255, 255, 255],
2016-01-26 10:25:19 +00:00
background: color
2016-01-26 10:20:40 +00:00
})
})
2016-01-26 08:53:03 +00:00
};
2016-01-26 11:17:10 +00:00
if (!marker) {
2016-01-26 08:53:03 +00:00
if (!map) {
L.mapbox.accessToken = config.mapboxAccessToken;
map = L.mapbox.map('map', 'mapbox.streets')
.setView(coords, zoomLevel);
}
marker = L.marker(coords, options)
.bindPopup(options.title)
.addTo(map);
map.setView(coords, zoomLevel);
2016-01-26 10:20:40 +00:00
updateUserList();
2016-01-26 08:53:03 +00:00
} else {
map.removeLayer(marker);
marker = L.marker(coords, options)
.bindPopup(options.title)
.addTo(map);
}
update({
name: username,
coords: coords
});
}
2016-01-26 11:17:10 +00:00
function updateUser(data) {
2016-01-26 08:53:03 +00:00
var user = getUserById(data.id);
if (!user) {
user = createUser(data);
}
2016-01-26 10:36:07 +00:00
user.coords = data.coords;
if (user.name != data.name) {
user.name = data.name;
updateUserList();
}
2016-01-26 08:53:03 +00:00
var options = {
2016-01-26 10:20:40 +00:00
title: user.name,
icon: L.icon({
iconUrl: MarkerIcon({
label: user.name[0],
background: user.color
})
2016-01-26 08:53:03 +00:00
})
};
if (user.marker) {
map.removeLayer(user.marker);
}
user.marker = L.marker(user.coords, options)
.bindPopup(user.name)
.addTo(map);
}
2016-01-26 10:20:40 +00:00
function updateUserList() {
var list = document.createElement('div');
list.id = 'users';
[{
name: username,
color: color
}].concat(users).forEach(function(user) {
var div = document.createElement('div');
div.className = 'person';
div.innerHTML = user.name;
div.style.background = 'rgb(' + user.color.join(', ') + ')';
div.style.top = '8px'
2016-01-26 10:36:07 +00:00
div.onclick = function() {
if (!user.id) {
var name = prompt("What is your name?", username) || 'Anonymous';
localStorage.username = username = name;
update({
name: username,
color: color,
coords: coords
});
updateUserList();
} else if (user.coords) {
map.setView(user.coords, zoomLevel);
}
}
2016-01-26 10:20:40 +00:00
list.appendChild(div);
});
if (userlist) {
document.body.replaceChild(list, userlist);
} else {
document.body.appendChild(list);
}
userlist = list;
}
function MarkerIcon(options) {
options = options || {};
options.background = options.background || [255, 0, 0];
options.color = options.color || [255, 255, 255];
options.label = options.label || 'A';
var size = 20;
var canvas = document.createElement('canvas')
canvas.setAttribute('width', size);
canvas.setAttribute('height', size);
var context = canvas.getContext('2d');
context.fillStyle = 'rgb(' + options.background.join(', ') + ')';
context.arc(size / 2, size / 2, size / 2 - 2, 0, 360);
context.fill();
context.beginPath();
context.lineWidth = 2;
context.strokeStyle = 'rgb(' + options.color.join(', ') + ')';
context.arc(size / 2, size / 2, size / 2 - 1, 0, 360);
context.stroke();
context.font = '14px sans-serif';
context.textAlign = 'center';
context.fillStyle = 'rgb(' + options.color.join(', ') + ')';
context.fillText(options.label, size / 2, size * 0.75);
return canvas.toDataURL();
}
2016-01-26 08:53:03 +00:00
return that;
})();