個案研究 - HTML5 MathBoard

Jeremy Chone
Jeremy Chone

簡介

MathBoard 應用程式

iPad 上的 MathBoardPalaSoftware 應用程式。這個應用程式極為精美,具有許多細微卻自然的動畫,以及獨特的真實外觀和風格。目標是將 iPad 應用程式的最高擬真度傳輸至 HTML5。

N2N-Apps 是一間軟體開發公司,專注於使用 HTML5 技術建構新一代的網頁和行動應用程式。該公司在 2010 年獲得 Jeremy Chone 資助,他在 Netscape、Oracle 和 Adobe 累積了 11 年的工程與管理經驗後,決定與企業分享自身專業知識,建構優質的網頁和行動應用程式。N2N-應用程式著重在推送的品質和速度

下載 Chrome 線上應用程式商店的 MathBoard 下載 Chrome 線上應用程式商店的 MathBoard (免費版)

需求條件

這個 HTML5 攜碼轉移專案的重要需求條件如下:

  1. 原始 iPad 應用程式的外觀與風格以及使用者介面的高保真度。
  2. 根據目標板型規格進行調整 (例如配備鍵盤/滑鼠或觸控螢幕的 PC/Mac)。
  3. 完全導入適用功能。
  4. 主要指定 HTML5 瀏覽器。
  5. 將應用程式設為「無伺服器」,讓應用程式完全在用戶端上執行,且可能由靜態伺服器或 Google Chrome 封裝應用程式代管。
  6. 不到一個月的時間,就能製作包含所有功能但問題解題工具的 1.0 版。

架構

架構

基於這些需求,我們決定繼續採用以下架構:

  1. HTML5:由於我們沒有任何支援 HTML4 的要求,因此決定以 HTML5 為基礎。
  2. Android
  3. SnowUI:jQuery 提供了極佳的 API 和最佳做法來使用 DOM,但是對於 HTML5 MathBoard 應用程式,我們需要 MVC 或 MVP 樣式架構來自動化調度管理所有不同的檢視畫面。SnowUI 是簡單但功能強大的 MVC 架構,以 jQuery 為建構基礎。它提供以 DOM 為主的 MVC 機制,以及靈活的建構自訂元件方式,同時讓應用程式開發人員有機會使用任何認為最佳的小工具/控制項程式庫或自訂程式碼。

從 iPad 到 PC 的注意事項

將應用程式移植至 HTML5 以供電腦使用時,我們必須對應用程式的設計和使用者互動方式進行多項修改。

螢幕方向

iPad MathBoard 完全採用垂直方向,這種螢幕通常以水平方向使用,因此不適合電腦螢幕。因此,我們重新編排了 UI 設計,並將設定面板移至右側,並移動到滑動檢視畫面 (以 CSS3 轉場效果建立動畫)。

螢幕方向
iPad 與 HTML5 的螢幕方向比較

輸入:鍵盤/滑鼠與觸控

iPad 和網頁版的另一個主要差異在於輸入介面。在 iPad 上只有觸控介面,因此在電腦上需要同時考量滑鼠和鍵盤。

iPad 上的 MathBoard 輸入控制項高度精美。我們希望網頁介面中 能呈現相同的高保真度這項解決方案加入了對鍵盤快速鍵的支援,以及使用 CSS 定位複製 UI 控制項。上傳至 HTML5 的連接埠是完美的像素:

UI 控制項
iPad 與 HTML5 版本設定

與 iPad 介面一樣,我們允許使用者點選左右箭頭來變更控制項的值。您也可以拖曳垂直線,快速變更值。實作 clickkeydown 的重複行為,讓使用者可以在按下滑鼠或鍵盤時加速變更值。

新增 TAB 支援以從一個輸入欄位移至另一個輸入欄位,← 和 → 箭頭可循環切換值。

iPad 版本的一項功能,在電腦介面上並沒什麼意義,就是繪圖板。儘管使用滑鼠繪製數字可能很實際,但使用滑鼠繪製數字並不實際。相反地,我們決定比實作繪圖板需要更多時間來潤飾鍵盤介面。

HTML5 功能

MathBoard 的 Web 版本中有許多 HTML5 功能:

本機儲存空間

使用者可以透過 MathBoard 儲存測驗,以便日後重播。HTML5 MathBoard 使用 HTML5 localStorage 搭配 SnowUI DAO 介面實作這項功能。

