個案研究 - HTML5 MathBoard

Jeremy Chone
Jeremy Chone

簡介

MathBoard 應用程式

MathBoard on iPadPalaSoftware 應用程式,是一款經過精心設計的應用程式,內含許多細微但自然的動畫,以及獨特的逼真外觀和感受。目標是將 iPad 應用程式以最高保真度移植至 HTML5。

N2N-Apps 是一家軟體開發公司,專注於運用 HTML5 技術建構新一代的網頁和行動應用程式。該公司在 2010 年獲得 Jeremy Chone 的投資,他曾在 Netscape、Oracle 和 Adobe 累積 11 年的工程和管理經驗,並決定將專業知識分享給企業,以便建構高品質的網頁和行動應用程式。N2N-Apps 著重於品質和提交速度。

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

需求條件

這項 HTML5 移植專案的主要要求如下:

  1. 原始 iPad 應用程式外觀與使用者介面的高保真移植版本。
  2. 適應目標板型規格 (例如電腦/Mac 搭配鍵盤/滑鼠,而非觸控螢幕)。
  3. 實作所有適用功能。
  4. 主要鎖定 HTML5 瀏覽器。
  5. 讓應用程式「無伺服器」,讓應用程式完全在用戶端上執行,並可託管於靜態伺服器或 Google Chrome 封裝應用程式。
  6. 在不到一個月的時間內,製作出 1.0 版,其中包含所有功能 (問題解決工具除外)。

架構

架構

根據需求,我們決定採用下列架構:

  1. HTML5:由於我們沒有任何 HTML4 支援需求,因此決定以 HTML5 做為基礎。
  2. jQuery:雖然 HTML5 有許多進階選取器,讓 jQuery 如此出色,但我們還是決定繼續使用 jQuery,因為它提供了非常可靠且成熟的方法來操作 DOM 和相關事件。jQuery 也有著以 DOM 為中心的優點,這會讓應用程式的設計和實作更貼近 HTML。
  3. SnowUI:jQuery 提供優質的 API 和最佳做法,可用於處理 DOM,不過,對於 HTML5 MathBoard 應用程式,我們需要 MVC 或 MVP 樣式的架構,才能協調所有不同的檢視畫面。SnowUI 是 jQuery 之上的簡單且強大的 MVC 架構。它提供以 DOM 為中心的 MVC 機制,以及建構自訂元件的彈性方式,同時讓應用程式開發人員有機會使用任何視窗小工具/控制項程式庫或自訂程式碼。

從 iPad 傳輸至電腦的考量因素

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

螢幕方向

iPad MathBoard 是專為垂直方向設計,但 PC 螢幕通常是橫向使用,因此不太適合。因此,我們重新整理了 UI 設計,並將設定面板移至右側的滑動檢視畫面 (使用 CSS3 轉場效果的動畫)。

螢幕方向
iPad 與 HTML5 螢幕方向

輸入方式:鍵盤/滑鼠與觸控

iPad 版和網頁版的另一個主要差異是輸入介面。在 iPad 上,您只有觸控介面,在電腦上,您需要考慮滑鼠和鍵盤。

iPad 上的 MathBoard 輸入控制項經過精心設計,我們希望在網頁介面中呈現相同的高保真度。解決方案是新增支援鍵盤快速鍵,並使用 CSS 定位複製 UI 控制項。轉換為 HTML5 的結果非常完美:

UI 控制項
iPad 與 HTML5 版本設定

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

新增了 TAB 鍵支援功能,可從一個輸入欄位移動到另一個輸入欄位,並透過 ← 和 → 箭頭循環瀏覽值。

在 iPad 版本中,繪圖板是一項對電腦介面來說不太實用的功能。雖然實作這項功能可能很有趣,但使用滑鼠繪製數字並不實用。相反地,我們決定將更多時間用於改善鍵盤介面,而非實作繪圖板。

HTML5 功能

在 MathBoard 的網頁版中,我們使用了許多 HTML5 功能:

本機儲存空間

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

localStorage 是自然的選擇,因為資料相當簡單,不需要進階索引。我們會將所有測驗儲存在一個 JSON 格式中,並以文字形式 JSON.stringify

snowUI DAO 是簡單的 CRUD 介面包裝函式,可讓 UI 擷取資料,而無須擔心資料的實際儲存方式。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();
})());

這個 DAO 註冊至 settingValue 後,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」TrueType 字型納入應用程式中非常簡單:

@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」屬性設定動畫更有效率。這點對行動裝置 (例如 iOS) 尤其重要,因為 3D 轉換會進行硬體加速。
  3. 在這種情況下,setTimeout 並非絕對必要,因為原始位置是在修改前設定的。不過,這樣做可讓瀏覽器在滑動右側窗格前顯示測驗,讓動畫更流暢。

2.) 設定對話方塊動畫

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

為達成這項目標,我們在右側窗格中採用類似的轉換效果。唯一需要花點時間解決的問題,是解決對話方塊首次顯示時的卡頓情形。為了指示瀏覽器快取對話方塊 UI,我們最終會顯示對話方塊 UI,並捲動至該畫面。我們一開始嘗試使用 display: none。由於瀏覽器會假設對話方塊不需要顯示,因此這個做法是錯誤的。解決方法是在初始化時使用 z-index: -1 顯示設定,讓使用者看不到,但瀏覽器可以看到。

3.) 測驗成功或錯誤訊息動畫

第三個動畫其實是兩個動畫合而為一。當畫面顯示「成功」或「不正確」訊息時,請先縮放至某個點,稍待片刻,然後再縮放至更大的尺寸,然後消失。為此,我們有兩種 CSS3 動畫樣式,並透過 JavaScript 在 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);

音訊標記

使用者回答測驗時,應用程式會發出成功或失敗的音效。簡單的做法是使用音訊標記,並呼叫 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 應用程式。