Într-o lume a tehnologiei și a device-urilor inteligente,în care comunicarea ar trebui privită ca un factor esențial, trebuie să dezvoltăm pe lângă formele tradiționale noi modalități de interacțiune om-calculator. Scopul acestui articol este de a propune ideea utilizării de căi alternative pentru a interacționa cu un calculator, căi aliniate noilor tehnologii disponibile. Propunerea va fi exemplificată printr-o aplicație de chat online în timp real, care va fi creată folosind ASP.NET MVC și SignalR și care va primi informațiile de la o tastatură controlată prin Leap Motion Controller.
Pentru a implementa aplicația de chat online în timp real care permite inputul de gesturi de la Leap Motion Controller, interpretate de către tastatura virtuală, avem nevoie de următoarele tehnologii:
Funcționalitatea web-chat este dezvoltată folosind ASP.NET MVC și SignalR; tastatura virtuală este implementată pe baza THREE.js și CSS3DRenderer, iar inputul de gesturi și semnalele de feedback de la Leap Motion Controller sunt interpretate folosind extensiile LeapJS API și Leap-widgets.js.da
În trecut, paginile web erau statice și nimeni nu se aștepta ca ele să facă un update singure după un timp. Fiecare acțiune a user-ului necesita ca întregul conținut al paginii să fie retrimis de la server. Încetul cu încetul, internetul și-a accentuat dezvoltarea, iar drumul de la pagini statice la pagini dinamice a început să se contureze. O primă încercare de a crea pagini dinamice a fost reprezentată de introducerea tag-ului iFrame și de controlul ActiveX. Mai târziu, odată cu introducerea Ajax și jQuery, paginile web dinamice au câștigat în fața vechilor pagini html (http://www.evolutionoftheweb.com/).
Când navigăm pe internet, avem nevoie de un browser web pentru a accesa și a afișa o pagină web. Acest browser are propriul lui motor de randare, care ajută la interpretarea și coordonarea diferitelor tag-uri, elemente și resurse de pe pagina respectivă, pentru a putea să le afișeze utilizatorului. Acum câțiva ani, foloseam calculatorul pentru a naviga pe internet; nu exista încă noțiunea de smartphone, tabletă, smart TV sau smartwatch sau orice alt tip de gadget inteligent.
În prezent, aproape toate device-urile noastre folosesc un browser web care ne permite să stăm pe internet. Dorim ca aplicațiile pe care le dezvoltăm să fie disponibile și să poată fi accesate de pe toate aceste device-uri, însă tocmai datorită varietații lor conținutul arată bine pe unele, dar nu grozav pe altele. De asemenea, ne dorim ca aplicații precum un sistem de monitorizare sau o aplicație pentru verificat vremea să afișeze informațiile noi în timp real (imediat ce informația devine disponibilă) fără să fie nevoie să o cerem noi. Dacă ne conectăm de pe device-urile noastre la o aplicație de social media, ne așteptăm ca orice schimbare și actualizare făcute de pe device-ul propriu să fie vizibilă instant și pe tableta noastră sau pe smart TV, precum și pe device-urile prietenilor noștri, fără să fie nevoie să acționăm explicit în acest sens.
Atunci cum am putea crea aplicații web care să funcționeze în timp real și pe care să le putem accesa de pe toate aceste tipuri de device-uri? SignalR ne ajută să găsim o soluție pentru a transfera datele între server și client într-un mod rapid și sigur, pentru comunicarea în timp real.
SignalR este o librărie open source susținută de Microsoft. Oferă comunicare bidirecțională (full duplex) între client și server. Prin urmare, spre deosebire de modelul tradițional, unde clientul trebuia să facă o cerere către server, de această dată clientul și serverul împart un canal deschis iar serverul poate la rândul său să contacteze clientul.De asemenea, poate să furnizeze conținut în mod asincron, să suporte toate browser-ele și are o modalitate inteligentă de a decide ce tip de transport să folosească pentru a transmite mesajele.
Deciziile privind transportul se bazează pe tipul de browser și pe alte configurații client și server și încearcă diferite tehnici de transport, cum ar fi websocket, server sent events, forever frame și long polling, având un mecanism de selecție dacă unul din ele nu este suportat.
Conexiunea începe ca HTTP standard și, dacă e posibil, se face trecerea spre websocket, care ar fi metoda de transport ideală din perspectiva SignalR. Protocolul Websocket este destul de nou pe piață (2011) și device-urile mai vechi nu îl suportă. Cu SignalR nu trebuie să ne facem griji și să scriem cod pentru clienți mai vechi deoarece SignalR poate decide ce alt tip de transport poate folosi pentru a stabili conexiunile cu ei. Dacă Websocket nu este disponibil, se ia decizia între server sent events (nu sunt suportate de Internet Explorer), forever frame (doar pentru Internet Explorer) și Ajax long polling.
SignalR furnizează ca modele de comunicare Persistent Connections și Hubs. Persistent Connections este configurabilă și este similară web socket-urilor. Dacă, de exemplu, aplicația noastră are cerințe speciale și trebuie să avem control asupra acțiunilor pe care vrem să le facem când deschidem o conexiune, putem alege să o derivăm.
Hubs sunt construite peste Connection API. Dacă alegem să folosim hub-urile oferite de SignalR, putem să apelăm metodele definite pe partea de server de pe client și viceversa, direct. Întreaga parte de management a conexiunilor este oferită de SignalR. Prin urmare, dacă ne folosim de Hubs, lăsăm SignalR-ul să facă toată treaba.
Server side:
//DemoHub class is derived from class. This allows us to create public methods that can be called from script in web pages
public class DemoHub : Hub
{
//method that can be called from the client
public void MessageToServer(string sampleText)
{
//specify the function to call on the client, this
//function has to be defined on the client; This will
//execute the js function messageToClient on all
//the clients connected to the hub due to Clients.All
//property that gives access to all connected clients
Clients.All.messageToClient(“message received”);
}
}
Client Side:
//reference to a hub proxy
var demo = jQuery.connection.demoHub;
//js function on the client that can be called from
//the hub
demo.client.messageToClient = function (message) {
alert(message);
};
//opening a connection to a hub
jQuery.connection.hub.start().done(function () {
//call MessageToServer method on the hub from the
//client
demo.server.messageToServer(“Sending message”),
});
Leap Motion Controller este un device care captează și interpretează semnale de la senzori optici și infra-roșu pentru a identifica mâinile, degetele și instrumentele de indicație. Acest device de urmărire este o alegere bună deoarece are suport API multi-language. De asemenea, oferă o cartografiere virtuală a spațiului, feedback în timp real, dar și recunoaștere și training pentru gesturi. Următoarea imagine prezintă acest device împreună cu sistemul său de coordonate.
Câmpul vizual al senzorului optic este de aproximativ 150 de grade, iar raza de detecție se extinde de la 25 până la 600 de milimetri deasupra device-ului. Unitățile sale de măsură sunt reprezentate în milimetri pentru distanțe, microsecunde pentru timp, milimetri per secundă pentru viteză și radian pentru unghiuri.
Modelul Entity al datelor captate de controller este denotat de un Frame, conținând informații din întregul spațiu de lucru, cum ar fi mișcarea și gesturile realizate, mâinile, degetele și/sau instrumentele de indicare. Folosind aceste informații, gesturi precum descrierea unui cerc, apăsarea unei taste sau atingerea ecranului pot fi identificate.
Integrarea Leap Motion Controller în aplicație se va baza pe interfața WebSocket din arhitectura sistemului. Datele captate de device sunt transmise într-o structură de tip JSON printr-un WebSocket. În acest fel, librăriile JavaScript de pe client pot interpreta și analiza mesajele. Interpretarea datelor brute primite prin WebSocket se face în browser cu ajutorul framework-ului LeapJS.
Elementul vizual care intermediază comunicarea cu calculatorul este tastatura virtuală. Această tastatură este implementată folosind tehnologii JavaScript client, cum ar fi THREE.js, Tween.js și CSS3DRENDERER ca motoare de randare.
Folosind THREE.js, o scenă 3D este creată pentru a prezenta elementele tastaturii. Unele animații sunt ușor de integrat cu ajutorul funcționalității oferite de către framework-ul Tween.js. Alegerea modalității de randare este reprezentată de CSS3DRENDERER datorită faptului că acest tip de randare este rapid în cazul de față, funcționează pe browser-e de mobile, este de mici dimensiuni și se bazează în principal pe CSS.
Următoarele linii de JavaScript prezintă codul minimal de care este nevoie pentru a crea un THREE.CSS3DObject și pentru a inițializa scena:
function CreateButton(key, keyDescription) {
var keyElement = document.createElement(’div’);
keyElement.className = ’key’;
keyElement.id = key;
var letter = document.createElement(’div’);
letter.className = ’letter’;
letter.textContent = key;
keyElement.appendChild(letter);
var description = document.createElement(’div’);
description.className = ’description’;
description.innerHTML = keyDescription;
keyElement.appendChild(description);
var css3dObject = new THREE.
CSS3DObject(keyElement);
css3dObject.name = key;
return css3dObject;
}
function InitScene() {
var camera = new THREE.PerspectiveCamera(45,
window.innerWidth / window.innerHeight,
1, 1000);
camera.position.set(0, 0, 200);
var scene = new THREE.Scene();
var key = CreateButton(’w’, ’w key’);
key.position.set(20, 20, 20)
scene.add(key);
var css3dRenderer = new THREE.CSS3DRenderer();
css3dRenderer.setSize(window.innerWidth,
window.innerHeight);
document.getElementById(’scene’).
appendChild(css3dRenderer.domElement);
var trackballControls = new THREE.
TrackballControls(camera,
css3dRenderer.domElement);
trackballControls.minDistance = 50;
trackballControls.maxDistance = 1000;
}
Următoarele figuri ilustrează stările unei taste - normal, hover și tapped. Toate aceste stări se realizează folosind reguli CSS applicate elementelor de HTML, transpuse în THREE.CSS3DObjects și randate prin CSS3DRENDERER
Aceste clase CSS vor fi folosite în timpul interacțiunii dintre taste și Leap Motion Controller pentru a furniza feedback vizual pentru acțiunile utilizatorului.
Interacțiunea dintre tastatura virtuală și LeapMotion Controller se va realiza prin framework-ul LeapJS. Informația furnizată de framework va fi actualizată repetitiv, captând date cu o frecvență de 60 de cadre pe secundă.
Din cauză că vom avea nevoie de informații legate de poziția mâinii pe ecran și gesturile făcute de către utilizator, inițializarea controller-ului este descrisă prin următoarele linii de cod JavaScript:
var leapController = Leap.loop({
enableGestures: true })
.use('screenPosition');
leapController.connect();
Pentru a identifica ce fel de acțiune intenționează să facă utilizatorul, obiectul Frame furnizat de framework-ul LeapJS ar trebui luat în considerare.
Obiectul Frame furnizează informații importante captate în zona de detecție privind: id-ul său, rata de cadre curentă, degete, gesturi, mâini, pointables, tool-uri, spațiul de interacțiune și totodată un indicator pentru validitatea datelor furnizate. Un Frame este considerat a fi valid când conține date pentru toți itemii detectați. Pe lângă aceste atribute, obiectul Frame furnizează și un set de funcții, cum ar fi: dump() , finger(), hand(), pointable(), rotationAngle(), rotationAxis(), rotationMatrix(), scaleFactor(), tool(), toString(), translation(). Aceste funcții sunt foarte folositoare în procesul de interogare și procesare a datelor captate.
Frame Event Callbacks sunt folosite pentru a gestiona informațiile despre gesturile recunoscute și pentru a lua măsurile necesare. În primul rând, poziția mâinii este transpusă pe ecran. Acest lucru se face folosind event-ul de hand detection, după cum am arătat mai jos:
var leapController =
Leap.loop({ enableGestures: true },
{
hand: function (hand) {
var screenPosition = hand.
screenPosition(hand.palmPosition);
//... screen position related logic implementation
}
})
.use(’screenPosition’);
În funcție de poziția mâinii pe ecran, elementele de interes vor fi identificate - în acest caz, tasta care urmează a fi apăsată. Ca feedback pentru user, vor fi folosite clasele CSS prezentate în secțiunile de mai sus.
Starea tapped este transpusă folosind informații legate de gesturi din Frame Object-ul curent. Dacă există un gest keytap după interogarea colecției de gesturi, atunci tasta situată în acea poziție își va schimba statusul și va fi adăugată la o colecție pentru a crea un mesaj care va fi trimis mecanismului de chat.
Folosind ASP.NET MVC și SignalR, un mecanism de chat online în timp real a fost implementat. Combinând THREE.js cu CSS3DRENDERER, o tastatură virtuală 3D a fost creată folosind elemente HTML stilizate prin CSS. Interpretarea gesturilor userului ca formă de interacțiune cu tastatura s-a putut realiza prin integrarea LeapMotion Controller în aplicație folosind LeapJS și Leap-widgets.js. Rezultatul mixării acestor informații este o aplicație funcțională de web-chat în timp real, având ca input o tastatură interactivă care înțelege gesturile utilizatorului.
[1] http://www.evolutionoftheweb.com/
[2] https://en.wikipedia.org/wiki/History_of_the_World_Wide_Web
[3] https://en.wikipedia.org/wiki/Ajax_(programming)
[4] https://en.wikipedia.org/wiki/WebSocket
[5] http://www.asp.net/signalr
[6] http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr
[7] https://developer.leapmotion.com/documentation/cpp/devguide/Leap_Overview.html
[8] https://developer.leapmotion.com/documentation/javascript/devguide/Leap_Architecture.html
[9] http://leapmotion.github.io/leapjs-plugins/docs/#screen-position
[10] https://github.com/leapmotion/leapjs-widgets
[11] https://developer.leapmotion.com/documentation/javascript/devguide/Leap_Frames.html
[12] https://developer.leapmotion.com/documentation/javascript/devguide/Leap_Gestures.html
[14] http://threejs.org/examples/
[15] https://github.com/mrdoob/three.js/blob/master/examples/css3d_periodictable.html
de Leonard Pitu
de Adrian Ulici