Friday, February 03, 2012
■ [Metro]Metro style appsはHTMLで書けるの?という話。

Windows 8のMetro style appsがHTMLとJavaScript「で」書けるようになるということについて、先日Twitterでも少し誤解されていたのでちょっとまとめ直してみます。
実際書けるの?
ざっくり整理するとこうなります。
- JavaScriptやHTML/CSSを使うなら全体をHTMLで書くしかない
- そこにXAMLを選ぶということはできない
- HTMLやCSSがWeb標準であるかというと大半のアプリケーションはそれでは済まないけれど、Web標準だけで書くこともできる
ちなみにここにはパッケージングが必要だとかそういう話は含めていません。
というわけで関連する技術を適当に図にしたのがこれです。
これはごく一般的なMetro style appsの形です。真ん中にInternet Explorerのエンジンを置いて、上が普通のWebで使うことのできる技術、下がWindowsネイティブの技術です。
というわけですこし分解して見てみます。
0. Web
Metro style appsの前にブラウザで見る普通のWebページの場合を。多分こんな感じ。ネイティブの機能は全くありません。
1. 最小の構成
まず最初にMetro style appsに必要最低限な構成です。この場合最低HTMLが1ファイルあれば出来上がりです(ほかにも必要であればCSSとかJSとかとか)。この時利用する技術は普通のWebと同じレベル、いわゆるWeb標準としてあるものだけです。
これでもとりあえず見た目がMetro styleかどうかはともかくMetro style appsです。
2. 先行実装、ベンダー拡張
とはいえちょっと高機能にしたい、表現力を上げたいなどという時にはブラウザに先行実装されていたり、ベンダーが独自に拡張したCSSやAPIを利用します。-ms-*プロパティとかですね。まあこれも最近のWebの世界では-webkit-*とかよく使われているのでそれですね。
というわけでその辺りを盛り込んだものでもMetro style appsです。この時点ではやっぱりまだ普通のWebとあまり変わりません。
3. Windows Library for JavaScript
しかしそろそろちゃんとMetro styleにしたくなります。色合いやコントロールなどです。
そういったMetro styleらしいアプリケーションを構築するためにWindows Library for JavaScript、WinJSとよばれるライブラリが提供されています。ライブラリと言いながらスタイルシートも含まれています。
で、WinJSを使うようになるとこんな感じです。WinJSは色々な機能があり、必要なものだけを選択して(要するに.jsファイルの参照)使えるので取り敢えず見た目やベースライブラリだけを使う前提です。
図をみるとわかりますがまだこの時点では拡張されたものも含めてWeb寄りの技術で構成されています。
HTML版のMetro style appsではUIコントロールにWinJS.UIというものを使いますが、その記述も実態もHTML5と(拡張された)CSSとJavaScriptで構成されています。
書き方次第ではまだWebと共存できる可能性があります。が、WinJS.UIが他のベンダープレフィックスなどを考慮してくれることはないのでこの辺りから普通のブラウザと同じかどうかはだいぶ怪しくなります(IEでは動いてしまうけれどIEでしか動かない)。
これはもちろんMetro style appsです。
4. Windowsネイティブ
そして最後にWeb標準になりそうもWebから扱えそうにもならないような機能(ブラウザに持つ必要のないもの)はWindowsのネイティブ機能、Windows Runtime(WinRT)に頼ることになります。
たとえばコンテキストメニュー、ページナビゲーション、アプリケーションのサスペンド、ソケット通信、ファイル操作といったローカルと密接なものたちなどです。またWinJSも一部WinRTを知っているので、協調して動いたりラッパーになっていたりするものがあります。
ここまで来て最初の図になります。そしてネイティブ機能を使うことになるのでもはやWeb技術だけではなくなります。
そしてこの形がMetro style appsとしては一般的な構成になるとおもわれます。Visual Studioのテンプレートはこの形で吐き出します。
まとめ
というわけでHTMLで書けるかという話ですが最初のほうに書きましたが、大抵はWindows 8に依存したHTMLで書くことになるけれどブラウザと同じ形にしようと思えばできる、です。
大抵のアプリケーションは最後のパターンになると思いますが、重要なのは1や2のパターンもアリだと言うことです。これはMetro styleを必要としないアプリケーション、例えば全て独自のUIをもつゲームなどを作る場合には有利になるのではないかと思います。
ちなみに
Web標準的なもので書こうと思えば書けるといってはみたものの、一部操作に制限があったりするのでWebのコードをそのまま持っていくと何らかの書き換えが必要になる場合がまれにあります。そんな時はMetro style appsに依存して回避する書き方か制限を回避する推奨される別な手段での書き方に修正が必要です。
Tuesday, January 31, 2012
■ Perl (Mojolicious::Lite)でちょっとしたCGIを作るメモ

