Studium przypadku – HTML5 MathBoard

Wprowadzenie

Aplikacja MathBoard

MathBoard na iPada to aplikacja PalaSoftware, która jest dopracowana pod każdym względem. Zawiera wiele subtelnych, ale naturalnych animacji oraz ma niepowtarzalny, realistyczny wygląd. Celem było przeniesienie aplikacji na iPada do formatu HTML5 z najlepszą możliwą jakością.

N2N-Apps to firma zajmująca się tworzeniem oprogramowania, która specjalizuje się w budowaniu aplikacji internetowych i mobilnych nowej generacji przy użyciu technologii HTML5. Firma została założona w 2010 r. przez Jeremy’ego Chone’a, który po 11 latach pracy jako inżynier i kierownik w firmach Netscape, Oracle i Adobe postanowił podzielić się swoim doświadczeniem z firmami, aby pomóc im w tworzeniu wysokiej jakości aplikacji internetowych i mobilnych. N2N-Apps koncentruje się na jakości i szybkości dostawy.

Pobierz MathBoard ze sklepu Chrome Web Store Pobierz MathBoard ze sklepu Chrome Web Store (wersja bezpłatna)

Wymagania

Najważniejsze wymagania dotyczące tego projektu portowania do HTML5:

  1. wiernie odwzorowany wygląd i interfejs oryginalnej aplikacji na iPada.
  2. Dostosować do docelowego formatu (np. komputer PC lub Mac z klawiaturą/myszką a ekran dotykowy).
  3. wdrożenie 100% odpowiednich funkcji.
  4. kierować je głównie na przeglądarki HTML5;
  5. Utwórz aplikację „bezserwerową”, która będzie działać wyłącznie na kliencie i będzie mogła być hostowana na serwerze statycznym lub w aplikacji pakietowej Google Chrome.
  6. W mniej niż miesiąc potwórz wersję 1.0 ze wszystkimi funkcjami, z wyjątkiem rozwiązywania problemów.

Architektura

Architektura

Biorąc pod uwagę te wymagania, zdecydowaliśmy się na tę architekturę:

  1. HTML5: ponieważ nie mamy żadnych wymagań dotyczących obsługi HTML4, zdecydowaliśmy się na HTML5 jako podstawę.
  2. jQuery: mimo że HTML5 zawiera wiele zaawansowanych selektorów, które sprawiają, że jQuery jest tak świetne, zdecydowaliśmy się na to drugie, ponieważ oferuje ono bardzo niezawodny i dojrzały sposób manipulowania DOM i powiązanymi zdarzeniami. jQuery ma też tę zaletę, że jest bardziej zorientowane na DOM, co sprawia, że projektowanie i wdrażanie aplikacji jest bliższe HTML.
  3. SnowUI jQuery udostępnia świetne API i sprawdzone metody pracy z DOM, ale w przypadku aplikacji MathBoard w HTML5 potrzebowaliśmy frameworku w stylu MVC lub MVP, aby zsynchronizować wszystkie różne widoki. SnowUI to prosty, ale zaawansowany framework MVC oparty na jQuery. Udostępnia ono mechanizm MVC skoncentrowany na DOM oraz elastyczny sposób tworzenia komponentów niestandardowych, jednocześnie dając deweloperowi aplikacji możliwość korzystania z dowolnej biblioteki widżetów lub elementów sterujących albo kodu niestandardowego, który uzna za optymalny.

Przesyłanie danych z iPada na komputer

Podczas przenoszenia aplikacji na HTML5 na potrzeby komputerów PC musieliśmy wprowadzić kilka zmian w jej wyglądzie i interakcji z użytkownikiem.

Orientacja ekranu

MathBoard na iPadzie jest przeznaczony wyłącznie do użytku w orientacji pionowej, co nie było optymalnym rozwiązaniem w przypadku wyświetlaczy PC, które są zazwyczaj używane w orientacji poziomej. W związku z tym zreorganizowaliśmy interfejs użytkownika i przesunęliśmy panel ustawień na prawą stronę, w widoku przesuwanym (animowanym przez przejścia CSS3).

