Intelligent Technology's Technical Blog

株式会社インテリジェントテクノロジーの技術情報ブログです。

【Herlock】アプリ開発(テキスト表示とレイアー)

こんにちは、石尾です。

前回は、Herlockを触った程度で終わりました。
今回から、Herlockによるアプリの実装に関して投稿していこうと思います。

※前回同様に、Herlockはクローズドベータ版を利用しています。

Herlockの仕組み

Herlockは、JavaScriptだけで実装できると前回紹介しましたが、ネイティブアプリでよく利用するWebViewを使いブラウザ(HTML)表示をしている訳ではありません。JavaScriptエンジン自体を拡張して、描画はOpenGLにより行っています。

とすると、画面レイアウトの実装やその利用APIなど細かく覚える必要があるのでは!?と思いましたが、
描画レイアウトの構成は、Flashの表示リストやHTMLのDOMのようなツリー構造であるため、それほど理解しがたいことはないと思います。
(ただ、複雑な画面のアプリ作成の場合は、まだ判断しがたいですが、)

詳しく知りたい方は、株式会社ソニックムーブのブログを参照してください。
Herlockの内部的な仕組みと開発コンセプト | SONICMOOV LAB
【中級編】Herlockにおけるライブラリの使用 | SONICMOOV LAB
Javascript&OpenGLで作るネイティブアプリ

HerlockのAPI:Layer

コーディングする前に、Layerについてちょっと説明をします。
Layerは、描画コンテンツ(ImageやStageなど)を画面に投影するためのコンテナです。画面サイズの端末差異を吸収する役割(scaleModeプロパティで調整)を担います。Window上に複数のLayerを重ねて、表示します。

※Imageは、画像データの読み込み・保持や描画を行います。HTMLのimageタグのようなもの。
※Stageは、Layerの表示ツリー構成要素。ルート要素となります。
WebGLは、3Dグラフィック要素、CanvasはHTMLのcanvasタグのようなものと予想。(Herlock内に情報が見つからなかった)

LayerのscaleModeプロパティは、次の4つがあります。

showAll(Layer.SCALE_SHOW_ALL) アスペクト比を維持しコンテンツ全体がスクリーンに収まるように描画。スクリーンが余る。
noBorder(Layer.SCALE_NO_BORDER) アスペクト比を維持したままスクリーン全体に描画。コンテンツがスクリーンからはみ出す。
noScale(Layer.SCALE_NO_SCALE) 拡大縮小なし。
exactFit(Layer.SCALE_EXACT_FIT) アスペクト比を無視しスクリーン全面に描画
※デフォルトは、showAll。()内は、定数。

また、Layerの配置を垂直方向verticalAlignプロパティと水平方向horizontalAlignプロパティで設定します。

Layer.verticalAlign
top(Layer.VALIGN_TOP) 上寄せ
middle(Layer.VALIGN_MIDDLE) 中央寄せ
bottom(Layer.VALIGN_BOTTOM) 下寄せ
※デフォルトは、middle。()内は、定数。

Layer.horizontalAlign
left(Layer.HALIGN_LEFT) 左寄せ
center(Layer.HALIGN_CENTER) 中央寄せ
right(Layer.HALIGN_RIGHT) 右寄せ
※デフォルトは、center。()内は、定数。

テキスト表示サンプル

プロジェクト作成時のテンプレートを「TextSample」に設定すると、次のコードが実装されたプロジェクトが作成されます。

var stage = new Stage( 320, 640 );
addLayer( new Layer( stage ) );

var textField = new TextField();
textField.defaultTextFormat = new TextFormat( null, 25, 0xff0000 );
textField.text = "テキスト";
stage.addChild( textField );

Stageオブジェクトを生成し、引数320が横幅、640が縦幅をpx単位で設定しています。
Layerオブジェクトを生成し、Stageオブジェクトを設定しています。
テキストオブジェクトTextFieldを生成し、Stageオブジェクトの子要素として設定しています。

アプリの実行イメージは次のようになります。

レイアーサンプル

プロジェクト作成時のテンプレートを「LayerSample」に設定すると、次のコードが実装されたプロジェクトが作成されます。

(function () {
    // header 上に吸着
    var headerLayer = new Layer(new Stage(640, 80));
    headerLayer.verticalAlign = "top";
    headerLayer.scaleMode = "showAll";

    // content 多少端が切れてもいいデザインで、必ず表示したいものは中央に寄せる
    var contentLayer = new Layer(new Stage(300, 300));
    contentLayer.verticalAlign = "middle";
    contentLayer.scaleMode = Layer.SCALE_NO_BORDER;

    // header 下に吸着
    var footerLayer = new Layer(new Stage(640, 80));
    footerLayer.verticalAlign = "bottom";
    footerLayer.scaleMode = "showAll";

    //
    window.addLayer(contentLayer);
    window.addLayer(footerLayer);
    window.addLayer(headerLayer);

    //
    var header = new TextField();
    header.width = 640;
    header.height = 80;
    header.background = true;
    header.backgroundColor = 0x0;
    header.defaultTextFormat = new TextFormat(null, 30, 0xffffff);
    header.text = "header";
    header.alpha = 0.7;
    headerLayer.content.addChild(header);

    //
    var image = new Image();
    image.src = "assets/images/image.png";
    image.onload = function () {
        contentLayer.verticalAlign = "middle";
        contentLayer.scaleMode = "noBorder";
        contentLayer.content.addChild(new Bitmap(new BitmapData(image)));
    };


    //
    var footer = new TextField();
    footer.width = 640;
    footer.height = 80;
    footer.background = true;
    footer.backgroundColor = 0x0;
    footer.defaultTextFormat = new TextFormat(null, 30, 0xffffff);
    footer.text = "footer";
    footer.alpha = 0.7;
    footerLayer.content.addChild(footer);

})();

headerLayer、contentLayer、footerLayerの3つのLayerを生成し、それぞれverticalAlignとscaleModeプロパティを設定しています。そして、親となるwindowオブジェクトにLayerを追加設定しています。
※このサンプルでは、名前空間を意識してでしょうか? function(){};即時関数として定義しています。

アプリの実行イメージは次のようになります。レイアウト位置が調整されていることがわかります。

プロジェクト内のファイル構成

作成したプロジェクトは、次のようなフォルダ構成となっています。
上記で生成されたコードは、main.jsで実装されます。

{プロジェクトルートフォルダ}
│  main.js
│  README.md
├─app
│      
└─assets
    ├─images
    │      image.png
    │      
    └─sounds

ちなみに、HerlockによりビルドしたAndroidデバッグアプリのapkファイルをjarコマンドで展開するとassetsフォルダ配下のassets.zipファイルに上記のプロジェクトルートフォルダが圧縮されて登録されています。

{ルートフォルダ}
│  AndroidManifest.xml
│  
├─assets
│     assets.zip
・・・

感想

レイアウトの実装は、Androidアプリ開発でのXMLレイアウトファイルなどを使うわけでなく、またHTMLで作成するのでなく、JavaScriptでごりごり実装する必要があります。また、他画面構成の場合、親となるwindowオブジェクトに対してLayer追加・削除を行い、画面遷移等の制御をする必要があるなぁと思いました。

また、今回Herlockを使っていて気付いたのです。HerlockViewerで開発アプリを実行していますが、実機上に開発アプリはインストールされていません。HerlockViewer内で、アプリを実行しているだけのようです。

引き続き、アプリの実装に関してレポートしていきたいと思います。