diff --git a/app.js b/app.js index 9736f84..4984410 100644 --- a/app.js +++ b/app.js @@ -4,9 +4,31 @@ //Restrictions on HEROKU: // Doesn't support installing dependencies with npm with node 0.8 // Doesn't support websocekts. - // Including libraries +var knox = require('knox'); + +var client = knox.createClient({ + key: 'AKIAIDZAMIX2REQZACVA', + secret: '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' + , bucket: 'bucket222' +}); +var stringafile =''; +var stringaip =''; +/* +var object = { foo: "bar" }; +var string = JSON.stringify(object); +var req = client.put('/test/obj.json', { + 'Content-Length': string.length + , 'Content-Type': 'application/json' +}); +req.on('response', function(res){ + if (200 == res.statusCode) { + console.log('saved to %s', req.url); + } +}); +req.end(string); +*/ var app = require('http').createServer(handler), io = require('socket.io').listen(app), nstatic = require('node-static'); // for serving files @@ -28,7 +50,7 @@ function handler (request, response) { } // Delete this row if you want to see debug messages -io.set('log level', 1); + io.set('log level', 1); // Heroku doesn't support websockets so... // Detect if heroku via config vars @@ -37,13 +59,36 @@ io.set('log level', 1); if (process.env.HEROKU === 'true') { io.configure(function () { io.set("transports", ["xhr-polling"]); - io.set("polling duration", 10); + io.set("polling duration", 20); }); } // Listen for incoming connections from clients io.sockets.on('connection', function (socket) { +/* +client.get('filelog.txt').on('response', function(res){ +var miadata = new Date(); +stringaip = socket.handshake.address.address + ' ' + miadata.getDate() +'/' + miadata.getMonth() + '/' + miadata.getYear() ++ ' ' + miadata.getHours() +':' + miadata.getMinutes() +':' + miadata.getSeconds(); + // console.log(stringaip); + // console.log(res.headers); + res.setEncoding('utf8'); + res.on('data', function(chunk){ +// console.log(chunk); +stringafile = stringafile + chunk; +// console.log(stringafile); + }); +}).end(); + +var buffer = new Buffer(stringafile + stringaip + '\n'); +var headers = { + 'Content-Type': 'text/plain' +}; +client.putBuffer(buffer, '/filelog.txt', headers, function(err, res){ + // Logic +}); +*/ // Start listening for mouse move events socket.on('mousemove', function (data) { @@ -52,11 +97,31 @@ io.sockets.on('connection', function (socket) { socket.broadcast.emit('moving', data); }); +socket.on('salvasulserver', function (data) { + + // var object = { foo: data.dataserver }; + var datidalclient = data.dataserver.replace(/^data:image\/\w+;base64,/, ""); +var buf = new Buffer(datidalclient, 'base64'); +//var string = 'scrivo qualche cosa'; +var req = client.put(data.orario + '.png', { + 'Content-Length': buf.length, + 'Content-Type': 'image/png' +}); +req.on('response', function(res){ + if (200 == res.statusCode) { +// console.log('saved to %s', req.url); + } +}); +req.end(buf); + + }); + socket.on('doppioclick', function (data) { // This line sends the event (broadcasts it) // to everyone except the originating client. socket.broadcast.emit('doppioclickser', data); + }); socket.on('chat', function (data) { @@ -64,6 +129,22 @@ socket.on('chat', function (data) { // This line sends the event (broadcasts it) // to everyone except the originating client. socket.broadcast.emit('chatser', data); + + }); +socket.on('fileperaltri', function (data) { + + // This line sends the event (broadcasts it) + // to everyone except the originating client. + socket.broadcast.emit('fileperaltriser', data); + + }); + +socket.on('camperaltri', function (data) { + + // This line sends the event (broadcasts it) + // to everyone except the originating client. + socket.broadcast.emit('camperaltriser', data); }); + }); \ No newline at end of file diff --git a/assets/css/styles.css b/assets/css/styles.css index c452368..a8f73c7 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -103,7 +103,7 @@ top:6px; left:3px; border:1px green solid; width:250px; -height:200px; +height:180px; font-size:11px; overflow:auto; } @@ -114,13 +114,8 @@ height:auto; #frecce { float:right; -background-color:#FFFFFF; -height:400px; -} - - -#frecce:hover { -background-color:#FFFF00; +background-color:transparent; +height:445px; } #paper { @@ -129,10 +124,10 @@ background-color:#FFFF00; #controlli { position:absolute; -top:3px; +top:6px; left:-285px; width:300px; -height:400px; +height:480px; background-color:#ffffff; border:1px red solid; z-index:10; @@ -141,6 +136,22 @@ z-index:10; left:0px; } +#frecce:hover { +background-color:transparent; +} +#frecce:out { +background-color:transparent; +} + +#monitorcam { +position:absolute; +top:0px; +left:170px; +width:320px; +height:240px; +border:2px green solid; +z-index:120 +} /*---------------------------- The Footer -----------------------------*/ diff --git a/assets/js/script.js b/assets/js/script.js index 176b605..b3c67e1 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -5,13 +5,17 @@ jQuery(function(){ alert('Sorry, it looks like your browser does not support canvas!'); return false; } - + + // The URL of your web server (the port is set in app.js) //var url = 'http://localhost:3000'; var url = window.location.hostname; + var positionx ='20'; + var positiony='0'; var doc = jQuery(document), canvas = jQuery('#paper'), + canvas1 = jQuery('#paper1'), instructions = jQuery('#instructions'); var color = '#000000'; // A flag for drawing activity @@ -22,6 +26,7 @@ var color = '#000000'; // funzione richiesta di nick name var username = ''; + if(!username) { @@ -29,10 +34,10 @@ if(!username) } username = username.substr(0,20); - - var socket = io.connect(url); +var socket = io.connect(url); var ctx = canvas[0].getContext('2d'); +var ctx1 = canvas1[0].getContext('2d'); var spessore = jQuery('#spessore').value; var colorem; // Force canvas to dynamically change its size to the same width/height @@ -43,7 +48,7 @@ var colorem; // ctx setup ctx.lineCap = 'round'; ctx.lineJoin = 'round'; - ctx.lineWidth = 3; + ctx.lineWidth = 2; ctx.font = "20px Tahoma"; // Generate an unique ID @@ -61,15 +66,54 @@ if (code == '13') { }); jQuery('
ME ' + document.getElementById('scrivi').value +'
').appendTo('#testichat'); document.getElementById('scrivi').value =''; - + +var objDiv = document.getElementById("testichat"); +objDiv.scrollTop = objDiv.scrollHeight; + }} +}); + +$('#file-input').change(function(e) { + var file = e.target.files[0], + imageType = /image.*/; + if (!file.type.match(imageType)) + return; + + var reader = new FileReader(); + reader.onload = fileOnload; + reader.readAsDataURL(file); + + }); +/* +jQuery('#salvasulserver').click(function (){ +var dataserver = canvas[0].toDataURL(); + +socket.emit('salvasulserver',{ + 'id': id, + 'dataserver': dataserver, + 'orario': jQuery.now() + }); }); -jQuery('#paper').dblclick(function (e){ +*/ + +jQuery('#vedomonitor').click(function (){ +if(document.getElementById('monitorcam').style.display == 'none') { +document.getElementById("monitorcam").style.display = 'block'; +document.getElementById('vedomonitor').innerHTML = ' Hide webcam monitor '; +} else { +document.getElementById('monitorcam').style.display = 'none'; +document.getElementById('vedomonitor').innerHTML = ' Show webcam monitor '; +} +}); +jQuery('#paper').dblclick(function (e){ +positionx = e.pageX; +positiony= e.pageY; if (document.getElementById('scrivi').value.length > 1 ) { ctx.fillStyle = $('#minicolore').minicolors('rgbaString'); +ctx.font = document.getElementById('fontsize').value +"px Tahoma"; ctx.fillText(document.getElementById('scrivi').value, e.pageX, e.pageY); socket.emit('doppioclick',{ @@ -78,7 +122,8 @@ socket.emit('doppioclick',{ 'scrivi': document.getElementById('scrivi').value, 'color': $('#minicolore').minicolors('rgbaString'), 'id': id, - 'spessremo' : document.getElementById('spessore').value + 'spessremo' : document.getElementById('spessore').value, + 'fontsizerem': document.getElementById('fontsize').value }); document.getElementById('scrivi').value =''; @@ -95,9 +140,30 @@ window.open(document.getElementById("canvasimg").src, "toDataURL() image", "widt jQuery('#cancellalavagna').click(function (){ ctx.clearRect(0, 0, canvas[0].width, canvas[0].height); }); + + socket.on('camperaltriser', function (data) { +var camdaclient = new Image(); +camdaclient.src = data.camperaltridati; +camdaclient.onload = function() { +// imgdaclient.src = data.fileperaltri; +ctx.drawImage(camdaclient,data.positionx,data.positiony,320,240); +} +}); + + + socket.on('fileperaltriser', function (data) { + +var imgdaclient = new Image(); +imgdaclient.src = data.fileperaltri; +imgdaclient.onload = function() { +// imgdaclient.src = data.fileperaltri; +ctx.drawImage(imgdaclient, data.positionx, data.positiony); +} +}); socket.on('doppioclickser', function (data) { ctx.fillStyle = data.color; + ctx.font = data.fontsizerem + "px Tahoma"; ctx.fillText(data.scrivi, data.x, data.y); }); @@ -107,6 +173,8 @@ ctx.clearRect(0, 0, canvas[0].width, canvas[0].height); //alert (data.testochat); jQuery('
' + data.usernamerem +' '+ data.testochat +'
').appendTo('#testichat'); document.getElementById('frecce').style.backgroundColor ='#ffff00'; +var objDiv1 = document.getElementById("testichat"); +objDiv1.scrollTop = objDiv1.scrollHeight; }); socket.on('moving', function (data) { @@ -143,7 +211,7 @@ document.getElementById('frecce').style.backgroundColor ='#ffff00'; // document.addEventListener("touchstart", touchHandler, true); - // document.addEventListener("blur", cambiacolore(), true); +// document.addEventListener("blur", cambiacolore(), true); document.addEventListener("change", cambiaspessore, true); function cambiaspessore () { @@ -200,7 +268,7 @@ document.getElementById('frecce').style.backgroundColor ='#ffff00'; setInterval(function(){ var totalOnline = 0; for(var ident in clients){ - if(jQuery.now() - clients[ident].updated > 10000){ + if(jQuery.now() - clients[ident].updated > 20000){ // Last update was more than 10 seconds ago. // This user has probably closed the page @@ -209,10 +277,15 @@ document.getElementById('frecce').style.backgroundColor ='#ffff00'; delete clients[ident]; delete cursors[ident]; } - else totalOnline++; - } - jQuery('#onlineCounter').html('Players Connected: '+totalOnline); - },10000); + else { + totalOnline++; + if (document.getElementById('faisuonare').checked) { + var thissound=document.getElementById("audio1"); +thissound.play(); + } + }} + jQuery('#onlineCounter').html('Users connected: '+totalOnline); + },20000); function drawLine(fromx, fromy, tox, toy){ ctx.strokeStyle = $('#minicolore').minicolors('rgbaString'); @@ -231,8 +304,93 @@ document.getElementById('frecce').style.backgroundColor ='#ffff00'; ctx.lineTo(tox, toy); ctx.stroke(); } + +function fileOnload(e) { + var img = $('', { src: e.target.result }); + // alert(img.src.value); + // var canvas1 = $('#paper')[0]; + // var context1 = canvas1.getContext('2d'); + img.load(function() { + ctx.drawImage(this, positionx, positiony); + socket.emit('fileperaltri',{ + 'id': id, + 'positionx': positionx, + 'positiony': positiony, + 'fileperaltri': this.src + }); + }); + } +(function() { + + var streaming = false, + video = document.getElementById('video'), + paper1 = document.getElementById('paper1'), + startbutton = document.getElementById('catturacam'), + width = 320, + height = 240; + + navigator.getMedia = ( navigator.getUserMedia || + navigator.webkitGetUserMedia || + navigator.mozGetUserMedia || + navigator.msGetUserMedia); + + navigator.getMedia( + { + video: true, + audio: false + }, + function(stream) { + if (navigator.mozGetUserMedia) { + video.mozSrcObject = stream; + } else { + var vendorURL = window.URL || window.webkitURL; + video.src = vendorURL ? vendorURL.createObjectURL(stream) : stream; + } + video.play(); + }, + function(err) { + console.log("An error occured! " + err); + } + ); + + video.addEventListener('canplay', function(ev){ + if (!streaming) { + height = video.videoHeight / (video.videoWidth/width); + video.setAttribute('width', 320); + video.setAttribute('height', 240); + // canvas.setAttribute('width', width); + // canvas.setAttribute('height', height); + streaming = true; + } + video.setAttribute('width', 320); + video.setAttribute('height', 240); + }, false); + + function takepicture(e) { + ctx.drawImage(video, positionx, positiony,320,240); +ctx1.drawImage(video,0,0,320,240); +var datacam = paper1.toDataURL('image/png'); +// paper1 e ctx1 servono per prelevare solo i dati della webcam e inviarli al server per gli altri +socket.emit('camperaltri',{ + 'id': id, + 'positionx': positionx, + 'positiony': positiony, + 'camperaltridati': datacam + }); + } + + startbutton.addEventListener('click', function(ev){ + + takepicture(); + ev.preventDefault(); + }, false); + +})(); + + }); + \ No newline at end of file diff --git a/assets/success.wav b/assets/success.wav new file mode 100644 index 0000000..72d3dd8 Binary files /dev/null and b/assets/success.wav differ diff --git a/index.html b/index.html index 9e57730..9d2b100 100644 --- a/index.html +++ b/index.html @@ -2,45 +2,48 @@ - + - + - + - whiteboard collaborative multicolor multiusers + Real time whiteboard collaborative multicolor multiusers with chat and upload images - + + - - - + + + + + +
-
+
-
-

-Insert a text
+
+At first double click on the whiteboard
where you want to place your photo,
+then upload file .jpg to share with all
+

-Double click on the whiteboard where
you want to places the text
or enter if you want to chat +Double click on the whiteboard where
you want to place the text
or enter if you want to chat
+
+Play a sound when someone
connect this whiteboard
+
+ +
@@ -76,21 +116,23 @@
- + + Your browser needs to support canvas for this to work! +
-

Draw anywhere!

+

Draw anywhere!

You will see everyone else who's doing the same.

-

Tip: if the stage gets dirty, simply reload the page

+

If you like this web application please click the button LIKE at the bottom of this page