Orientacja ekranu
Orientacja ekranu iPada a HTML5

Wpisywanie: klawiatura/mysz a dotykowa

Kolejną ważną różnicą między wersją na iPada a wersją internetową jest interfejs wprowadzania. Na iPadzie masz tylko interfejs dotykowy, a na komputerze musisz wziąć pod uwagę zarówno mysz, jak i klawiaturę.

Elementy sterujące w MathBoard na iPadzie są bardzo dopracowane. Chcieliśmy uzyskać tę samą wysoką jakość w interfejsie internetowym. Rozwiązaniem było dodanie obsługi skrótów klawiszowych i powtarzanie elementów interfejsu za pomocą pozycjonowania CSS. Przeniesienie do HTML5 było idealne do piksela:

Elementy sterujące w interfejsie
Ustawienia wersji na iPada i HTML5

Podobnie jak w interfejsie na iPadzie, użytkownik może kliknąć strzałkę w lewo lub w prawo, aby zmienić wartość elementu sterującego. Linie pionowe można też przeciągać, aby szybko zmieniać wartości. W przypadku elementów click i keydown wprowadziliśmy działanie powtarzalne, aby użytkownicy mogli przyspieszyć zmianę wartości po naciśnięciu myszy lub klawiatury.

Dodano obsługę klawisza TAB, aby przechodzić z jednego pola wejściowego do drugiego, oraz strzałek ← i →, aby przełączać wartości.

Jedna z funkcji w wersji na iPada, która nie miała większego sensu w przypadku interfejsu na PC, to tablica do rysowania. Chociaż implementacja tego rozwiązania mogłaby być ciekawa, rysowanie cyfr za pomocą myszy nie jest zbyt praktyczne. Zamiast tego postanowiliśmy poświęcić więcej czasu na dopracowanie interfejsu klawiatury niż na wdrożenie tablicy do rysowania.

Funkcje HTML5

W wersji internetowej MathBoard używamy wielu funkcji HTML5:

Lokalna pamięć masowa

MathBoard umożliwia użytkownikom zapisywanie quizów, aby można było je później odtworzyć. HTML5 MathBoard wdraża tę funkcję za pomocą HTML5 localStorage za pomocą interfejsu SnowUI DAO.

localStorage był naturalnym wyborem, ponieważ dane były dość proste i nie wymagały zaawansowanego indeksowania. Wszystkie quizy przechowujemy w jednym formacie JSON, który JSON.stringify jako tekst.

Interfejs DAO usługi snowUI to prosty interfejs CRUD, który umożliwia pobieranie danych bez konieczności martwienia się o sposób ich przechowywania. Implementacja DAO zajmuje się szczegółami przechowywania.

W przypadku MathBoard wymagania dotyczące pamięci były bardzo proste. Musieliśmy przechowywać tylko ustawienia użytkownika i dane quizu. Oba są przechowywane jako ciągi znaków JSON w localStorage.

Na przykład DAO wartości ustawienia wyglądało tak:

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();
})());

Gdy ten DAO zostanie zarejestrowany w przypadku settingValue, interfejs użytkownika może wykonać to wywołanie bez konieczności martwienia się logiką sklepu:

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

czcionki CSS3,

MathBoard używa czcionek niestandardowych. Dzięki obsłudze czcionek w CSS3 można było bez problemu uwzględnić w naszej aplikacji czcionkę TrueType „Chalkduster”:

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

Ponieważ ta czcionka była domyślną dla prawie całego tekstu w aplikacji, uczyniliśmy ją domyślną dla tekstu głównego.

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

CSS3 gradient, cień, zaokrąglone rogi

Wszystkie przejścia, cienie, przezroczystości i zaokrąglone rogi są tworzone za pomocą CSS3. To było prawdziwe zbawienie w porównaniu z tradycyjnym tworzeniem interfejsów w formacie .png.

