Caso de éxito: HTML5 MathBoard

Introducción

Aplicación MathBoard

MathBoard en iPad, una aplicación de PalaSoftware, es una aplicación altamente pulida con muchas animaciones sutiles pero naturales, y un aspecto realista único. El objetivo era crear el puerto de mayor fidelidad de la aplicación para iPad en HTML5.

N2N-Apps es una empresa de desarrollo de software enfocada en crear aplicaciones web y para dispositivos móviles de última generación con tecnología HTML5. La empresa fue financiada en 2010 por Jeremy Chone, quien, después de 11 años de experiencia en ingeniería y administración de Netscape, Oracle y Adobe, decidió compartir su experiencia con empresas para compilar aplicaciones web y para dispositivos móviles de alta calidad. N2N-Apps se centra en la calidad y la velocidad de entrega.

Descargar MathBoard para Chrome Web Store Descargar MathBoard para Chrome Web Store (versión gratuita)

Requisitos

Los requisitos clave para este proyecto de portabilidad de HTML5 eran los siguientes:

  1. Puerto de alta fidelidad del aspecto y la interfaz de usuario de la aplicación original para iPad.
  2. Adáptate al factor de forma de destino (es decir, PC/Mac con teclado/mouse en comparación con pantalla táctil).
  3. Implementa el 100% de las funciones aplicables.
  4. Orientarse principalmente a navegadores HTML5
  5. Haz que la aplicación sea "sin servidores" para que se ejecute por completo en el cliente y se pueda alojar en un servidor estático o en una aplicación empaquetada de Google Chrome.
  6. Crear una versión 1.0 con todas las funciones, excepto el solucionador de problemas en menos de un mes

Arquitectura

Arquitectura

Teniendo en cuenta los requisitos, decidimos usar la siguiente arquitectura:

  1. HTML5: Debido a que no tenemos ningún requisito de compatibilidad con HTML4, decidimos usar HTML5 como base.
  2. jConsultar
  3. SnowUI: jQuery proporciona una gran API y una práctica recomendada para trabajar con el DOM; sin embargo, para la aplicación HTML5 MathBoard, necesitábamos un framework de estilo MVC o MVP para organizar todas las diferentes vistas. SnowUI es un marco de trabajo de MVC simple pero potente, además de jQuery. Proporciona un mecanismo de MVC centrado en DOM y una forma flexible de compilar componentes personalizados, a la vez que le brinda al desarrollador de aplicaciones la oportunidad de usar cualquier biblioteca de widgets o controles o código personalizado que considere óptimo.

Consideraciones de iPad a PC

Al transferir la aplicación a HTML5 para uso en PC, tuvimos que realizar varias modificaciones en el diseño y la interacción del usuario de la aplicación.

Orientación de la pantalla

El iPad MathBoard está orientado exclusivamente verticalmente, lo que no es óptimo para pantallas de PC, ya que, por lo general, se usan de forma horizontal. En consecuencia, reorganizamos el diseño de la IU y movimos el panel de configuración al lado derecho, en una vista deslizante (animada por transiciones CSS3).

Orientación de pantalla
Orientación de la pantalla en iPad frente a HTML5

Entrada: teclado/mouse o táctil

Otra diferencia clave entre la versión para iPad y la versión web es la interfaz de entrada. En el iPad, solo tienes la interfaz táctil. En la PC, debes tener en cuenta el mouse y el teclado.

Los controles de entrada de MathBoard en el iPad están bien definidos. Queríamos la misma representación de alta fidelidad en la interfaz web. La solución consistía en agregar compatibilidad con combinaciones de teclas y replicar los controles de la IU mediante el posicionamiento de CSS. El puerto para HTML5 era perfecto en píxeles:

Controles de la IU
Configuración de la versión en iPad frente a HTML5

Al igual que en la interfaz de iPad, permitimos que el usuario haga clic en las flechas izquierda y derecha para cambiar el valor de un control. La línea vertical también se puede arrastrar para cambiar rápidamente los valores. Se implementó un comportamiento de repetición para click y keydown a fin de que los usuarios puedan acelerar el cambio de valor cuando se presiona el mouse o el teclado.

Se agregó compatibilidad con la tecla TAB para moverse de un campo de entrada a otro, y las flechas ← y → cambian los valores.

Una función de la versión de iPad que no tenía mucho sentido para la interfaz de PC fue el tablero de dibujo. Si bien implementarla podría haber sido sofisticada, dibujar números con un mouse no es muy práctico. En cambio, decidimos dedicar más tiempo a pulir la interfaz del teclado que a implementar el tablero de dibujo.

Funciones de HTML5

En la versión web de MathBoard, usamos muchas funciones de HTML5:

Almacenamiento local

MathBoard permite a los usuarios guardar sus cuestionarios para volver a reproducirlos más tarde. HTML5 MathBoard implementa esta función con localStorage HTML5 y la interfaz de DAO de SnowUI.

localStorage fue una opción natural, ya que los datos eran bastante simples y no requerían indexación avanzada. Almacenamos todos los cuestionarios en un formato JSON que JSON.stringify como texto.

