ケーススタディ - HTML5 MathBoard

はじめに

MathBoard アプリケーション

PalaSoftware アプリケーションである iPad 版 MathBoard は、微妙ながらも自然なアニメーションが多く、ユニークでリアルな外観を備えた非常に洗練されたアプリケーションです。目標は、iPad アプリケーションを HTML5 に最大限の忠実度で移植することでした。

N2N-Apps は、HTML5 技術を使った次世代のウェブ アプリケーションやモバイルアプリの構築に注力するソフトウェア開発企業です。2010 年に Jeremy Chone によって資金提供されました。Jeremy Chone は、Netscape、Oracle、Adobe で 11 年にわたるエンジニアリングと管理の経験を経て、高品質なウェブ アプリケーションとモバイル アプリケーションを構築するために、その専門知識を企業と共有することにしました。N2N-Apps は 配信の品質とスピードに重点を置いています

Chrome ウェブストア向け MathBoard をダウンロード Chrome ウェブストア向け MathBoard をダウンロード(無料版)

要件

この HTML5 移植プロジェクトの主な要件は次のとおりです。

  1. 当初の iPad アプリケーションのデザインとユーザー インターフェースに忠実度の高いポートを採用。
  2. 目的のフォーム ファクタに適応します(キーボード/マウスを備えた PC/Mac か、タッチ スクリーンかなど)。
  3. 該当する機能をすべて実装する。
  4. 主に HTML5 ブラウザをターゲットに設定します。
  5. アプリケーションを「サーバーレス」にして、アプリケーションを完全にクライアント上で実行し、静的サーバーまたは Google Chrome のパッケージ化されたアプリケーションでホストできるようにします。
  6. すべての機能を備えた 1.0 バージョンを 1 か月未満で作成できます。

アーキテクチャ

アーキテクチャ

要件を考慮して、次のアーキテクチャを採用することにしました。

  1. HTML5: HTML4 のサポート要件はないため、HTML5 をベースとすることにしました。
  2. jQuery: HTML5 には jQuery を優れたものにする高度なセレクタが数多く備わっていますが、DOM と関連イベントを操作する非常に堅牢で成熟した方法を提供できたことから、私たちは jQuery を使用することに決めました。また、jQuery には DOM 中心であるというメリットがあり、アプリケーションの設計と実装を HTML に近づける傾向があります。
  3. SnowUI: jQuery は DOM を操作するための優れた API とベスト プラクティスを提供しますが、HTML5 MathBoard アプリケーションには、すべての異なるビューをオーケストレートするために MVC または MVP スタイルのフレームワークが必要でした。SnowUI は、jQuery をベースとするシンプルかつ強力な MVC フレームワークです。DOM 中心の MVC メカニズムと、カスタム コンポーネントを柔軟に構築できる手段を提供します。これにより、アプリケーション デベロッパーは、最適だと判断したウィジェットやコントロールのライブラリやカスタムコードを使用できます。

iPad から PC への移行に関する考慮事項

アプリケーションを PC 用の HTML5 に移植する際、アプリケーションのデザインとユーザー操作にいくつかの変更を加える必要がありました。

画面の向き

iPad MathBoard は垂直方向にのみ対応しており、通常は横向きで使用されるため、PC のディスプレイには最適ではありませんでした。そこで UI デザインを再編成し、設定パネルをスライドビュー(CSS3 の遷移によりアニメーション化)で右側に移動しました。

画面の向き
iPad と HTML5 の画面向き

入力: キーボード/マウスとタップ

iPad とウェブ版のもう一つの主な違いは、入力インターフェースです。iPad ではタッチ インターフェースしかありませんが、PC ではマウスとキーボードの両方を考慮する必要があります。

iPad の MathBoard 入力コントロールは非常に洗練されています。ウェブ インターフェースでも同じ高忠実度表現が必要でした。そこで、キーボード ショートカットのサポートを追加し、CSS の位置指定を使用して UI コントロールを複製しました。HTML5 への移植は完璧でした。

UI コントロール
iPad と HTML5 のバージョン設定

iPad インターフェースと同様に、ユーザーは左右の矢印をクリックしてコントロールの値を変更できます。縦線をドラッグして値をすばやく変更することもできます。clickkeydown の繰り返し動作を実装し、マウスまたはキーボードが押されたときに値の変化を加速できるようにしました。

ある入力フィールドから別の入力フィールドに移動するための TAB サポートが追加され、← と → の矢印で値が循環できるようになりました。

PC のインターフェースにはあまり意味をなさない iPad 版の機能に、ドローボードがあります。簡単に実装できたかもしれませんが、マウスで数字を描画するのは実用的ではありません。代わりに、ドローボードを実装するよりも、キーボード インターフェースの改良に時間をかけることにしました。

HTML5 の機能

ウェブ版の MathBoard では、HTML5 の機能を多数使用しています。

ローカル ストレージ

MathBoard では、ユーザーがクイズを保存して後で再生できます。HTML5 MathBoard は、SnowUI DAO インターフェースの HTML5 localStorage を使用してこの機能を実装します。

データが十分にシンプルで、高度なインデックス作成が不要なため、localStorage が当然の選択でした。すべてのクイズを 1 つの 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」をアプリケーションに組み込むことは簡単でした。

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

また、このフォントがアプリのほぼすべてのテキストでデフォルトとして使用されていたため、body のデフォルトにしました。

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 遷移のおかげで、アニメーションを簡単に追加でき、最高のパフォーマンスを実現できました。

アプリケーションには 3 つの主要なアニメーションがあります。

1)スライドする右ペイン

最初のアニメーションは右側のペイン(#rightPane)にあります。ユーザーが新しいクイズを開始するとスライドが閉じ、クイズを終了するとスライドが開きます。この効果を作成するために、次の CSS 遷移を使用し、JavaScript でトリガーしました。rightPane のデフォルト スタイルは開いた状態です。

#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 は厳密には必要ではありません。ただし、ブラウザは rightPane をスライドインする直前にクイズを表示することで、アニメーションをより滑らかにすることができます。

2)[設定] ダイアログ ボックスのアニメーション

ユーザーが右側の設定をクリックすると、画面の下部から設定ダイアログが表示され、該当するセクションまで下にスクロールします。

これを実現するために、右側のペインにも同様の移行を行いました。少し時間を要したのは、ダイアログの最初の表示時の表示の不鮮明さを解消することでした。ダイアログ UI をキャッシュに保存するようブラウザに指示するために、一度表示してスクロールする必要がありました。最初は display: none で試しました。このアプローチは、ブラウザはダイアログを表示する必要はないと判断していたため、正しくありませんでした。この問題の解決策は、初期化時に z-index: -1 で設定を表示することで、ユーザーには表示されませんが、ブラウザには表示することです。

3.)クイズの成功または間違ったメッセージのアニメーション

3 つ目のアニメーションは 2 つ一体です。「成功」または「不正確」のメッセージが表示された場合、まずあるポイントまでスケーリングし、少し待ってから、さらに大きくして消えます。そのために、2 つの CSS3 アニメーション スタイルを使用し、webkitTransitionEnd イベントで 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);

オーディオタグ

ユーザーがクイズに回答すると、アプリケーションは成功または失敗の音声を鳴らします。シンプルなのは、audio タグを使用して、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 アプリと密接に再現できました。