Użyliśmy też zaawansowanych właściwości CSS3, aby dostosować wygląd i działanie suwaka, tak aby był bardziej subtelny (aby dostosować suwaki w przeglądarkach WebKit, zobacz http://webkit.org/blog/363/styling-scrollbars/).

Przejścia CSS3

W przypadku MathBoarda w HTML5 odtworzyliśmy wszystkie animacje z iPada, a nawet dodaliśmy nową dla przesuwanego panelu po prawej stronie. Dzięki przejściom CSS3 dodawanie animacji było proste i pozwalało uzyskać najlepszą wydajność.

W aplikacjach były 3 główne animacje.

1) przesuwany panel po prawej stronie,

Pierwsza animacja znajduje się w panelu po prawej stronie (#rightPane). Gdy użytkownik rozpoczyna nowy quiz, animacja przesuwa się w dół, a gdy kończy quiz, przesuwa się w górę. Aby uzyskać ten efekt, użyliśmy tego przejścia CSS i uaktywnienia go za pomocą JavaScriptu. Domyślny styl prawego panelu:

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

Gdy użytkownik rozpoczyna quiz, logika JavaScripta przenosi panel:

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

Kilka uwag na temat tej implementacji:

  1. Ponieważ rozmiary aplikacji są stałe, mogliśmy użyć klasy CSS „.close” i zakodować pozycję zamknięcia w taki sam sposób, w jaki zakodowaliśmy pozycję otwarcia.
  2. Mogliśmy też użyć funkcji CSS „translate”, która byłaby wydajniejsza niż animacja właściwości „left” w panelu. Jest to szczególnie ważne w przypadku urządzeń mobilnych (np. iOS), na których transformacje 3D są przyspieszane sprzętowo.
  3. W tym przypadku element setTimeout nie jest w zasadzie konieczny, ponieważ pierwotna pozycja została ustawiona przed wprowadzeniem modyfikacji. Pozwala jednak przeglądarce płynniej wyświetlić animację, wyświetlając quiz tuż przed przesunięciem panelu na prawo.

2) Animacja okna ustawień

Gdy użytkownik kliknie ustawienie po prawej stronie, na dole ekranu pojawi się okno ustawień, które przewinie się do odpowiedniej sekcji.

Aby to osiągnąć, wprowadziliśmy podobny panel po prawej stronie. Jedynym problemem, który wymagał trochę czasu, było wyeliminowanie zacięć podczas pierwszego wyświetlenia dialogu. Aby przekazać przeglądarce instrukcje dotyczące zapisania w pamięci podręcznej interfejsu okna, wyświetliliśmy je raz i przewinęliśmy do niego. Najpierw spróbowaliśmy z display: none. To podejście było nieprawidłowe, ponieważ przeglądarka założyła, że okno dialogowe nie musi być wyświetlane. Rozwiązaniem było wyświetlenie ustawień za pomocą z-index: -1 podczas inicjalizacji, dzięki czemu są one niewidoczne dla użytkownika, ale widoczne dla przeglądarki.

3) Animacja dotycząca prawidłowej odpowiedzi na quiz lub nieprawidłowej odpowiedzi

Trzecia animacja to tak naprawdę 2 animacje w jednej. Gdy pojawi się komunikat „success” (sukces) lub „incorrect” (nieprawidłowy), najpierw powiększ obraz, odczekaj chwilę, a na koniec powiększ obraz jeszcze bardziej i zniknij. W tym celu mamy 2 style animacji CSS3, które można sterować za pomocą kodu JavaScript w ramach zdarzenia 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

Gdy użytkownicy odpowiadają na pytania quizu, aplikacja odtwarza dźwięk sukcesu lub porażki. Najprostszym rozwiązaniem było użycie tagu audio i wywołanie funkcji play(). Na głównej stronie aplikacji są dodawane te elementy dźwiękowe:

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

Podsumowanie

HTML5 umożliwia tworzenie nowych aplikacji internetowych, komputerowych i mobilnych. Dzięki CSS3 udało się dostosować wygląd i działanie aplikacji, aby jak najlepiej odpowiadały zaawansowanej funkcjonalności aplikacji MathBoard na iPada. Pamięć HTML5 idealnie nadaje się do przechowywania danych, a prostota dźwięku w HTML5 pozwoliła nam wiernie odtworzyć aplikację na iPada.