Perlで真の意味でちょっとしたCGIアプリケーションを作ることがたまーにあります(CSVデータを表示するだけ的な)。どうせちょっとしたものですしCGI.pmとかで頑張ってもいいのですがそれもめんどくさいのでMojolicious::Liteを使ってみたのでそのメモです。
まずは手元の環境でcpanminusをダウンロードし、アプリケーションのディレクトリ app1 を作成して、そこにMojoliciousをインストールします。
CGIを持っていく先はだいたいどんなモジュールが入っているか謎ですし、システムワイドなモジュールのインストールができなかったりしますのでextlibに突っ込むのが面倒なくていいです。
perlbrewでインストールしたばかりのクリーンなPerl 5.12.4な環境なのでだいたい以下の手順で動く気がします。
手順
とりあえずまずはcpanmをダウンロードしてきて、アプリケーションのディレクトリ(ここではapp1)のextlibにMojoliciousをインストールします。
% curl -LO http://xrl.us/cpanm % chmod +x cpanm % mkdir app1 % ./cpanm -L app1/extlib Mojolicious --> Working on Mojolicious Fetching http://search.cpan.org/CPAN/authors/id/S/SR/SRI/Mojolicious-2.45.tar.gz ... OK Configuring Mojolicious-2.45 ... OK Building and testing Mojolicious-2.45 ... OK Successfully installed Mojolicious-2.45 1 distribution installed
Mojolicious::Liteのアプリケーションを生成します。(大した内容ではないけど)
% cd app1 % perl -Iextlib/lib/perl5/ extlib/bin/mojo generate lite_app [exist] /home/user/tmp/app1 [write] /home/user/tmp/app1/myapp.pl [chmod] myapp.pl 744
このままだとextlibを参照しないのでmyapp.plをエディタで開いて use Mojolicious::Lite; の上あたりに以下の行を追加します。
use File::Spec; use File::Basename; use lib File::Spec->catdir(dirname(__FILE__), 'extlib', 'lib', 'perl5');
書き換えたら起動してみます。
% ./myapp.pl daemon [Thu Jan 19 13:22:00 2012] [info] Server listening (http://*:3000) Server available at http://127.0.0.1:3000.
起動してサーバーのポート3000にアクセスしてページが出てくればできあがりです。ちなみに /perldoc にアクセスするとリファレンスを読めます。
で、あとはチュートリアルを見つつ適当に実装します。実際にCGIとして使うにはmyapp.plを名前を変えたりかえなかったりして普通にApacheなどから起動するように設定すればCGIとして動きます。実際のサーバーに設置するときにも丸ごと持っていけばよいでしょう。かんたん。
Plackを使う
./myapp.pl daemon で起動するとtemplatesディレクトリに書いたテンプレートの読み直しが行われなくて面倒だったのでPlackを使うことに。なんとかする方法がありそうな気もするのだけど。
% cd .. % ./cpanm -L app1/extlib Plack (略) Building and testing Plack-0.9985 ... OK Successfully installed Plack-0.9985 34 distributions installed % cd app1 % perl -Iextlib/lib/perl5/ extlib/bin/plackup myapp.pl -R templates Watching templates ./lib myapp.pl for file updates. HTTP::Server::PSGI: Accepting connections at http://0:5000/
感想
Mojolicious::Liteはインストールも実行も実装もかんたんです。モジュールのインストールがMojoliciousだけなのでだいぶスッキリ。
ドキュメントもそれなりにあるのもいいですね。
でもデータベースを使う場合とかもうちょっとまともなやつならAmon2とかのほうがいいのかも。
Sunday, January 22, 2012
■ [Metro]Metro style appsと解像度と画面サイズと画面解像度

このエントリの内容はWindows Developer Previewの仕様を元にしています。今後Betaやリリース時には変更される可能性があることに注意してください。
Metro style appsの解像度に合わせたスケーリング - ういはるかぜの化学 - subtech でスケーリングについて書きましたが、その拡大率が決定される条件がちょっと謎な感じに見えます。たとえば同じ画面解像度1920x1080でも10.6インチと23インチとで拡大率が違うわけです。
しかもVAIO Z(13インチ, 1920x1080)にWindows Developer Previewをインストールするとなぜかシステム解像度(以前からあるあのDPI設定)がデフォルトで120dpiになっています。その割にはMetro style appsはスケーリングしません。どうも画面サイズ(物理的な画面サイズ)をWindows側で把握してコントロールしているような感じです。
画面サイズの取得なんてとれるのかなと思って調べてみると GetDeviceCaps 関数 というWin32 APIにVERTSIZE,HORZSIZEを渡すと取れそうなのですがいろいろなところでまともな値は返さない(物理サイズの参考にはならない)という声も見かけます。
まあそうはいっても他に見当たらないのでコードを書いてとりあえず試してみました。
https://gist.github.com/1656292
書いたコードをVAIO L (24インチ, 1920x1080)で実行したところ530x300mmという値が返ってきました。24インチの16:9で53.13cm x 29.89cmぐらいらしいのでだいたいあってそうです。ならばとVAIO Z (13インチ, 1920x1080)で試してみると今度は290x160mmという値が返ってきました。やっぱりちゃんと動いているっぽいです。
Windows 7で動かすと677x381mmという明らかに変な値が出てくることからWindows 8からまともに機能するようになったようです。
というわけでこれをシミュレータで動かしたりして、さらにそのサイズからDPIを求めたりしてまとめたのが以下の表です。
| 環境 | 画面サイズ(インチ) | Windowsが把握している画面サイズ | 画面解像度 | 画面サイズと画面解像度で求めたDPI | 拡大率 |
|---|---|---|---|---|---|
| VAIO L | 24 | 530x300mm | 1920x1080 | 約92dpi x 91dpi | 100% |
| VAIO Z | 13 | 290x160mm | 1920x1080 | 約168dpi x 171dpi | 100% |
| シミュレーター | 10.6 | 132x235mm | 1366x768 | 約148dpi | 100% |
| 1920x1080 | 約207dpi | 140% | |||
| 2560x1440 | 約276dpi | 180% | |||
| 12 | 1280x800 | 162x258mm | 約126dpi | 100% | |
| 23 | 286x509mm | 1920x1080 | 約96dpi | 100% | |
| 27 | 336x598mm | 2560x1440 | 約109dpi | 100% |
これでどういう意味があるかと言うと、どうもWindows 8は10.6インチ(1366x768)をスタンダード スレートと定義しているらしく(ガイドラインの一番上の図がそんな感じ)そこを基準にいろいろ決まっているようです。
たとえば10.6インチの1920x1080では140%に拡大されるのに13インチで1920x1080のVAIO Zでは何も起こらないのは、
- 10.6インチの1920x1080は約207dpiで140%の拡大率
- 拡大率140%は約207dpiが基準になり、それを超えると適用される
- VAIO Zでは約170dpi前後ぐらいしかないので100%の域になる
となっていると推測できます。画面サイズで決定されるので拡大率にシステムのDPI設定は考慮されないことになります。
これで画面解像度だけで拡大率が決まるわけではない理由がなんとなくわかりました。
CSSのメディアクエリーで使われていた謎のdpi値
MSDNのガイドラインでは以下のようなメディアクエリーの例が書かれていました(微妙に間違ってるので直してますけど…)。
/* CSS - 拡大率に応じてリモートの画像を読み込む */ @media all and (max-resolution: 134dpi){ /* 100%の拡大率のとき100%用の画像 */ .imageBackground { background-image: url('http://www.fabrikam.com/foo.png?s=100'); } } @media all and (min-resolution: 135dpi) { /* 140%の拡大率のとき140%用の画像 */ .imageBackground { background-image: url('http://www.fabrikam.com/foo.png?s=140'); } } @media all and (min-resolution: 173dpi) { /* 180%の拡大率のとき180%用の画像 */ /* MSDNのサンプルでは174dpiになっているが173dpiでないと動かない */ .imageBackground { background-image: url('http://www.fabrikam.com/foo.png?s=180'); } }
134dpi、135dpi、173dpiとありますがこれは100%を96dpiとしたときの値です。つまり
- 96dpi * 100% = 96dpi
- 96dpi * 140% = 134.40dpi (135dpi)
- 96dpi * 180% = 172.8dpi (173dpi)
となります。Windowsは96dpiが標準解像度となっているのでそれが基準になっているのですね。
CSSの定義例で言うと
- 一つ目はmax-resolution:134dpiなので134dpiまでなので135dpi(140%)にならない範囲ぎりぎり→100%
- 二つ目はmin-resolution:135dpiなので140%の時の135dpi以上
- 三つ目はmin-resolution:173dpiなので180%の時の173dpi以上
に適用されることになるわけです。
ちなみにこのDPI値はHTML+JavaScriptなMetro style appsではwindow.screen.deviceXDPIとして取得できます。WinRTを経由してもWindows.Graphics.Display.DisplayProperties.LogicalDpiプロパティを使うことで取得できます。
が、なぜか180%の時の値が違います。deviceXDPIは173を返しますがLogicalDpiは174を返します。MSDNのメディアクエリーの例に174dpiと書いてあったのはWinRTの値が元なのではないかと思います。実際ダウンロードできるサンプルコードの方では173dpiになっています。まあ計算しても違うわけですしWinRTのバグのような気がします。
というわけでスケーリング周りを調べたらなかなかややこしかったですという話でした。
■ [Metro]Metro style appsの解像度に合わせたスケーリング

このエントリの内容はWindows Developer Previewの仕様を元にしています。今後Betaやリリース時には変更される可能性があることに注意してください。
昨今のスマートフォンやタブレットは画面が高精細化してきつつあり、アプリケーションも解像度に応じた対応を迫られ、iPhone 4以降ではRetina Display対応といった風にアプリケーションが対応しているのを見かけるようになりました。
Windows 8(コードネーム)はこれからリリースされるOSですのでそのあたりも考慮されています。そこでMetro style appsにおいてはアプリケーションはどのようにして対応するのかガイドライン(Guidelines for scaling)があるのでちょっと解説してみます。
スケーリングのされ方
Metro style appsでは解像度と画面の物理サイズによって100%,140%,180%と3段階の拡大率を持ち自動的に適用されます。拡大というのはブラウザの拡大みたいなものです。
たとえば10.6インチの1366x768では拡大なしですが、同じ物理画面サイズで1920x1080の場合には140%に拡大されるといった感じです。また、同じ1920x1080でも10.6インチ(スレートサイズ)と23インチ(デスクトップ)では解像度(DPI)が違うので拡大率も違ったりします。この辺は別に書きます(→Metro style appsと解像度と画面サイズと画面解像度 - ういはるかぜの化学 - subtech)。
| 拡大率 | 画面サイズ |
|---|---|
| 100% | 10.6インチ/1366x768, 23インチ/1920x1080 |
| 140% | 10.6インチ/1920x1080 |
| 180% | 10.6インチ/2560x1440 |
アプリケーションですべきこと
自動的に拡大されると書きましたが、ただ拡大するだけではキレイになるとは限らないのでアプリケーション側での対応も必要となります。ガイドライン(Guidelines for scaling)によれば以下のことをするようにと書かれています。
スケーラブルなベクターグラフィックスを使う
解像度非依存なベクター画像を使いましょうという話です。ベクター画像であれば伸び縮みさせてもジャギジャギしたりもやもやしたりしません(Windowsがうまくレンダリングします)。
HTMLでアプリケーションを作る場合にはSVGを、C#などで作る場合にはXAMLを使うことで実現します。
アプリケーションパッケージからビットマップ画像を読み込む
ビットマップ画像(JPEG,PNGなど)に特定のルールに従って名前をつけておくと自動的に拡大率の状態に応じて読み込むファイルを変える機能があります。
この機能によって拡大率の違いによってサイズの違う画像を読み込むことができます。
たとえばHTMLでは以下のようにimg要素でファイル /img/Image.png を参照します。
<img src="/img/Image.png" alt="Image" />
この時、実際に読み込まれるファイルは /img/Image.png だけでなく以下の拡大率によってバリエーションも参照されます。
- /img/Image.scale-100.png (100%時)
- /img/Image.scale-140.png (140%時)
- /img/Image.scale-180.png (180%時)
- /img/scale-100/Image.png (100%時)
- /img/scale-140/Image.png (140%時)
- /img/scale-180/Image.png (180%時)
この例のようにファイル名に .scale-{100,140,180} を含めるか、フォルダとして scale-{100,140,180} として分けるか好きな置き方を選ぶことができます。これはHTMLからの参照だけでなくCSSからの参照(たとえばbackground-imageプロパティ)も対象となります。
外部の画像を参照する場合はメディアクエリーを使う
外部つまりリモートにある画像を参照する場合には拡大率によって自動でバリエーションを検索する機能は動作しません。
そこでHTML ベースなMetro style appsでCSSから参照する場合にはメディアクエリーで解像度に応じて読み込む画像を切り替えます。
たとえばMSDNにある例だと以下のようなCSSになっています。
/* CSS - 拡大率に応じてリモートの画像を読み込む */ @media all and (max-resolution: 134dpi){ /* 100%の拡大率のとき100%用の画像 */ .imageBackground { background-image: url('http://www.fabrikam.com/foo.png?s=100'); } } @media all and (min-resolution: 135dpi) { /* 140%の拡大率のとき140%用の画像 */ .imageBackground { background-image: url('http://www.fabrikam.com/foo.png?s=140'); } } @media all and (min-resolution: 173dpi) { /* 180%の拡大率のとき180%用の画像 */ /* MSDNのサンプルでは174dpiになっているが173dpiでないと動かない */ .imageBackground { background-image: url('http://www.fabrikam.com/foo.png?s=180'); } }
min-resolution/max-resolutionの値が謎のdpiになっている理由は別に書くことにしますが、メディアクエリーのパターンとしては謎のdpiの指定も含めてこのようになります。
ユーザーの画像をファイルシステムから取り出すときにはサムネイルAPIを使う
ユーザーが持っている画像を動的に読み出して使う場合にはWinRTにあるサムネイルAPIを使います。サムネイルAPIはWindowsが現在の拡大率に最適な画像を返します。
サムネイルAPIというのはWindows.Storage名前空間にあるStorageFileクラスが持つ、GetThumbnailAsyncメソッドのことです。StorageFileクラスはフォルダなどから参照したときにとれるものです(よくあるFileクラス的なもの)。
参照:StorageFile.GetThumbnailAsync(ThumbnailMode) | getThumbnailAsync(ThumbnailMode) method
画像を実行時に読み込む場合には拡大率をみて読み込む
JavaScriptなどから動的に画像を読み込む場合にはコードで現在の拡大率によって画像の参照をコントロールする必要があります。
現在の拡大率はWindows.Graphics.Display.DisplayPropertiesクラスのResolutionScaleプロパティを参照することで得ることができます。
switch (Windows.Graphics.Display.DisplayProperties.resolutionScale) { case Windows.Graphics.Display.ResolutionScale.scale100Percent: console.log('100%'); break; case Windows.Graphics.Display.ResolutionScale.scale140Percent: console.log('140%'); break; case Windows.Graphics.Display.ResolutionScale.scale180Percent: console.log('180%'); break; }
画像には幅と高さを指定する
拡大率で読み込む画像が変わったりした場合にレイアウトが崩れるのを防ぐため、画像には幅と高さを指定するようにします。
グリッドをつかう
要するにメジャーなグリッドを20px、マイナーなグリッドを5pxずつとして画面を設計することで拡大した場合にも中途半端な値(たとえば23px*1.4倍=32.2pxに対して25px*1.4倍=35px)にならずピクセルの丸めとズレのようなものが発生しなくなってきれいです。
アプリケーションでしてはいけないこと
スケーリングを考慮する上で逆に避けるべきこともガイドラインには書かれています。
小さい画像を拡大時に使うこと
小さい画像というか100%用の標準的なサイズだけしか用意されていない場合、高解像度環境でスケーリングが必要な場合自動的に拡大されてぼやけた見た目になることになります。ということで画像は各拡大率にあわせたものを用意しておきましょう。
iPhoneで言うとRetina非対応なアプリをiPhone 4で実行したようなことになるのでという話です。
大きい画像を小さくして使うこと
小さい画像を高解像度で使うのと逆に、高解像度用の画像を低い拡大率で使うと縮小するとジャギジャギしてしまうので避けましょう。たとえば180%のパターンだけ用意してそれを140%と100%でも使い回す、といったことです。
ただし例外的に写真の画像は縮小しても見た目上問題ないのであればよいでしょう。
5pxの倍数以外でサイズを指定すること
上にも書きましたが5pxの倍数以外でサイズを指定すると拡大したときにズレが生じてしまいますので避けましょう。
スケーリングの状態を試す
スケーリングの仕組みが用意されていてもどうやってテストすれば?となるわけですが、シミュレータには解像度と画面サイズを想定した設定が用意されていてこれでテストすることができます。
どうぞご利用ください。
参考までに設定時の状態を以下にまとめておきます。
| 拡大率 | 設定 |
|---|---|
| 100% | 10.6インチ/1366x768, 12インチ/1280x800, 23インチ/1920x1080, 27インチ/2560x1440 |
| 140% | 10.6インチ/1920x1080 |
| 180% | 10.6インチ/2560x1440 |
Saturday, January 14, 2012
■ ブラウザーのアドレスバーの呼び名

どうでもいい話ですが最近のブラウザのアドレスバーには呼び名がついていたりします。
Windows Internet Explorer
Internet Explorerのアドレスバーは9からOne Boxという呼び名がつきました。
Web検索サジェスト、履歴とお気に入りの検索を持っています。ちなみにデフォルト無効ですが購読しているフィードから検索することもできます。
参考: ワン ボックス - Microsoft Windows
Mozilla Firefox
FirefoxのアドレスバーはLocation barが正式でバージョン3あたりで強化されてAwesome Bar(スマートロケーションバーとも)と呼ばれることがあるという感じのようです。Awesome Barと呼ぶのはきっと通でしょう。
履歴とお気に入りの検索機能を持っています。その検索は他のブラウザよりも強力な感じです。
ちなみに他のブラウザと異なりアドレスバーと検索ボックスが分かれていますがサジェストは出ないもののWeb検索にも使えます。
参考:
Google Chrome
ChromeのアドレスバーはOmniboxという呼び名です。
履歴とWeb検索のサジェスト、お気に入り/アプリケーションの検索機能を持っています。
参考:Use the address bar (omnibox) - Google Chrome Help
その他
Monday, December 19, 2011
■ IEBlogの古いアーカイブページ

IEBlog Archives 2004/7-2009/12
見出しの青い四角がはてなっぽい。しかし、2年以上前のアーカイブ見る手立てはないのかな……
なんかデザイン変更で2年前以前のアーカイブへのリンクがなくなったっぽいのでとりあえず最初から2009年末分までをひねり出してみたり。
ひねり出すのに使ったJavaScript。ChromeでIEBlogを開いてJavaScriptコンソールで実行すればなんとなくできます。ちなみに変換前のデータはHTMLにJSONとして埋めてあります。
古いやつ見るのもなかなか味わい(謎)があってちょっとおもしろいですね。










morbo app1
でできます。
>でもデータベースを使う場合とかもうちょっとまともなやつならAmon2とかのほうがいいのかも。
これはちょっと誤解を招くかも。Mojolicious::Liteは小規模開発、Mojoliciousは大規模開発が可能なように設計されてます。
Amon2云々は最初Amon2で書いててMojolicious::Liteにした経緯があったので、Mojoliciousが大規模に向いてないとは思ってなかったのですが確かに誤解を招きますね…。後で修正しておきます。