タグ「HTML5」が付けられているもの

ng-conf 2014っていうイベントが1月にあったようですね。

YouTubeで動画が公開されている(でもすべてではない)ので助かります。とても勉強になりますね。ほんと、いい時代になったものです。

さて、Daniel ZenのTalkを見ました。AngularJSでモバイルアプリを作るために使えるライブラリがいっぱい紹介されていたのでメモしておきます。

PhoneGap

まず、PhoneGap。 今では、Open Sourceなんですね。

http://cordova.apache.org/

使ったことはないですが興味はあります。 一部ネイティブ関数にもアクセスできるようです。

http://en.wikipedia.org/wiki/Phonegap#Supported_platforms

APNも使えるようですね。個人的にはこれが一番大きいかな。

ngTouch

次は、ngTouch。 これは、Angularのモジュールです。タッチイベントを扱えるそうです。 一方、300ms問題だけなら、fastclickでよさそうです。

angular-mobile-nav

続いて、angular-mobile-nav。iOS5くらいのLook&Feelが簡単に作れるライブラリのようですが、READMEによるとangular-1.2だったらもっと簡単にできるということなので、今後使う機会はなさそうです。

angular-gestures

angular-gesturesは、その名の通りジェスチャーを使うためのディレクティブを提供してくれるようです。基本的には、hammer.jsのラッパーなのでしょうか。

angular-jqm

angular-jqmはjQuery Mobileのラッパーディレクティブです。jQueryなんて使わないぜ、と思っていたら、なんとこのライブラリ、jQueryとjQuery MobileのJSには非依存だそうです。つまり、jQuery MobileのCSSを使っているだけ。一気に気に入りました。そのセンスがいいです。機会があれば使ってみたいと思います。

AngularJS Native

これは、PhoneGapのネイティブ関数を呼ぶためのラッパーのようなものでしょうか。それぞれモジュールごとに分かれているようです。

angular-carousel

angular-carouselは、carouselを簡単に実現するためのライブラリです。 carouselってなんて訳すのでしょう?カルーセル? デモを見れば一発で分かると思います。

angular-snap

angular-snapは、snap.jsのラッパーディレクティブです。最近のモバイルアプリでよくある画面全体がスライドしてメニューがでるUIができるようです。snap.jsは依存ライブラリもなく、サポートブラウザも多く、設定も柔軟なようで魅力的です。

Ionic Framework

Ionic Frameworkは、PhoneGap用のフレームワークです。AngularJSも使われているとのことです。このフレームワークの範囲内でできることをやる分には簡単にできそうです。


その他、Tips等も紹介されていますので、興味がある方は直接スライドを見るとよいでしょう。

http://bit.ly/zen-ng-phonegap

オフラインファーストという言葉があるようです。言葉の存在こそ知りませんでしたが、以前からオフラインアプリを推進したいと思っていました。モバイルファーストなら、HTML5アプリといってもオフラインで使えるべきでしょう、と思います。これには賛否両論あるみたいですが。

http://blog.joelambert.co.uk/2012/11/26/offline-first-a-better-html5-user-experience/

2012年にこんな記事があったのですね。

さて、このオフラインファーストの文脈で、最近注目しているライブラリがあります。Breezeです。 まさにオフラインアプリを作るためのクライアントサイドデータ処理ライブラリです。

stackoverflowでBreezeの代替はないのかという質問がありましたが、

http://stackoverflow.com/questions/15938866/alternative-to-breeze-js

今のところ、ぱっとしたものはなさそうです。今後の登場にも期待しましょう。

Breezeはだいぶ強力なようですが、それを理解するのはなかなか骨が折れます。基本的なデータベースの概念が理解できていないとつらいのかしら。ドキュメントもあるのですが、どこから読んでいいのか分かりにくいです。stackoverflowで聞いてね、って感じです。それはそれで、いいアプローチだとは思います。 ちなみに、Angularのドキュメントは読みやすいと感じます。

