EaselJSはCANVASをactionscriptに似た感じで扱えるようにするjavascriptライブラリだ。
ライブラリの作者はフラッシュ開発者として有名なGrant Skinner氏である。またadobeのFlashプロダクトマネージャで、最近モバイルブラウザー向けFlash Player開発中止についての詳細説明をしていたMike Chambers氏も、その開発に協力しており、将来的にはフラッシュとの連携がありそうだと言われている。
つい先ごろ0.4が公開された。ここのところバージョンアップが無かったので開発が続くのか少々不安だったのだけど、これで継続することがはっきりとしたので、いじりはじめてみることにした。
今回はhello worldとプロジェクトのスタートポイント作成を行った。
[Hello World]
EaselJSの最新版は以下のgtihubからダウンロード可能だ。
https://github.com/gskinner/EaselJS
examplesにあるHelloWorld.html及びMike Chambers氏のGetting Started with the Canvas Element and EaselJSを元にサークルとテキストが表示されるだけのスクリプトを作り上げた。
canvasは他から与えられるようにしてある。
var stage = new Stage(canvas); var g = new Graphics(); g.setStrokeStyle(50); g.beginStroke(Graphics.getRGB(225, 226, 227, .7)); g.drawCircle(0, 0, CIRCLE_RADIUS); circle = new Shape(g); circleXReset = -CIRCLE_RADIUS; circle.x = 150; circle.y = canvas.height / 2; stage.addChild(circle); text = new Text("Hello World!", "100px Arial", "#FFF"); text.x = 5; text.y = 150; stage.addChild(text); stage.update();
上記Hello WorldでEaselJSの空気は確かにasにかなり似通っており、きっとasのディスプレイオブジェクトにあるプロパティなら確認せずに書いてしまっても大丈夫そうだと理解できた。
[テンプレート]
HTML5 Boilerplateという、HTML5を扱う上でのベストプラクティスを集めたテンプレート集がある。
以下が日本語で解説してくれているサイトだ。
HTML5 Boilerplate を使用して Web 開発を容易に始める
これまでのスタディなどはsencha touch2を除きこのHTML5 Boilerplateを使用してきた。
webGLのようにPCオンリーでは無いこと及びモバイルでやりたいことが増えてきたためモバイルファーストの方針で、Mobile Boilerplateをテンプレートとして使用し、必要なところを変更していくことにした。
とりあえずの変更点は、
・jQueryのコメントアウトを外す。
・ライブラリにeasel.js,Stats.jsを加え、今回のjsファイルであるscriptHello.jsを読み込むようにする。
・img/h,img/l,img/mにあるスタート画面やアイコンをオリジナルの物にする。
あたりとしてある。
これ以外にもボットやサイトマップなどあるが今のところは置いておく、あとよくわからないテクニックやツール類も後で判明したら手を加えていくつもりだ。
[スクリプト構築方]
次に具体的なスクリプトの構築方へと入っていく。
グローバル汚染が嫌なので無名関数の中にいれることとする。
(function(window) { ・・・ })(window);
スタディでの利便性を考えとりあえずはjQuery使用するが、他のフレームワークを使用する可能性もあるので切り離しやすい構造にする。
main関数でeaselJsを扱い、その外側で無名関数内ではjQuery使用可としておく。easelJsを使用するmain関数や関数型コンストラクタ内ではjQuery使用を控えておく。
必要なパラメータ等はmain関数の外側で用意しておき初期化時やsetter/getterなどで授受出来るようにしておく。
しかしながら依存が多く発生するときやしそうなときは、これにこだわらない。
main関数はフラッシュのMainクラスつまりドキュメントクラスとしての扱いをする。
ステージに結び付け、ディスプレイオブジェクトのTOPに当たる部分にする。
これは上記のjQuery使用部分とeaselJs使用部分を分離させる為にも有効だ。
関数型コンストラクタでは大丈夫だが、無名関数内でコンストラクタを使用せずにTicker.addListener(this)とするとTickerが動かない。これは無名関数の外から無名関数内のtick関数を見つけられないからなので、
Ticker.addListener(window)
window.tick = tick;
とでもしておけば解決する。
[アドレスバー]
iPhoneでは、どうしてもアドレスバーが取ってしまう面積が大きくもったいないので消しておきたい。これは画面内容が全て読み込まれた後、少しタイミングをずらして1pixスクロールさせることで可能だ。
canvas.height = $(document).height()+60; setTimeout(start, 100);
まず今のウィンドウサイズ+アドレスバー分の大きさを確保して100ms後にスタート関数を動かす。
scrollTo(0,1); var canvas = $("#stageCanvas")[0]; canvas.height = $(document).height(); canvas.width = $(document).width(); var m = main().init(canvas,stats);
この時点でアドレスバー分含めたドキュメントの大きさは確保されているので1pixスクロールする。
そして、そのドキュメントの大きさにあわせてcanvasサイズを決めて、mainコンストラクタからオブジェクト化をさせる。
これでアドレスバーの表示はなくなり、その分コンテンツに使用できる。しかしながらsencha touch2のようにアドレスバーが出にくいようにはできていないので、調査をすすめる。
<追記>下記のようにすればステージをいじってもアドレスバーが出ないようにできた。
if (Touch.isSupported()) { Touch.enable(stage); }
また、htmlのheadにある以下の部分のコメントアウトを外し、ホーム画面に追加をするとフルスクリーンになる。
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <script>(function(a,b,c){if(c in b&&b1){var d,e=a.location,f=/^(a|html)$/i;a.addEventListener("click",function(a){d=a.target;while(!f.test(d.nodeName))d=d.parentNode;"href"in d&&(d.href.indexOf("http")||~d.href.indexOf(e.host))&&(a.preventDefault(),e.href=d.href)},!1)}})(document,window.navigator,"standalone")</script> <link rel="apple-touch-startup-image" href="img/l/splash.png">
[Stats.js]
three.jsのスタディに続きパフォーマンス確認のためにStats.jsを含める。
var $main = $("#main"); var stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0px'; stats.domElement.style.zIndex = 100; $main.append(stats.domElement);
tickでstageのアップデートと共にstatsのアップデートも行う。
これを忘れていて私はしばらく戸惑っていた。
that.tick = function() { ・・・ stage.update(); stats.update(); }
今回作成したhello worldとzipファイルをこちらに置いておく。
Hello EaselJS
easelJs_start.zip
これでとりあえずでは使えるスタートポイントになった気がする。
次回以降で素材読み込みとインタラクションを行うつもりだ。
それと今後の課題に、HTML5 Boilerplate及びMobile Boilerplateで使われているプラクティスの読解も入れることにした。