非常適合使用 localStorage,因為資料相當簡單,也不需要進階索引建立功能。我們會以 JSON 格式儲存所有測驗,並以 JSON.stringify 做為文字。

SnowUI DAO 是一種簡單的 CRUD 介麵包裝函式,可讓使用者介面擷取資料,而無需擔心資料實際儲存方式。DAO 實作會負責處理儲存細節。

MathBoard 的儲存空間需求非常簡單。我們只需儲存使用者設定和測驗資料。兩者都以 JSON 字串形式儲存在 localStorage 中。

舉例來說,設定值的 DAO 如下所示:

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

settingValue 註冊這個 DAO 後,UI 就可以進行下列呼叫,而不必擔心儲存邏輯:

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

CSS3 字型

MathBoard 使用自訂字型。多虧支援 CSS3,在應用程式中加入「Chalkduster」真實類型字型十分簡單:

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

此外,由於這個字型是應用程式中幾乎所有文字的預設字型,因此我們將其設為內文的預設字型。

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

CSS3 漸層、陰影、圓角

所有漸層、陰影、透明度和圓角都是透過 CSS3 完成。 相較於傳統的 .png 操作使用者介面,這項功能可帶來真正的遊戲節省體驗。

我們也使用進階 CSS3 屬性自訂捲軸的外觀和風格,使其更精細 (如需 WebKit 瀏覽器的樣式捲軸樣式,請參閱 http://webkit.org/blog/363/styling-scrollbars/)。

CSS3 轉場效果

對於 HTML5 MathBoard,我們複製了所有 iPad 的動畫,甚至為滑動右側面板新增動畫。多虧 CSS3 轉場效果 加入動畫相當麻煩,而且可以取得最佳成效

我們在應用程式中 有三個主要的動畫

1.) 右側滑動的窗格

第一個動畫在右側窗格 (#rightPane) 上,當使用者開始新測驗,以及使用者結束測驗時開啟的投影片時會關閉。為建立這種效果,我們使用下列 CSS 轉換作業,並透過 JavaScript 觸發轉換。右窗格的預設樣式為開啟狀態:

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

使用者開始測驗時,我們的 JavaScript 邏輯會移動面板:

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

此實作的注意事項:

  1. 由於應用程式大小固定,我們可以使用 CSS 類別「.close」並採用硬式編碼的方式,對關閉位置進行硬式編碼。
  2. 我們也可以使用 CSS「translate」,這會比窗格的「left」屬性獲得更出色的成效。這對 3D 轉換執行硬體加速的行動裝置 (例如 iOS) 來說尤其重要。
  3. 在本例中,setTimeout 並非必要,因為原始位置是在修改前設定。但可以讓瀏覽器在向右滑動正確的窗格前顯示測驗,讓動畫更流暢。

2.) 設定對話方塊動畫

當使用者點選右側的設定時,設定對話方塊會從畫面底部顯示,並向下捲動至適當的部分。

為此,我們在右側窗格進行了類似的轉換。唯一會花費時間解決對話方塊首次出現時的波動。為指示瀏覽器快取對話方塊 UI,我們最終會顯示該對話方塊並捲動至頁面。我們一開始先嘗試使用 display: none。這個方法有誤,因為瀏覽器假設不需要顯示對話方塊。該解決方法是在初始化時使用 z-index: -1 顯示設定,讓使用者看不見設定,但瀏覽器也能看到這些設定。

3.) 測驗成功或不正確的訊息動畫

第三個動畫實際上是一次。出現「成功」或「錯誤」訊息時,首先縮放到一個點,等待些許一點,最後再擴大規模並消失。我們針對 webkitTransitionEnd 事件提供兩種 CSS3 動畫樣式,並透過 JavaScript 自動化調度管理。

.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);

音訊標記

使用者回答測驗時,應用程式會發出成功或失敗的音效。最簡單的選擇是使用音訊標記,並對其呼叫 play()。這些音訊位元會新增至應用程式的主頁:

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

結論

HTML5 真正實現了全新型態的網頁、電腦和行動應用程式。 CSS3 能夠協助我們自訂應用程式的外觀和風格,以便與 iPad 版 MathBoard 的高度複雜性非常相近。HTML5 儲存空間非常適合我們的資料持續性,再加上簡單易用的 HTML5 音訊,讓我們能夠精準複製 iPad 應用程式。