今日の本題。MEANスタックって知っていますか? ちらほら記事があるので、知名度はそこそこでしょうか。 MongoDB, Express, AngularJS, Node.jsの頭文字をとっているのですが、個人的には順序が気になって仕方がないです。まあ、語呂合わせなんでしょうけど。

http://mean.io/

こんなサイトがあるのですね。

http://jp.blog.mongodb.org/post/49262866911/the-mean-stack-mongodb-expressjs-angularjs-and

なるほど、MongoDBの人たちが呼び始めたのでしょうか。

さて、本当の本題。BMEANスタックというのをご存知の人は少ないのではないでしょうか。まぁ、Breezeの人が呼んでいるだけだと思いますが、最近の一押しです。

BMEANのBはもちろんBreezeです。BreezeのバックエンドとしてMongoDBを使います。AngularJSも実はオフラインアプリと相性がいいと思っています。ExpressとNode.jsはバックエンドのフレームワークですね。

BMEANを見つけたのは、Breezeのサンプルアプリです。

http://www.breezejs.com/samples/zza

これもまたドキュメントが少なくて、ソースコード読めっていうスタンスなのですが、がんばって読んでみています。そこまで完全なオフラインファーストは意識されていないようで、基本的にはオンラインで動かすことを前提に、一時的にオフラインになっても大丈夫なようにできる(そのようにコーディングすれば)というところでしょうか。

しばらくはBMEANスタックを考えてみようと思います。 そのうち、オフラインファーストに求められるライブラリの形が見えてくるかもしれません。


2/8追記。

Breezeのチュートリアルは面白いです。

http://learn.breezejs.com/

インタラクティブに実行できるので、勉強になりますね。もっと内容が増えてくれたらいいのですが。

Node.jsでオフラインで動くHTML5のWebアプリを作るときに、connect-cache-manifestを使う に書いた2つの不満を解消するために connect-cache-manifest を改良しました。

今回の修正点は2つ。 1つはファイルを除外するオプション、もう一つはファイル名とURLのパスが同一でない場合に書き換えるオプションです。

説明よりコードを読んだほうが分かりやすいと思ます。

var express = require('express');
var cacheManifest = require('connect-cache-manifest');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cacheManifest({
  manifestPath: '/application.manifest',
  files: [{
    dir: __dirname + '/public',
    prefix: '/static/',
    ignore: function(x) {
      return (/(?:\.swp|~)$/).test(x);
    }
  }, {
    dir: __dirname + '/views',
    prefix: '/html/',
    ignore: function(x) {
      return (/(?:\.swp|~)$/).test(x);
    },
    replace: function(x) {
      return x.replace(/\.jade$/, '.html');
    }
  }],
  networks: ['*'],
  fallbacks: []
}));
app.use('/static', express.static(path.join(__dirname, 'public')));
app.get('/html/:name', function(req, res) {
  res.render(req.params.name);
});

このように、ignoreとreplaceがオプション指定できるようになりました。

これで、バックアップファイルは除外されるし、jadeファイルが増えてもリストアップする必要がありません。とても便利です。

以前の記事で紹介した、 connect-cache-manifestですが、 実は自分でちゃんと使ったことがありませんでした。

今回、一通り動くところまで使ってみたので、参考までに紹介します。 Expressと Jadeを使う前提です。

多くの場合、ディレクトリの構造は次のようになるのではないでしょうか。

|-- app.js
|-- public
|    |-- js
|    |    |-- foo.js
|    |    |-- bar.js
|    |-- css
|    |    |-- foo.css
|    |    |-- bar.css
|    |-- images
|         |-- foo.png
|         |-- bar.png
|-- views
     |-- xxx.jade
     |-- yyy.jade

このような場合での、connect-cache-manifestの設定は次のようになります。

