Case study - MathBoard HTML5

Jeremy Chone
Jeremy Chone

Introduzione

Applicazione MathBoard

MathBoard su iPad, un'applicazione PalaSoftware, è un'applicazione molto curata con molte animazioni discrete ma naturali e un aspetto e un design realistici unici. L'obiettivo era eseguire la porta più fedele dell'applicazione per iPad a 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 finanziata nel 2010 da Jeremy Chone che, dopo 11 anni di esperienza 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 distribuzione.

Scarica MathBoard per il Chrome Web Store Scarica MathBoard per il Chrome Web Store (versione senza costi)

Requisiti

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

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

Architettura

Architettura

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

  1. HTML5: dal momento che non abbiamo requisiti di supporto HTML4, abbiamo deciso di usare HTML5 come base.
  2. jQuery: sebbene HTML5 abbia molti dei selettori avanzati che rendono jQuery davvero efficace, abbiamo deciso di continuare a usare jQuery in quanto ci ha offerto un modo molto solido e maturo per manipolare il DOM e gli eventi correlati. jQuery ha anche il vantaggio di essere più incentrato sul DOM, che tende a rendere la progettazione e l'implementazione di un'applicazione più vicina all'HTML.
  3. SnowUI: jQuery offre un'ottima API e best practice per lavorare con il DOM. Tuttavia, per l'applicazione HTML5 MathBoard 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 incentrato sul DOM e un modo flessibile per creare componenti personalizzati dando allo sviluppatore dell'applicazione l'opportunità di utilizzare qualsiasi libreria di widget/controlli o codice personalizzato che ritiene ottimale.

Considerazioni da iPad a PC

Durante il trasferimento dell'applicazione in HTML5 per PC, abbiamo dovuto apportare diverse modifiche al design e all'interazione utente.

Orientamento dello schermo

La MathBoard dell'iPad è orientata esclusivamente in verticale, il che non era ottimale per i display di PC, in quanto l'utilizzo era generalmente orizzontale. Di conseguenza, abbiamo riorganizzato il design dell'interfaccia utente e spostato il riquadro delle impostazioni sul lato destro, in una visualizzazione scorrevole (animata da transizioni CSS3).

Orientamento schermo
Orientamento dello schermo per iPad rispetto a HTML5

Input: tastiera/mouse o tocco

Un'altra differenza fondamentale tra la versione per iPad e il web è l'interfaccia di input. Sull'iPad hai solo l'interfaccia touch, sul PC devi tenere conto sia del mouse che della tastiera.

I controlli di input di MathBoard sull'iPad sono molto raffinati. Volevamo la stessa rappresentazione ad alta fedeltà nell'interfaccia web. La soluzione prevedeva l'aggiunta del supporto per le scorciatoie da tastiera e la replica dei controlli UI utilizzando il posizionamento CSS. La porta a HTML5 era perfetta in termini di pixel:

Controlli UI
Impostazioni versione iPad e HTML5

Come nell'interfaccia dell'iPad, all'utente è consentito fare clic sulla freccia sinistra e destra per modificare il valore di un controllo. Puoi anche trascinare la linea verticale per cambiare 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 premi il mouse o la tastiera.

È stato aggiunto il supporto del tasto Tab per spostarsi da un campo di immissione all'altro. Le frecce saranno e → scorrono da un campo all'altro.

Una funzionalità della versione per iPad che non aveva molto senso per l'interfaccia PC era il tavolo da disegno. Potrebbe essere una fantasia implementarla, ma disegnare numeri con il mouse non è molto pratica. Abbiamo deciso invece di dedicare più tempo a perfezionare l'interfaccia della tastiera, anziché implementare il disegno.

Funzionalità HTML5

Nella versione web di MathBoard, vengono utilizzate molte funzionalità HTML5:

Spazio di archiviazione locale

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

localStorage è stata una scelta naturale poiché i dati erano abbastanza semplici e non richiedevano un'indicizzazione avanzata. Memorizziamo tutti i quiz in un unico formato JSON che JSON.stringify sotto forma di testo.

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

