Introdução
O MathBoard no iPad, um aplicativo do PalaSoftware, é altamente refinado, com muitas animações sutis, mas naturais, e uma aparência realista única. O objetivo era fazer a porta de maior fidelidade do aplicativo para iPad para HTML5.
A N2N-Apps é uma empresa de desenvolvimento de software com foco na criação de uma próxima geração de aplicativos da Web e para dispositivos móveis com tecnologia HTML5. A empresa foi fundada em 2010 por Jeremy Chone, que, após 11 anos de experiência em engenharia e gerenciamento da Netscape, Oracle e Adobe, decidiu compartilhar sua experiência com empresas para criar aplicativos da Web e para dispositivos móveis de alta qualidade. A N2N-Apps se concentra na qualidade e na velocidade de entrega.
Fazer o download do MathBoard para a Chrome Web Store Fazer o download do MathBoard para a Chrome Web Store (versão sem custo financeiro)
Requisitos
Os principais requisitos para esse projeto de portabilidade HTML5 eram os seguintes:
- Porta de alta fidelidade da aparência e interface do usuário do aplicativo original para iPad.
- Adapte ao formato desejado (por exemplo, PC/Mac com teclado/mouse vs. tela touch).
- Implementar 100% dos recursos aplicáveis.
- Segmentar principalmente navegadores HTML5.
- Tornar o aplicativo "sem servidor" para que ele seja executado inteiramente no cliente e possa ser hospedado em um servidor estático ou aplicativo empacotado do Google Chrome.
- Crie uma versão 1.0 com todos os recursos, mas o solucionador de problemas em menos de um mês.
Arquitetura
Dados os requisitos, decidimos ficar com a seguinte arquitetura:
- HTML5: como não temos nenhum requisito de suporte a HTML4, decidimos usar HTML5 como base.
- jQuery: Embora o HTML5 tenha muitos seletores avançados que tornam o jQuery tão incrível, decidimos continuar com o jQuery, pois ele nos ofereceu uma maneira muito robusta e madura de manipular o DOM e eventos relacionados. O jQuery também tem o benefício de ser mais centrado no DOM, o que tende a tornar o design e a implementação de um aplicativo mais próximos do HTML.
- SnowUI: o jQuery fornece uma excelente API e prática recomendada para trabalhar com o DOM. No entanto, para o aplicativo MathBoard HTML5, precisávamos de uma estrutura de estilo MVC ou MVP para orquestrar todas as diferentes visualizações. O SnowUI é uma estrutura MVC simples, porém avançada, baseada no jQuery. Ele oferece um mecanismo MVC centrado no DOM e uma maneira flexível de criar componentes personalizados, além de permitir que o desenvolvedor de aplicativos use qualquer biblioteca de widgets/controles ou código personalizado que considere ideal.
Considerações do iPad para o PC
Ao transferir o aplicativo para HTML5 para uso em PCs, tivemos que fazer várias modificações no design e na interação do usuário com o aplicativo.
Orientação da tela
O iPad MathBoard é exclusivamente vertical, o que não é ideal para telas de PC, já que geralmente são usadas na horizontal. Consequentemente, reorganizamos o design da interface e movemos o painel de configurações para o lado direito, em uma visualização deslizante (animada por transições CSS3).
Entrada: teclado/mouse x toque
Outra diferença importante entre a versão para iPad e a versão para Web é a interface de entrada. No iPad, você tem apenas a interface de toque. No PC, é preciso considerar o mouse e o teclado.
Os controles de entrada do MathBoard no iPad são altamente sofisticados. Queríamos a mesma representação de alta fidelidade na interface da Web. A solução foi adicionar suporte a atalhos de teclado e replicar controles de interface usando o posicionamento de CSS. A porta para HTML5 era perfeita como um pixel:
Assim como na interface do iPad, permitimos que o usuário clique na seta para a esquerda e para a direita para alterar o valor de um controle. A linha vertical também pode ser arrastada para
mudar rapidamente os valores. Um comportamento de repetição foi implementado para click
e keydown
para que os usuários possam acelerar a mudança de valor quando o
mouse ou o teclado for pressionado.
O suporte a TAB foi adicionado para mover de um campo de entrada para outro, e as setas ← e → percorrem os valores.
Um recurso da versão do iPad que não fazia muito sentido para a interface do PC era a prancheta. Embora pudesse ser complicado implementar esse método, desenhar números com um mouse não é muito prático. Em vez disso, decidimos passar mais tempo aprimorando a interface do teclado do que implementando a prancheta.
Recursos HTML5
Na versão para Web do MathBoard, usamos muitos recursos do HTML5:
Armazenamento local
O MathBoard permite que os usuários salvem o teste para reproduzi-lo mais tarde. O HTML5 MathBoard
implementa esse recurso usando localStorage
do HTML5, usando a
interface DAO do SnowUI.
localStorage
foi uma escolha natural, já que os dados eram simples
o suficiente e não exigiam indexação avançada. Armazenamos todos os testes
em um formato JSON e JSON.stringify
como texto.
O DAO da snowUI é um wrapper de interface CRUD simples que permite que a interface busque dados sem precisar se preocupar com a forma como eles são realmente armazenados. A implementação do DAO cuida das especificações do armazenamento.
No MathBoard, os requisitos de armazenamento eram muito simples. Precisávamos armazenar
apenas as configurações do usuário e os dados do teste. Ambos são armazenados como strings JSON em localStorage
.
Por exemplo, o DAO do valor da configuração tinha a seguinte aparência:
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();
})());
Depois que esse DAO é registrado para o settingValue
, a interface pode
fazer a seguinte chamada sem precisar se preocupar com a lógica do armazenamento:
var addition = snow.dm.get('settingValue', 'operator_addition');
addition.value = true; // to check the addition checkbox
snow.dm.save('settingValue', addition);
Fontes CSS3
O MathBoard usa fontes personalizadas. Graças ao suporte a fontes CSS3, foi fácil incluir a fonte do tipo real "Chalkduster" em nosso aplicativo:
@font-face {
font-family: Chalkduster;
src: url(Chalkduster.ttf);
}
E, como essa fonte era o padrão para quase todo o texto no aplicativo, também a tornamos padrão para o corpo.
body {
background: #333333;
font-family: Chalkduster;
color: #ffffff;
}
CSS3 gradiente, sombra, cantos arredondados
Todos os gradientes, sombras, transparências e cantos arredondados são feitos com CSS3. Isso foi uma grande economia de jogos em comparação com a maneira tradicional .png de criar interfaces de usuário.
Também usamos propriedades CSS3 avançadas para personalizar a aparência da barra de rolagem e torná-la mais sutil (consulte http://webkit.org/blog/363/styling-scrollbars/ para estilizar barras de rolagem em navegadores WebKit).
Transições CSS3
Para o MathBoard HTML5, replicamos todas as animações do iPad e adicionamos uma nova para o painel deslizante da direita. Graças às transições CSS3, adicionar animações era trivial e permitiu o melhor desempenho.
Tínhamos três animações principais nos aplicativos.
1) O painel deslizante para a direita
A primeira animação está no painel direito (#rightPane
), que é fechado
quando o usuário inicia um novo teste e quando ele termina.
Para criar esse efeito, usamos a transição CSS a seguir e a acionamos
via JavaScript. O estilo padrão do rightPane é aberto:
#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 o usuário inicia um teste, nossa lógica JavaScript move o painel:
var $rightPane = $('#rightPane');
var left = $rightPane.position().left - 400;
setTimeout(function() {
$rightPane.css('left', left + 'px');
}, 0);
Confira algumas observações sobre essa implementação:
- Como os tamanhos dos aplicativos são fixos, poderíamos ter usado uma classe CSS ".close" e fixado no código a posição fechada da mesma forma que fixamos o código aberto.
- Também poderíamos ter usado CSS "translate", que teria um desempenho melhor do que animar a propriedade "left" do painel. Isso vale principalmente para dispositivos móveis (como iOS), em que as transformações 3D são aceleradas por hardware.
- O
setTimeout
não é estritamente necessário nesse caso, porque a posição original foi definida antes da modificação. No entanto, ela permite que o navegador torne a animação mais suave exibindo o teste pouco antes de deslizar o painel rightPane para dentro.
2) Animação da caixa de diálogo de configurações
Quando o usuário clica em uma configuração à direita, a caixa de diálogo de configurações é exibida na parte de baixo da tela e rola até a seção adequada.
Para isso, fizemos uma transição semelhante para o painel direito. A única coisa que levou algum tempo foi resolver a instabilidade na primeira aparição da caixa de diálogo.
Para instruir o navegador a armazenar a interface da caixa de diálogo em cache, acabamos exibindo-a
uma vez e rolando até ela. Inicialmente, tentamos com display: none
.
Essa abordagem estava errada porque o navegador presumiu que a caixa de diálogo não precisa ser mostrada.
A solução era mostrar as configurações com um z-index: -1
na inicialização,
tornando-o invisível ao usuário, mas visível ao navegador.
3) Animação do teste concluído ou da mensagem incorreta
A terceira animação é, na verdade, duas em uma. Quando a mensagem de "sucesso" ou "incorreto" aparecer, primeiro dimensione até um ponto, aguarde um pouco e, por fim, aumente ainda mais e desapareça. Para isso, temos dois estilos de animação CSS3
e orquestramos isso via JavaScript em um 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 de áudio
Quando os usuários respondem a um teste, o aplicativo emite um som de sucesso ou falha.
A escolha simples era usar a tag de áudio e chamar play()
neles.
Estes bits de áudio são adicionados à página principal do aplicativo:
<audio id="audioCorrect" src="correct.mp3" preload="auto" autobuffer></audio>
<audio id="audioWrong" src="wrong.mp3" preload="auto" autobuffer></audio>
Conclusão
O HTML5 está realmente viabilizando uma nova safra de aplicativos da Web, para computadores e para dispositivos móveis. O CSS3 foi fundamental na personalização da aparência do aplicativo para corresponder à alta sofisticação do MathBoard para iPad. O armazenamento em HTML5 era perfeitamente adequada para a persistência de dados, e a simplicidade do áudio HTML5 nos permitiu replicar o aplicativo para iPad.