var express = require('express');
var cacheManifest = require('connect-cache-manifest');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cacheManifest({
  manifestPath: '/application.manifest',
  files: [{
    dir: __dirname + '/public',
    prefix: '/static/'
  }, {
    file: __dirname + '/views/xxx.jade',
    path: '/html/xxx.html'
  }, {
    file: __dirname + '/views/yyy.jade',
    path: '/html/yyy.html'
  }],
  networks: ['*'],
  fallbacks: []
}));
app.use('/static', express.static(path.join(__dirname, 'public')));
app.get('/html/:name', function(req, res) {
  res.render(req.params.name);
});

これで、/application.manifestが生成されるようになります。 使ってみて不満が二つありました。一つは、emacsやvimで*~のバックアップファイルができた場合にそれもマニフェストに入ってしまうこと、もう一つは、jadeファイルが複数ある場合にリストアップしなければならないことです。そのうち気が向いたら改良しようかな。

これで、HTML5のマニフェストを使いつつ、ほとんど気にせずに普通にコーディングができます。

そうそう、ついでにもう一つ。ファイルを新規に追加したときは、nodeを再起動しないといけません。これは、node-supervisorやnodemonを使えば解決できるかもしれません。試していませんが。

RSS Pipesの補完機能としてのRSSリーダーを、HTML5 Canvasのみを使ってどこまでスマホアプリが作れるのか挑戦中です。

Googleリーダがなくなるから、それの代替として作ろうと始めましたが、Googleリーダの期限までには完成しそうにありません。

今日は、RSSの記事のリンクを開く機能を作りました。 CanvasではHTMLは表示できません。そこで、Canvasの外側に独立して iframeを使うことで表示しました。 iframeの表示はjQueryを使いました。KineticJSのようなpure JavaScriptを使っていると、DOM操作はちょっと古びたものに感じます。

さて、RSSのリンクを開くためのボタンも作ってみました。 右上の方に矢印のアイコンを置いて、それを押すとiframeが開きます。 その矢印アイコンですが、Kineticのshapeで作成するのは面倒だったので、inkscapeで作成してSVG DataをKineticのpathで読み込みました。

コードはこんな感じです。

var path = new Kinetic.Path({
  x: 0,
  y: -6,
  data: 'M 23.618434,50.171286 41.144607,36.346769 23.23155,22.400304 l 0.0092,8.18132 c 0,0 -7.445838,-1.03921 -11.864782,3.095364 -4.4188829,4.134559 -4.3930939,13.742678 -4.3930939,13.742678 0,0 2.442808,-4.269676 6.9240349,-5.841822 4.481182,-1.572147 9.583341,-0.746586 9.583341,-0.746586 l 0.127874,9.340028 z',
  fill: '#f0f0f0',
  scale: 0.43
});

全コードはこちらです。

https://github.com/dai-shi/canvas-rss-reader/

実行サンプルはこちらです。

http://canvas-rss-reader.herokuapp.com/

未読既読の機能までできたら、とりあえずは使えるようになるかと思うのですが、どうでしょう。

RSS Pipesの補完機能としてのRSSリーダーを、HTML5 Canvasのみを使ってどこまでスマホアプリが作れるのか挑戦中です。

今回は、フリックで横スライドに挑戦しました。 しばらく時間が空いてしまったのは、どうやって実装するかイメージがわかなかったからです。 試行錯誤した結果、比較的満足いくものになりました。

実装するときに気にしているのは、 普通のスマホアプリと同じくらいの操作性を目指しつつ、KineticJSの機能をフル活用して少ないコーディングで実現することです。 横スライドも、縦スクロールと同様にドラッグ&ドロップの機能を活用しました。 なので、正確にはフリックを判定しているわけではなく、ドロップ後の位置でスライドするかどうか判定しています。 ちょっと使ってみると、直感と異なることもあるのですが、それは今後の課題ということで。

今回、Canvasでアプリを作る時に意識をしているのは、軽快さです。 普通に作ったアプリより軽く感じるWebアプリを作れるのかがポイントです。 現状はまだ機能が少ない(そもそも、まだRSSのURLが開けない)ですが、 自分のスマホではかなり軽快にスライド動作ができるようになっています。

他のスマホではどうなのか気になります。 ぜひ、お持ちのスマホで試してみてください。 下記の実行サンプルをスマホのブラウザで開くだけです。

