var cursor_image = "https://s3.amazonaws.com/luckyplop/52d5f60fde3d8562ad566838e0e09ca52725bb09.gif"; var own_cursor; var socket = io.connect(); var users = {}, scores = {}, cursors = []; var game = { cursor: null, init: function (){ game.bindSocket(); if (window._id) { socket.emit('joined', JSON.stringify({ "id": window._id })); var now = Date.now(); own_cursor = new Cursor({ firstname: "...", score: 0, current: 0, active: true, connected: now }, now); own_cursor.own = true; own_cursor.el.addClass("own"); game.bindEvents(); } game.loop(); }, loop: function (){ requestAnimFrame(game.loop); UI.updateWait(Date.now()); }, bindSocket: function(){ socket.on('count', function(data){ UI.updateUsers(data); }); socket.on('scores', function(data){ UI.updateUsers(data); UI.updateScores(data); }); socket.on('mouse', function(data){ if (data.id != _id && data.id in users) { users[data.id].cursor.el.css({ 'margin-left': data.x, 'margin-top': data.y }); } }); socket.on('focus', function(data) { if (data.id != _id && data.id in users && users[data.id].cursor) { users[data.id].cursor.focus(); } }); socket.on('blur', function(data){ if (data.id != _id && data.id in users && users[data.id].cursor) { users[data.id].cursor.blur(); } }) }, bindEvents: function(){ var emit_mouse_movement = $.throttle(50, function (e) { var y = Math.floor( e.pageY - window.innerHeight / 2 ); var x = Math.floor( e.pageX - window.innerWidth / 2 ); socket.emit('mouse', { x: x, y: y, id: _id }); }); $(window).bind({ blur: function (e) { // $("#really_waiting").html("BLUR"); socket.emit('blur', { id: _id }); own_cursor.blur(); }, focus: function (e) { // $("#really_waiting").html("FOCUS"); // socket.emit('focus', { id: _id }); // own_cursor.focus(); }, mousemove: function(e){ emit_mouse_movement(e); own_cursor.el.css({ 'left': e.pageX, 'top': e.pageY }); } }); var hovering = false; own_cursor.blur(); $("#racecar").hoverpng({ mouseover: function(e){ socket.emit('focus', { id: _id }); own_cursor.focus(); }, mousemove: function(e){ }, mouseout: function(e){ socket.emit('blur', { id: _id }); own_cursor.blur(); }, threshold: 0.8 }); $(".okfocus").bind({ mouseover: function(){ own_cursor.el.hide(); }, mouseout: function(){ own_cursor.el.show(); } }); } }; var UI = { updateWait: function(now) { for (var i = 0, _len = cursors.length; i < _len; i++) { if (! cursors[i].afk) { cursors[i].update(now); } } }, updateUsers: function(data) { console.log(data.users); var now = data.now; var seen_ids = {}; for (var i in data.users) { var user = data.users[i]; seen_ids[ user.id ] = true; if (!( user.id in users )) { users[user.id] = user; if (user.id != _id && ! user.cursor) { var cursor = new Cursor( user, now ); user.cursor = cursor; user.cursor.el.css({ 'margin-left': user.x, 'margin-top': user.y }); } else if (user.id == _id && own_cursor) { user.cursor = own_cursor; own_cursor.name.html( user.firstname ); } if (user.id in scores) { user.cursor.score = scores[user.id]; } } } for (var id in users) { if (!( id in seen_ids )) { if (users[id].cursor) { users[id].cursor.remove(); } delete users[id]; } } }, updateScores: function(data){ var current_scores = data.scores; $("#scores").html(""); for (var i = 0; i < current_scores.length; i++) { var score = new Score( current_scores[i] ); if (score.id in users) { users[score.id].cursor.score = score; } scores[score.id] = score; } } } function Score ( user ) { var base = this; base.add = function(){ base.el = $("
  • "); base.id = user.id; base.count = user.count; base.current = user.count; base.name = $(""); base.name.addClass("name"); base.name.html(user.firstname + " " + user.lastname); base.time = $(""); base.time.addClass("time"); base.time.html( timeInWords(user.count) ); base.el.append(base.name); base.el.append(" — "); base.el.append(base.time); $("#scores").append(base.el); } base.update = function(howlong){ base.current = base.count + howlong base.time.html( timeInWords( base.current ) ); } base.save = function(){ base.count = base.current; } base.add(); } function Cursor ( user, now ) { var base = this; base.id = user.id; base.start = Date.now(); base.initial = user.current || 0; base.delay = 0; base.blurStart = 0; base.afk = false; base.own = false; base.score = null; base.add = function(){ base.el = $("
    "); base.el.addClass("cursor"); base.el.css('background-image', 'url(' + cursor_image + '?' + Math.floor(Math.random() * 1000) + ')'); base.name = $("
    "); base.name.addClass('name'); base.name.html( user.firstname ); base.time = $("
    "); base.time.addClass('time'); base.time.html( "0:00" ); base.el.append(base.name); base.el.append(base.time); $("#cursors").append(base.el); cursors.push(base); if (user.active) { base.initial += now - user.connected; } else { base.blur(); } // console.log(now, base.start, base.initial, base.delay); } base.update = function(now){ var howlong = Math.floor( (now - base.start) ) + base.initial - base.delay; base.time.html( timeInMillisecs( howlong ) ); if (base.score) { base.score.update( howlong ); } } base.blur = function(){ base.blurStart = Date.now(); base.afk = true; base.el.addClass('idle'); } base.focus = function(){ base.afk = false; base.el.removeClass('idle').show(); if (base.blurStart) { base.delay += (Date.now() - base.blurStart); } } base.remove = function(){ if (base.score) { base.score.save(); } base.el.remove(); cursors.splice( cursors.indexOf(base), 1 ) } base.add(); }