In MathBoard, i requisiti di archiviazione erano molto semplici. Dovevamo archiviare solo le impostazioni utente e i dati dei quiz. Entrambe sono archiviate come stringhe JSON in localStorage.

Ad esempio, il DAO per il valore dell'impostazione era simile al seguente:

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 chiamata seguente senza doversi preoccupare della logica dell'archivio:

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 caratteri CSS3, è stato facile includere il carattere true type "Chalkduster" nella nostra applicazione:

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

Inoltre, poiché questo carattere era il valore predefinito per quasi tutto il testo nell'applicazione, lo abbiamo impostato come predefinito per il corpo.

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

Gradiente CSS3, ombra, angoli arrotondati

Tutti i gradienti, le ombre, la trasparenza e gli angoli arrotondati vengono eseguiti con CSS3. Si tratta di un vero e proprio risparmio di giochi rispetto al tradizionale metodo .png per le interfacce utente.

Abbiamo anche utilizzato proprietà CSS3 avanzate per personalizzare l'aspetto della barra di scorrimento e renderla più sottile (vedi http://webkit.org/blog/363/styling-scrollbars/ per applicare lo stile delle barre di scorrimento sui browser WebKit).

Transizioni CSS3

Per MathBoard HTML5, abbiamo replicato tutte le animazioni dell'iPad e abbiamo persino aggiunto una nuova animazione per il riquadro scorrevole destro. Grazie alle transizioni CSS3, l'aggiunta di animazioni era semplice e consentiva le migliori prestazioni.

Le applicazioni avevano tre animazioni principali.

1. Il riquadro scorrevole a destra

La prima animazione si trova nel riquadro di destra (#rightPane), che si chiude quando l'utente inizia un nuovo quiz e si apre quando l'utente termina il quiz. Per creare questo effetto, abbiamo utilizzato la seguente transizione CSS e l'abbiamo attivata tramite JavaScript. Lo stile predefinito dell'elemento destro è 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 come hardcoded la posizione di chiusura nello stesso modo in cui abbiamo impostato come hardcoded quella aperta.
  2. Avremmo potuto anche utilizzare la funzione CSS "translate", che avrebbe avuto un rendimento migliore rispetto all'animazione della proprietà "sinistra" del riquadro. Ciò è particolarmente vero per i dispositivi mobili (come iOS) in cui le trasformazioni 3D sono con accelerazione hardware.
  3. setTimeout non è strettamente necessario in questo caso poiché la posizione originale è stata impostata prima della modifica. Consente però al browser di rendere più fluida l'animazione visualizzando il quiz appena prima di inserire il cursore destro.

2. Animazione della finestra di dialogo delle impostazioni

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

Per farlo, abbiamo eseguito una transizione simile al riquadro di destra. L'unica cosa che ci è voluto un po' di tempo è stata quella di risolvere i problemi alla prima apparizione del dialogo. Per indicare al browser di memorizzare nella cache l'interfaccia utente della finestra di dialogo, abbiamo finito per visualizzarla una volta e scorrendo fino all'interfaccia. All'inizio, abbiamo provato con display: none. Questo approccio era errato perché il browser ha pensato che la finestra di dialogo non dovesse essere mostrata. La soluzione consisteva nel visualizzare le impostazioni con un z-index: -1 al momento dell'inizializzazione, rendendole invisibile all'utente ma visibile al browser.

3. Quiz riuscito o animazione del messaggio errata

La terza animazione è in realtà due in una. Quando viene visualizzato il messaggio "Operazione riuscita" o "Risposta errata", innanzitutto scala fino a un determinato punto, attendi un po' di tempo e infine scala ancora più in alto e scompare. Per questo motivo abbiamo due stili di animazione CSS3 che abbiamo orchestrato tramite JavaScript in 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 audio positivo o negativo. La scelta 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 dando il via a una nuova gamma di applicazioni web, desktop e mobile. CSS3 è stato fondamentale per personalizzare l'aspetto dell'applicazione in modo da rispecchiare fedelmente l'elevata sofisticazione di MathBoard per iPad, l'archiviazione in HTML5 era perfetta per la persistenza dei dati e la semplicità dell'audio HTML5 ci ha permesso di replicare da vicino l'app per iPad.