http://canvas-rss-reader.herokuapp.com/

全コードはこちらです。

https://github.com/dai-shi/canvas-rss-reader/

この時点のコードを参照するには、本日のコミットを参照してください。 上記実行サンプルは、今後最新版に変わっていってしまいますので、ご注意を。


6/23追記。

大切な発見を書くのを忘れていました。TweenのonFinishは呼ばれないことがあってはまりました。Tweenでノードを動かしている時に、ドラッグ&ドロップをすると、終了時にonFinishが呼ばれませんでした。setTimeoutを使うことで解決しました。KineticJSのバージョンは、4.5.2です。この仕様が将来のバージョンでどうなるかは不明です。

RSS Pipesの一機能として、スマホ向けのRSSリーダーみたいなものを作ってみようかと思います。

RSSリーダーなんて世の中にたくさんあるので、普通のものを作っても面白くありません。そこで、勉強がてらHTML5でスマホアプリにしてみようと考えました。しかも、フルキャンバスで。canvasというのはグラフィック用の機能ですが文字も書けるわけで、それですべてを作ったら面白いのではないかと思いました。

さて、HTML5 Canvasは何年か前に少しだけ触りましたが、最近はライブラリも充実しているのではないでしょうか。検索してみると、

HTML5のcanvasを劇的に使いやすくするJavaScriptライブラリまとめ5つ

を見つけました。また、stackoverflowで、

Current State of Javascript Canvas Libraries(2012)?

を見つけました。使ってみないと分からないだろうと思いますが、これらの情報から、KineticJSを試してみることにしました。

今日のところはここまで。これから少しずつ進捗を書いていけたらいいなと思っています。

昨日、見つけてissueの登録をしておいた、connect-offlineの件です。

https://github.com/dustMason/connect-offline/issues/1

早速返事が来ました、Pull Requestにして欲しいと。仕方ないやるかな、と思ってみたものの、やっぱりCoffeeScriptでは書く気になれません。また、パッケージ名も分かりにくいのではないのかと考え、新しく作ることにしました。

初めは、完全互換のパッケージにしようと考えていたのですが、process.cwd()で相対パスを使っているのが気に入らず、__dirnameを使うようにしたかったので、パスの指定の互換性がなくなってしまいました。

作っているうちに他の改善案(ディレクトリの再帰探索)も思いつき、実装方法もだいぶ変わってしまったので、互換の方向性はやめました。とは言っても、基本的には同じように使えるはずです。

https://github.com/dai-shi/connect-cache-manifest

から参照できます。npmにも登録済みです。

express.jsでHTML5のキャッシュマニフェストを使おう考えています。どうせならconnectのmiddlewareにしたら便利だろうと思って調べました。

GitHubでmanifestをキーワードに色々検索したのですが、見つかりませんでした。connect-manifestという空のプロジェクトがあったくらい。

あきらめて、自分で作ろうかと思ったところで、npmで検索してみました。結果、見つけました。

https://github.com/dustMason/connect-offline

offlineという名前だから、GitHubの検索では見つからなかったようです。 Node.jsはパッケージ探しが難しいですね。

このconnect-offlineはStar数が4しかありません。あまり、キャッシュマニフェストをmiddlewareで欲しいと思う人はいないのでしょうか。それとも、名前が悪くてみんな見つけられないのでしょうか。

READMEを読むと、以前のconnectにはcacheManifestというmiddlewareがバンドルされていたようです。connectのリポジトリを探りましたが、確かに、version 1.0より前のタグには存在します。なぜ、やめたのかは分かりませんでした。(消えたファイルのgit logを見ればいいのも)

さて、connect-offlineはちょっと想像していた機能が足りなかったので、自分で修正しようと思ったのですが、ソースがCoffeeScriptだったので手を出しませんでした。(CoffeeScriptはなぜか好きになれないので)

代わりに、issueにしておきました。

https://github.com/dustMason/connect-offline/issues/1