Case study: MathBoard HTML5

Jeremy Chone
Jeremy Chone

Introduzione

Applicazione MathBoard

MathBoard su iPad, un'applicazione PalaSoftware, è un'applicazione molto raffinata con molte animazioni sottili ma naturali e un aspetto realistico unico. L'obiettivo era realizzare la porta con la massima fedeltà dell'applicazione per iPad in HTML5.

N2N-Apps è una società di sviluppo software che si occupa della creazione di applicazioni web e mobile di nuova generazione con tecnologia HTML5. La società è stata fondata nel 2010 da Jeremy Chone che, dopo 11 anni di esperienza in ambito di ingegneria e gestione presso Netscape, Oracle e Adobe, ha deciso di condividere la sua esperienza con le aziende per creare applicazioni web e mobile di alta qualità. N2N-Apps si concentra sulla qualità e sulla velocità di pubblicazione.

Scarica MathBoard dal Chrome Web Store Scarica MathBoard dal Chrome Web Store (versione senza costi)

Requisiti

I requisiti chiave per questo progetto di porting in HTML5 erano i seguenti:

  1. Porta ad alta fedeltà dell'aspetto e dell'interfaccia utente dell'applicazione per iPad originale.
  2. Adattarsi al fattore di forma target (ad es. PC/Mac con tastiera/mouse o touchscreen).
  3. Implementare il 100% delle funzionalità applicabili.
  4. Scegli come target principalmente i browser HTML5.
  5. Rendi l'applicazione "serverless" in modo che venga eseguita interamente sul client e possa essere ospitata su un server statico o un'applicazione pacchettizzata di Google Chrome.
  6. Crea una versione 1.0 con tutte le funzionalità, tranne la risoluzione dei problemi, in meno di un mese.

Architettura

Architettura

Dati i requisiti, abbiamo deciso di adottare la seguente architettura:

  1. HTML5: poiché non abbiamo requisiti di supporto per HTML4, abbiamo deciso di utilizzare HTML5 come base.
  2. jQuery: anche se HTML5 include molti dei selettori avanzati che rendono jQuery così fantastico, abbiamo deciso di continuare a utilizzare jQuery perché ci ha fornito un modo molto affidabile e maturo per manipolare il DOM e gli eventi correlati. jQuery ha anche il vantaggio di essere più incentrato sul DOM, il che tende a rendere il design e l'implementazione di un'applicazione più simili a HTML.
  3. SnowUI: jQuery fornisce un'API e best practice eccellenti per lavorare con il DOM, tuttavia, per l'applicazione MathBoard HTML5 avevamo bisogno di un framework in stile MVC o MVP per orchestrare tutte le diverse visualizzazioni. SnowUI è un framework MVC semplice ma potente basato su jQuery. Fornisce un meccanismo MVC centrato sul DOM e un modo flessibile per creare componenti personalizzati, lasciando allo sviluppatore dell'applicazione la possibilità di utilizzare qualsiasi libreria di widget/controlli o codice personalizzato che ritiene ottimale.

Considerazioni relative al trasferimento da iPad a PC

Durante il porting dell'applicazione ad HTML5 per l'utilizzo su PC, abbiamo dovuto apportare diverse modifiche al design e all'interazione con l'utente dell'applicazione.

Orientamento dello schermo

MathBoard per iPad è orientata esclusivamente in verticale, il che non era ottimale per i display dei computer, in quanto in genere vengono utilizzati in orizzontale. Di conseguenza, abbiamo riorganizzato il design dell'interfaccia utente e spostato il riquadro delle impostazioni sul lato destro, in una vista scorrevole (animata da transizioni CSS3).

Orientamento schermo
Orientamento schermo iPad e HTML5

Input: tastiera/mouse o tocco

Un'altra differenza fondamentale tra la versione per iPad e quella web è l'interfaccia di inserimento. Su iPad hai solo l'interfaccia tocco, sul PC devi prendere in considerazione sia il mouse sia la tastiera.

I controlli di input di MathBoard su iPad sono molto raffinati. Volevamo la stessa rappresentazione ad alta fedeltà nell'interfaccia web. La soluzione è stata l'aggiunta del supporto per le scorciatoie da tastiera e la replica dei controlli dell'interfaccia utente utilizzando il posizionamento CSS. La porta su HTML5 è stata perfetta a livello di pixel:

Controlli UI
Impostazioni della versione per iPad e HTML5

Come nell'interfaccia dell'iPad, consentiamo all'utente di fare clic sulle frecce a sinistra e a destra per modificare il valore di un controllo. Puoi anche trascinare la linea verticale per modificare rapidamente i valori. È stato implementato un comportamento di ripetizione per click e keydown in modo che gli utenti possano accelerare la modifica del valore quando viene premuto il mouse o la tastiera.

