Cobo Coscotin Vasilica documentatie

553 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
553
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Cobo Coscotin Vasilica documentatie

  1. 1. COBO Aplicatie Web ce permite editarea colaborativa a unei planse (whiteboard) folosind facilitatile oferite de canvas Coscotin Vasilica Abstract. Cobo este o aplicatie web ce permite editarea colaborativa a unei planse folosind facilitatile oferite de elementul Canvas din HTML5. Comunicarea intre clienti(browsere) se face folosind Socket.IO. Aplicatia ofera utilizatorului posibilitatea de a desena cudiferite “creioane”, de a insera figuri geometrice , poze si text. Plansa poate fi salvata la nivel local sirestaurat ulterior sau exportata in format PNG. 1 Introducere Cobo a fost creata in cadrul laboratorului de Aplicatii Web la Nivel de Client de la Facultateade Informatica Iasi sustinut de Ciprian Amariei, profesor de curs fiind Dr. Sabin-Corneliu Buraga.Aplicatia este Open Source sursa putand fi descarcata la adresahttp://students.info.uaic.ro/~vasilica.coscotin/cobo. 2 Tehnologii folosite Cobo a fost creata folosind HTML5 , Javascript si Socket.IO. Elementul canvas din HTML5 apermis redare in mod dinamic a scripturilor de redare a formelor 2D si a imaginilor de tip Bitmap. Amfolosit libraria jQuery ,pentru Javascript , pentru a realiza medodele de intercatiunde dintre utilizator sibrowser . Pentru a permite comunicare in timp real intre clienti (browsere) am folosit Socket.IO careeste o implementare a interfetei HTTP Socket.
  2. 2. 2.1 Canvas si Javascript 2.1.1 Functii pentru desenare Fiecare canvas are un context de desenare in aplicatia COBO este unul 2D si este apelat in felulurmator : var canvas = document.getElementById("sheet"); var context = canvas.getContext("2d");unde sheet este ID-ul elementului canvas din index.html. Pentru a desena forme geometrice in contextul context folosim urmatoarele functii : pentru a desena linii (unde x1,y1 sunt coordonatele mouse-ului cand are loc evenimetnulmouseDown iar x2,y2 sunt coordonatele mouse-ului cand are loc evenimetnul mouseUp) var line = function(x1, y1, x2, y2, s) { s.globalCompositeOperation = source-over; setStyle(s); context.beginPath(); context.moveTo(x1, y1); context.lineTo(x2, y2); context.closePath(); context.stroke(); } pentru a desena cu un creion (unde x1,y1 sunt coordonatele mouse-ului cand are locevenimetnul mouseDown iar x2,y2 sunt coordonatele mouse-ului cand are loc evenimetnulmouseMove): var pencil = function(x1, y1, x2, y2, s) { s.globalCompositeOperation = source-over; setStyle(s); context.beginPath(); context.moveTo(x1, y1); context.lineTo(x2, y2); context.closePath(); context.stroke(); } pentru a desena un cerc (unde x1,y1 sunt coordonatele mouse-ului cand are loc evenimetnulmouseDown iar x2,y2 sunt coordonatele mouse-ului cand are loc evenimetnul mouseUp) var circle = function(x1, y1, x2, y2, s) { s.globalCompositeOperation = source-over; minX = (x1<x2) ? x1 : x2; minY = (y1<y2) ? y1 : y2; radiusX = Math.abs(x1 - x2) / 2; radiusY = Math.abs(y1 - y2) / 2; context.beginPath(); setStyle(s); context.arc(minX+radiusX, minY+radiusY, radiusX, 0, 2*Math.PI, false); context.closePath(); context.stroke(); } pentru a desena un cerc (unde x1,y1 sunt coordonatele mouse-ului cand are loc evenimetnul
  3. 3. mouseDown iar x2,y2 sunt coordonatele mouse-ului cand are loc evenimetnul mouseUp) var rectangle = function(x1, y1, x2, y2, s) { s.globalCompositeOperation = source-over; minX = (x1<x2) ? x1 : x2; minY = (y1<y2) ? y1 : y2; xl = Math.abs(x1-x2); yl = Math.abs(y1-y2); setStyle(s); context.beginPath(); context.rect(minX, minY, xl, yl); context.closePath(); context.stroke(); } In toate cele 4 functii parametrul s reprezinta stilul formei (culoare, grosime,transparenta,lineJoin si lineCap). 2.1.2 Mouse handlers Pentru a controla evenimentele mouse-ului am folosit urmatoarele functii: // event handler pentru Mouse Down $(#sheet).mousedown(function(e) { mouseDown = true; // pentru a verifica in mouseMove daca este tinut apasat clikstanga mouseX = e.pageX - this.offsetLeft; // pentru a lua pozitia mouseului fata decanvas mouseY = e.pageY - this.offsetTop; context.moveTo(mouseX, mouseY); switch(tool){ case Pen: // desenam in cazul in care unelata selectata este Pen pencil(mouseX, mouseY, mouseX+1, mouseY, style); msg = { "x1":mouseX, "y1":mouseY, "x2":mouseX+1, "y2":mouseY,"tool":Pen, "style":style }; socket.send(JSON.stringify(msg)); break; case Text: if($(#textVal).val() != ) { //vreificam daca sunt bifate optiunile pentru bold,italic si underline font = ; if($(#bold).is(:checked)) font += bold ; if($(#underline).is(:checked)) font += underline ; if($(#italic).is(:checked)) font += italic ; font += $(#penSize).slider(value)*5 + px sans-serif; context.font = font; context.fillStyle = style.strokeStyle; context.fillText($(#textVal).val(), mouseX, mouseY); msg = { "x":mouseX, "y":mouseY, "tool":Text, "font":font,"text":$(#textVal).val(), "style":style }; socket.send(JSON.stringify(msg));// trimitem la ceilalticlienti prin server } break; case IMAGE: // pentru a desa o imagine pe canvas context.drawImage(image, mouseX, mouseY); msg = { "x":mouseX, "y":mouseY, "image":image.src, "tool":Img }; socket.send(JSON.stringify(msg)); break; break; }
  4. 4. }); // event handler pentru Mouse Up $(#sheet).mouseup(function(e) { mouseDown = false; // nu mai este tinut apasat click-ul newX = e.pageX - this.offsetLeft;// pentru a lua pozitia mouseului fata de canvas newY = e.pageY - this.offsetTop;// pentru a lua pozitia mouseului fata de canvas oldX = mouseX; oldY = mouseY; switch(tool) { case Pen: // nu facem nimic pentru ca desenarea s-a facut in cadrul mouseMove break; case Circ: // desenam cecul din pozitia oldX oldY in pozitia newX newY si cudiametrul = distanta dintre oldX newX respectiv oldY newY circle(oldX, oldY, newX, newY, style); msg = { "x1":oldX, "y1":oldY, "x2":newX, "y2":newY, "tool":Circ,"style":style }; socket.send(JSON.stringify(msg)); break; case Rec:// desenam patratul din pozitia oldX oldY in pozitia newX newY si cudiametrul = distanta dintre oldX newX respectiv oldY newY rectangle(oldX, oldY, newX, newY, style); msg = { "x1":oldX, "y1":oldY, "x2":newX, "y2":newY, "tool":Rec,"style":style }; socket.send(JSON.stringify(msg)); break; case Line:// desenam linia din pozitia oldX oldY in pozitia newX newY si cudiametrul = distanta dintre oldX newX respectiv oldY newY line(oldX, oldY, newX, newY, style); msg = { "x1":oldX, "y1":oldY, "x2":newX, "y2":newY, "tool":Line,"style":style }; socket.send(JSON.stringify(msg)); break; } }); // event handler pentru mouse move $(#sheet).mousemove(function(e) { newX = e.pageX - this.offsetLeft; newY = e.pageY - this.offsetTop; if(mouseDown) { //cat timp e tinut apasat butonul de mouse deseneaza sau sterge oldX = mouseX; oldY = mouseY; switch(tool){ case Pen: pencil(oldX, oldY, newX, newY, style); msg = { "x1":oldX, "y1":oldY, "x2":newX,"y2":newY,"tool":Pen,"style":style }; socket.send(JSON.stringify(msg)); mouseX = newX; mouseY = newY; break; case Eraser: eraser(oldX, oldY, newX, newY, style); msg = { "x1":oldX, "y1":oldY, "x2":newX, "y2":newY,"tool":Eraser, "style":style }; socket.send(JSON.stringify(msg)); mouseX = newX; mouseY = newY; break; break; } } }); // cand mouse-ul paraseste suprafata canvasului $(#sheet).mouseleave(function() {
  5. 5. mouseDown = false; }); Aceste evenimente apar la actiunile mouse-ului pe suprafata browser-ului. 2.1.3 Alegerea culorii Alegerea culorii se face prin alegerea cantitatilor de rosu, albastru si verde prin miscarea lastanga sau dreapta a slider-elor // color and size //regleaza in fuctie de slider-ecolaore(cantitatea de Red, Green si Blue) $(#red).slider({ value: 95, min: 0, max: 255, slide: function(event, ui) { changeColor(); } }).width(160); $(#green).slider({ value: 221, min: 0, max: 255, slide: function(event, ui) { changeColor(); } }).width(160); $(#blue).slider({ value: 122, min: 0, max: 255, slide: function(event, ui) { changeColor(); } }).width(160); $(#opac).slider({ value: 100, min: 0, max: 100, slide: function(event, ui) { changeColor(); } }).width(160); //Schimb culoarea pensulei actualizand style- ul si in acleasi timp schimbsi culoarea fundalului din div-ul Selected color var changeColor = function(){ c = rgba( + $(#red).slider(value) + , + $(#green).slider(value) +, + $(#blue).slider(value) + , + ($(#opac).slider(value) / 100) + ); $(#selectedColor).css({backgroundColor: c}); style.strokeStyle = rgb( + $(#red).slider(value) + , + $(#green).slider(value) + , + $(#blue).slider(value) + );
  6. 6. style.globalAlpha = ($(#opac).slider(value) / 100); } 2.1.3 Dimensiune pensulei Dimensiune este setata tot cu ajutorul unui slider $(#penSize).slider({ value: 2, step: 0.1, min: 0.5, max: 20, slide: function(event, ui) { style.lineWidth = ui.value; } }).width(160); 2.1.4 Actiuni pe fisier Dupa cum am precizat si in abstract aplicatia ofera utilizatului posibiliatatea de a salva desenulla nivel local , de a restaura desenul salvat si de a exporta desenul in format PNG. Aceste actiuni suntrealizate in cu jQuery :// file functions //salveaza imaginea canvas la nivel-ul browser-ului var saveFile = function(){ localStorage.setItem("sheet", canvas.toDataURL()); } $(#save).click(function() { saveFile(); }); //deseneaza imaginea incarcata din "baza de date" a browser-ului var load = function(imageSource) { image = new Image(); image.src = imageSource; canvas.width = canvas.width; context.drawImage(image, 0, 0); } //incarca imaginea din "baza de date" a browserului $(#load).click(function() { imageSource = localStorage.getItem("sheet"); load(imageSource); msg = { "tool":Load, "image":imageSource }; socket.send(JSON.stringify(msg)); }); //face o coala noua stergat tot ce este in canvas $(#newSheet).click(function(){ canvas.width = canvas.width; msg = { "tool":New }; socket.send(JSON.stringify(msg)); }); //incarca o imagine selectata din dialog de selecare a unui fisier $(#imageSource).change(function() { var file = document.getElementById(imageSource).files[0]; reader = new FileReader();
  7. 7. reader.onload = function (event) { image = new Image(); image.src = event.target.result; }; reader.readAsDataURL(file); tool = IMAGE; }); //exporta imagina in fomrat Png $(#export).click(function() { window.open(canvas.toDataURL()); }); 2.2 Transmiterea datelor Transmiterea datelor se cu ajutorul Socket.IO care in functie de browser selecteaza un protocolde comunicare WebSocket pentru Google Chrome, xhr-multipart pentru Mozilla. Functiile pentru trasferul datelor sunt urmatoarele: //realoziaza conexiunea la server var socket = new io.Socket(localhost,{ port: 9125 }); socket.connect(); //trimite date la ceilalti clienti in functie de toolul selectat socket.on(message, function(msgData) { msgData = $.parseJSON(msgData); switch(msgData.tool){ case Pen: pencil(msgData.x1, msgData.y1, msgData.x2, msgData.y2,msgData.style); break; case Circ: circle(msgData.x1, msgData.y1, msgData.x2, msgData.y2,msgData.style); break; case Rec: rectangle(msgData.x1, msgData.y1, msgData.x2, msgData.y2,msgData.style); break; case Text: context.font = msgData.font; context.fillStyle = msgData.style.strokeStyle; context.fillText(msgData.text, msgData.x, msgData.y); break; case Load: load(msgData.image); break; case New: canvas.width = canvas.width; break; case IMAGE: image = new Image(); image.src = msgData.image; context.drawImage(image, msgData.x, msgData.y); break;
  8. 8. case Eraser: eraser(msgData.x1, msgData.y1, msgData.x2, msgData.y2,msgData.style); break; break;} }); break; case Line: line(msgData.x1, msgData.y1, msgData.x2, msgData.y2,msgData.style); break; case Text: context.font = msgData.font; context.fillStyle = msgData.style.strokeStyle; context.fillText(msgData.text, msgData.x, msgData.y); break; case Load: load(msgData.image); break; case New: canvas.width = canvas.width; break; case IMAGE: image = new Image(); image.src = msgData.image; context.drawImage(image, msgData.x, msgData.y); break; case Eraser: eraser(msgData.x1, msgData.y1, msgData.x2, msgData.y2,msgData.style); break; break;} });
  9. 9. 3 Modalitate de utilizare Din meniul din dreapta sus se alege pensula pentru desenare posibilitatile fii :Pencil, Line, Recangle, Circle, Eraser dupa care se deseneaza pe canvas ( foaia alba ). Meniul din dreapta se poate alege culoare pensulei precum si dimensiunea acestia (la optiuneasize). Tot aici la submeniu text putem scrie textul ce urmeaza sa fie inserat si selecta stilul textului(Bold,Italic,Underline) Din partea de sus meniului putem selecta daca sa salvam imaginea la nivel local , sa reincarcamimaginea salvata si sa o exportam in format PNG intr-o alta fereastra. 4 Bibliografie http://socket.io/ http://www.w3schools.com/ http://docs.jquery.com/Main_Page http://profs.info.uaic.ro/~busaco/teach/courses/cliw/web.html

×