El DAO de SnowUI es un wrapper de interfaz CRUD simple que permite que la IU recupere datos sin tener que preocuparse por cómo se almacenan. La implementación del DAO se encarga de los detalles de almacenamiento.

En MathBoard, los requisitos de almacenamiento eran muy simples. Necesitamos almacenar solo la configuración del usuario y los datos del cuestionario. Ambos se almacenan como strings JSON en localStorage.

Por ejemplo, el DAO para el valor de configuración se veía de la siguiente manera:

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 vez que se registre este DAO para el settingValue, la IU podrá realizar la siguiente llamada sin necesidad de preocuparse por la lógica de almacenamiento:

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

Fuentes CSS3

MathBoard usa fuentes personalizadas. Gracias a la compatibilidad con fuentes CSS3, fue trivial incluir la fuente de tipo verdadero "Chalkduster" en nuestra aplicación:

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

Además, como esta fuente era la predeterminada para casi todo el texto de la aplicación, la establecimos como predeterminada para el cuerpo.

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

Gradiente de CSS3, sombra, esquinas redondeadas

Todos los gradientes, las sombras, la transparencia y las esquinas redondeadas se realizan con CSS3. Esto ahorraba mucho dinero en comparación con la forma tradicional de usar interfaces de usuario en .png.

También usamos propiedades avanzadas de CSS3 para personalizar la apariencia de la barra de desplazamiento y hacerla más sutil (consulta http://webkit.org/blog/363/styling-scrollbars/ para definir el estilo de las barras de desplazamiento en navegadores WebKit).

Transiciones CSS3

En el caso de HTML5 MathBoard, replicamos todas las animaciones del iPad e incluso agregamos una nueva para el panel deslizante derecho. Gracias a las transiciones CSS3, agregar animaciones era trivial y permitía el mejor rendimiento.

Teníamos tres animaciones principales en las aplicaciones.

1. El panel deslizante derecho

La primera animación se encuentra en el panel derecho (#rightPane), que se cierra cuando el usuario inicia un cuestionario nuevo y las diapositivas se abren cuando el usuario finaliza un cuestionario. Para crear este efecto, usamos la siguiente transición de CSS y la activamos a través de JavaScript. El estilo predeterminado del rightPane es abierto:

#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;
}

Cuando el usuario inicia un cuestionario, nuestra lógica de JavaScript mueve el panel:

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

Algunas notas sobre esta implementación:

  1. Dado que los tamaños de las aplicaciones son fijos, podríamos haber usado una clase de CSS ".close" y codificar la posición de cierre de la misma manera que codificamos la abierta.
  2. También podríamos haber usado "translate" de CSS, lo que habría sido más eficaz que animar la propiedad "left" del panel. Esto es especialmente cierto para los dispositivos móviles (como iOS) en los que las transformaciones 3D están aceleradas por hardware.
  3. El setTimeout no es estrictamente necesario en este caso, ya que la posición original se estableció antes de la modificación. Sin embargo, permite que el navegador haga que la animación sea más fluida, ya que muestra el cuestionario justo antes de deslizar el panel derecho.

2. Animación del cuadro de diálogo de configuración

Cuando el usuario hace clic en un parámetro de configuración de la derecha, el diálogo de configuración aparece en la parte inferior de la pantalla y se desplaza hacia abajo hasta la sección correspondiente.

Para lograr esto, tuvimos una transición similar al panel derecho. Lo único que tardó algo de tiempo fue resolver la inestabilidad en la primera aparición del diálogo. Para indicarle al navegador que almacene en caché la IU de diálogo, la mostramos una vez y nos desplazamos hasta ella. Al principio, intentamos con display: none. Este enfoque era incorrecto porque el navegador asumió que no es necesario mostrar el diálogo. La solución fue mostrar la configuración con un z-index: -1 en la inicialización, de modo que fuera invisible para el usuario, pero visible para el navegador.

3. Animación de mensaje correcto o incorrecto de cuestionario

La tercera animación es en realidad dos en uno. Cuando aparezca el mensaje de éxito o error, primero debes escalar a un punto determinado, esperar un poco y, por último, escalar aún más y desaparecer. Para ello, tenemos dos estilos de animación CSS3 y los organizamos a través de JavaScript en 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);

Etiqueta de audio

Cuando los usuarios responden un cuestionario, la aplicación emite un sonido de éxito o reprobación. La elección simple fue usar la etiqueta de audio y llamar a play() en ellos. Estos bits de audio se agregan a la página principal de la aplicación:

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

Conclusión

HTML5 realmente permite un nuevo tipo de aplicaciones web, de escritorio y de dispositivos móviles. CSS3 fue fundamental para personalizar la apariencia de la aplicación y que coincidiera estrechamente con la alta sofisticación de MathBoard para iPad, el almacenamiento HTML5 fue la opción perfecta para nuestra persistencia de datos y la simplicidad del audio HTML5 nos permitió replicar con gran precisión la aplicación para iPad.