È stato aggiunto il supporto del tasto TAB per passare da un campo di immissione all'altro e le frecce ← e → consentono di scorrere i valori.

Una funzionalità della versione per iPad che non aveva molto senso per l'interfaccia del PC era la lavagna. Sebbene sarebbe stato bello implementarlo, disegnare i numeri con un mouse non è molto pratico. Abbiamo invece deciso di dedicare più tempo alla perfezione dell'interfaccia della tastiera rispetto all'implementazione della lavagna.

Funzionalità HTML5

Nella versione web di MathBoard utilizziamo molte funzionalità HTML5:

Conservazione locale

MathBoard consente agli utenti di salvare i quiz per riprodurli in un secondo momento. MathBoard HTML5 implementa questa funzionalità utilizzando HTML5 localStorage e l'interfaccia DAO SnowUI.

localStorage è stata una scelta naturale, poiché i dati erano abbastanza semplici e non richiedevano l'indicizzazione avanzata. Archiviamo tutti i quiz in un formato JSON che JSON.stringify come testo.

La DAO snowUI è un semplice wrapper dell'interfaccia CRUD che consente all'interfaccia utente di recuperare i dati senza doversi preoccupare di come vengono effettivamente archiviati. L'implementazione del DAO si occupa dei dettagli di archiviazione.

In MathBoard, i requisiti di archiviazione erano molto semplici. Dovevamo memorizzare solo le impostazioni utente e i dati dei quiz. Entrambi sono stati archiviati come stringhe JSON in localStorage.

Ad esempio, il DAO per il valore dell'impostazione aveva il seguente aspetto:

snow.dm.registerDao('settingValue', (function() {

  var _settingValues = null;

  function SettingValueDao() {};

  // ------ DAO CRUD Interface ------ //
  // get
  SettingValueDao.prototype.get = function(objectType, id) {
    return $.extend({},getSettingValues()[id]);
  };

  // find, remove

  // save
  SettingValueDao.prototype.save = function(objectType, data) {
    var storeValue = getSettingValues('settingValue')[data.id];
    if (!storeValue) {
      storeValue = {};
      getSettingValues()[data.id] = storeValue;
    }

    $.extend(storeValue, data);
    saveSettingValues();
  };
  // ------ /DAO CRUD Interface ------ //

  function getSettingValues() {
    if (_settingValues == null) {
      var settingValuesString = localStorage.getItem('settingValues');
      if (settingValuesString) {
        _settingValues = JSON.parse(settingValuesString);
      } else{
        _settingValues = {};
      }
    }

    return _settingValues;
  }

  function saveSettingValues(){
    var settingValues = getSettingValues();
    if (settingValues != null) {
      localStorage.removeItem('settingValues');
      localStorage.setItem('settingValues', JSON.stringify(settingValues)); 
    }
  }

  return new SettingValueDao();
})());

Una volta registrato questo DAO per settingValue, l'interfaccia utente può effettuare la seguente chiamata senza doversi preoccupare della logica del negozio:

var addition = snow.dm.get('settingValue', 'operator_addition');
addition.value = true; // to check the addition checkbox
snow.dm.save('settingValue', addition);

Caratteri CSS3

MathBoard utilizza caratteri personalizzati. Grazie al supporto dei font CSS3, è stato facile includere il font True Type "Chalkduster" nella nostra applicazione:

@font-face {
  font-family: Chalkduster;
  src: url(Chalkduster.ttf);
}

Poiché questo carattere era predefinito per quasi tutto il testo dell'applicazione, lo abbiamo impostato come predefinito per il corpo.

body {
  background: #333333;
  font-family: Chalkduster;
  color: #ffffff;
}

Sfumatura, ombreggiatura, angoli arrotondati CSS3

Tutti i gradienti, le ombre, la trasparenza e gli angoli arrotondati vengono realizzati con CSS3. È stato un vero e proprio vantaggio rispetto al tradizionale metodo .png per creare interfacce utente.

Abbiamo anche utilizzato proprietà CSS3 avanzate per personalizzare l'aspetto della barra di scorrimento in modo da renderla meno evidente (consulta http://webkit.org/blog/363/styling-scrollbars/ per informazioni su come applicare stili alle barre di scorrimento sui browser WebKit).

Transizioni CSS3

Per MathBoard HTML5, abbiamo replicato tutte le animazioni dell'iPad e ne abbiamo persino aggiunta una nuova per il riquadro scorrevole a destra. Grazie alle transizioni CSS3, l'aggiunta di animazioni è stata semplice e ha consentito il rendimento migliore.

Le applicazioni avevano tre animazioni principali.

1.) Il riquadro scorrevole a destra

La prima animazione si trova nel riquadro a destra (#rightPane), che si chiude quando l'utente avvia un nuovo quiz e si apre quando l'utente termina un quiz. Per creare questo effetto, abbiamo utilizzato la seguente transizione CSS e l'abbiamo attivata tramite JavaScript. Lo stile predefinito di rightPane è aperto:

#rightPane {
  /* look and feel, and layout property */
  position: absolute;
  width: 370px;
  height: 598px;
  top: 28px;
  left: 720px; /* open */
  -webkit-transition: all .6s ease-in-out;
}

Quando l'utente avvia un quiz, la nostra logica JavaScript sposta il riquadro:

var $rightPane = $('#rightPane');
var left = $rightPane.position().left - 400;
setTimeout(function() {
  $rightPane.css('left', left + 'px');
}, 0);

Alcune note su questa implementazione:

  1. Dato che le dimensioni dell'applicazione sono fisse, avremmo potuto utilizzare una classe CSS ".close" e impostare la posizione di chiusura in modo hardcoded nello stesso modo in cui abbiamo impostato quella di apertura.
  2. Avremmo anche potuto utilizzare la proprietà CSS "translate", che avrebbe avuto un rendimento migliore rispetto all'animazione della proprietà "left" del riquadro. Questo vale soprattutto per i dispositivi mobili (come iOS) in cui le trasformazioni 3D sono accelerate dall'hardware.
  3. In questo caso, setTimeout non è strettamente necessario poiché la posizione originale è stata impostata prima della modifica. Tuttavia, consente al browser di rendere più fluida l'animazione mostrando il quiz appena prima di far scorrere il riquadro destro.

2.) Animazione della finestra di dialogo Impostazioni

Quando l'utente fa clic su un'impostazione a destra, la finestra di dialogo delle impostazioni viene visualizzata dalla parte inferiore dello schermo e scorre verso il basso fino alla sezione appropriata.

Per farlo, abbiamo adottato una transizione simile per il riquadro a destra. L'unica cosa che ha richiesto un po' di tempo è stata risolvere il problema di balbuzie alla prima apparizione della finestra di dialogo. Per indicare al browser di memorizzare nella cache l'interfaccia utente della finestra di dialogo, abbiamo finito per visualizzarla una volta e scorrerci fino in fondo. All'inizio abbiamo provato con display: none. Questo approccio era errato perché il browser presumeva che la finestra di dialogo non debba essere mostrata. La soluzione è stata visualizzare le impostazioni con un z-index: -1 all'inizializzazione, rendendole invisibili all'utente, ma visibili al browser.

3.) Animazione di messaggio di successo o errato del quiz

La terza animazione è in realtà due in una. Quando viene visualizzato il messaggio "Operazione riuscita" o "Incorretta", prima aumenta la scala fino a un punto, attendi un po' e infine aumenta ancora la scala e scompare. A questo scopo, abbiamo due stili di animazione CSS3 e li orchestriamo tramite JavaScript su un evento webkitTransitionEnd.

.quiz-result > div.anim1 {
  opacity: 0.8;
  -webkit-transform: scale(6,6);
}
.quiz-result > div.anim2{
  opacity: 0;
  -webkit-transform: scale(9,9);
}
setTimeout(function() {
  $msg.addClass("anim1");
  $msg.bind("webkitTransitionEnd", function(){
    if ($msg.hasClass("anim1")) {
      setTimeout(function() {
        $msg.removeClass("anim1");
        $msg.addClass("anim2");
      }, 300);
    } else {
      $msg.remove();
      displayNextItem();
      freezeInput = false;
    }
  });
}, 0);

Tag audio

Quando gli utenti rispondono a un quiz, l'applicazione emette un suono di conferma o di errore. La scelta più semplice è stata utilizzare il tag audio e chiamare play(). Questi bit audio vengono aggiunti alla pagina principale dell'applicazione:

<audio id="audioCorrect" src="correct.mp3" preload="auto" autobuffer></audio>
<audio id="audioWrong" src="wrong.mp3" preload="auto" autobuffer></audio>

Conclusione

HTML5 sta davvero consentendo una nuova generazione di applicazioni web, desktop e mobile. CSS3 è stato fondamentale per personalizzare l'aspetto dell'applicazione in modo da assomigliare molto all'alta sofisticazione di MathBoard per iPad, lo spazio di archiviazione HTML5 era ideale per la persistenza dei dati e la semplicità dell'audio HTML5 ci ha permesso di replicare fedelmente l'app per iPad.