uupaa-excanvas.js と ExplorerCanvas(excanvas.js) の違い
uupaa-excanvas.js 0.4α がダウンロード可能になりました。
最新版のダウンロード: http://code.google.com/p/uupaa-js-spinoff/downloads/list
uupaa-excanvas.js と ExplorerCanvas(excanvas.js) の違いについて書いてみます。
# uupaa-excanvas.js(ver 0.23), ExplorerCanvas(r3) について述べています。
同じ材料から同じ物を作ったら、味も同じなのか?
uupaa-excanvas.js と ExplorerCanvas は共に、IE がネイティブにサポートしていない HTML5::Canvas を JavaScriptレベルで実装するものです。
Canvas API(I/F), 取り組むべき問題, 使える道具(VML + Silverlight), ゴールまでもが同じなので、ぱっと見は、両者はかなりそっくりになるはずです。
しかし、同じような材料(牛乳,卵,小麦粉,砂糖)で作ったケーキの味が、まったく同じになるはずがありませんよね?
今日は「見えない部分ではこんなにも実装が違ってるんだよ」風味な話をしようと思います。
使っている部品の違い
使っている部品の違いです。部品が違えば、それをドライブするロジックも異なります。
VML要素 | DXImageTransform | |
---|---|---|
uupaa-excanvas.js | vml:shape, vml:stroke, vml:fill, vml:oval,vml:textpath, office:spt, office:opacity2 |
Matrix, AlphaImageLoader |
ExplorerCanvas | vml:group, vml:image, vml:shape, vml:stroke, vml:fill, office:opacity2 |
Matrix |
サポートしている機能の違い
- uupaa-excanvas.js
- 未実装: MaxWidth, strokeText(in Silverlight)
- 制限あり: createLinearGradient, createRadialGradient, clip, drawImage, globalCompositeOperation, shadowBlur, shadowColor, shadowOffsetX, shadowOffsetY
- shadowは実装中です。次のバージョン(ver 0.3)で使えるようにする予定です。
- createLinearGradient, createRadialGradient, clip はWebkit に対する完全互換ではありません。いくつかの制限が伴います。
どちらのライブラリにも実装されていない機能は以下になります。
toDataURL, getImageData, putImageData,
textBaseline, isPointInPath, arcTo
- arcTo はHTML5::Canvasの仕様に不明瞭な点があり、実装を手控えている状態です。
- textBaseline はフォントメトリクス(フォントの詳細な情報)にアクセスする手段がないため実装できません。
- isPointInPath は高度に数学的なため実装できません。
- toDataURL, getImageData, putImageData は VML / Silverlight で生のピクセルデータにアクセスする方法がないため実装できない状態です。
- ActiveX経由(COM Object経由)なら以下のような方法もあります。
// 1. VC++ で、以下のような DLL(COM Object)を作成する。 STDMETHODIMP capture:: toBase64Png(x, y, w, h) { // Snapsie のコードを参考にしました CComPtr<IOleClientSite> clientSite; CComPtr<IWebBrowser2> browser; GetSite(IID_IUnknown, (void**)&clientSite); HRESULT hr = clientSite->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&browser); HWND hwndBrowser; hr = browser->get_HWND((long*)&hwndBrowser); CComPtr<IDispatch> dispatch; hr = browser->get_Document(&dispatch); HDC hdc1 = ::GetDC(hwndBrowser); HDC hdc2 = CreateCompatibleDC(hdc1); CreateDIBSection(); BitBlt(); : : } // 2. regsvr32 capture.dll を実行する // 3. COM Object を ブラウザから使う <script> toDataURL: function(type) { var obj = new ActiveXObject("capture.capture"); // 矩形領域の画像をコピーするCOM Object var data = ""; switch (type) { case "image/jpeg": data = "data:image/jpeg," + obj.toBase64Jpeg(x, y, w, h); // jpegなBase64データで受け取る break; case "image/png": default: data = "data:image/png," + obj.toBase64Png(x, y, w, h); // pngなBase64データで受け取る break; } return data; } </script>
この方法の欠点は、メリットがそれほど無いことと、regsvr32 が必要ということと、COM 関係のプログラミングには二度と関わりたくないという気持ちが強いことです。
http://uupaa-js-spinoff.googlecode.com/svn/trunk/uupaa-excanvas.js/DEMO.htm を見るとサポートしている機能の違いが、大体分かると思います。
# できれば SilverlightをインストールしたIEで見てください。
色のサポート
uupaa-excanvas.js は 様々な方法で色を指定できますが、ExplorerCanvas では注意が必要です。
ExplorerCanvas は rgb, rgba スタイルで色指定すると、描画の度に毎回文字列走査が入りますが、uupaa-excanvas.js は正規化した値(#ffffff, alpha値)をキャッシュし再利用します。
色の指定
uupaa-excanvas.js | ExplorerCanvas | |
#fff | ○ | △ |
#ffffff | ○ | ○ |
rgb(0,0,0) | ○ | ○ |
rgb(0%,0%,0%) | ○ | × (要素が描画されなくなる) |
rgba(0,0,0) | ○ | ○ |
rgba(0%,0%,0%) | ○ | × (要素が描画されなくなる) |
red (W3C named color) | ○ | ○ |
pink (Web named color) | ○ | △ |
transparent | ○ | × (alpha が 1 になり透過しない) |
CanvasReady のサポート
Webページを表示し終わるタイミングと、Canvasが利用可能になるタイミングは別物です。
またこの条件はブラウザ毎に異なります。
uupaa-excanvas.js では uuCanvas.ready(), uuCanvas.Layer.ready(), uuCanvas.already() によりタイミングを知る方法を提供していますが、ExplorerCanvas には同様の機能がありません。
ブラウザ | 描画可能なタイミング |
IE | DOM解析完了 + (該当する or 全ての) canvas 要素の初期化完了 |
Firefox | DOM解析完了 |
Safari,Chrome | DOM解析完了 |
Opera9.2 | DOM解析完了 |
Opera9.5,10 | Window.onload |
動的に追加した canvas 要素の初期化
動的に canvas 要素を追加した場合は初期化が必要です。以下の方法で初期化を行います。
uupaa-excanvas.js
// 動的にcanvasを生成し初期化する var elm = document.createElement("canvas"); document.body.appendChild(elm); elm = uuCanvas.init(elm); // 2Dコンテキストの取得 var ctx = elm.getContext("2d");
uuCanvas.Layer や uuCanvas.Draw を使うともっと簡単になります。
<script> var layer, draw; function canvasReady() { draw = new uuCanvas.Draw(layer.ref(1)); draw.angleGlossy(0, 0, "GLOSSYBLOODORANGE", { r: 20, angle: 30 }); layer.show(); } window.onload = function() { layer = new uuCanvas.Layer(document.getElementById("layerSpace"), 300, 150); layer.addCanvas(300, 150).ready(canvasReady); } </script> <div id="layerSpace" style="position: absolute; top: 0px; left: 0px;">
// 動的にcanvasを生成し初期化する(IE用に特別なコードを一行追加する) var elm = document.createElement("canvas"); document.body.appendChild(elm); if (document.uniqueID) { // for IE elm = G_vmlCanvasManager.initElement(elm); // IE用の初期化 } // 2Dコンテキストの取得 var ctx = elm.getContext("2d");
VML と Silverlight の共存
ExplorerCanvas はバックエンドに Silverlight も使えるように開発が進んでいるらしいのですが、将来的に共存できる/できないかは不明です。
uupaa-excanvas.js は VML と Silverlight を同時に利用可能です。
Silverlight が使える環境なら自動的に Silverlight でレンダリングしますが、以下のようにすることで VML でレンダリングを強制することが可能になり共存できます。
// 静的な canvas 要素に対しては、 class="vml" を指定する <canvas class="vml" width="300" height="150"></canvas> // 動的に生成する canvas 要素に対しては初期化時に VML の使用を強制できる。 <script> var canvas = document.body.appendChild(document.createElement("canvas")); canvas = uuCanvas.init(canvas, true); // 第二引数に真(trueや1)を指定すると、VMLでレンダリングされる </script> // uuCanvas.Layer 経由ならこうする。内部で uuCanvas.init(キャンバス, 1) が実行される。 var layer = new uuCanvas.Layer(document.body, 300, 150); layer.addCanvas(300, 150, 1); // 第三引数に真(trueや1)を指定する
共存可能なことにより以下のメリットが生まれます
- デバッグがとてもスムーズになる ⇒ Silverlight と VML のレンダリングの違いを開発時に目視で比較できます。
- ユーザの環境に左右されず、描画開始がスムーズに ⇒ ユーザの環境確認後に別々のスクリプトをロードする方法にくらべ、レンダリングをすばやく開始できます。
- いいとこ取りができる ⇒ Silverlight には Silverlight のよさが、VML には VML のよさがあります。誤解している方もいらっしゃるようですが、現時点では Silverlight >>> VML ではないのです。VML モードでしか使えない機能(strokeText)もあります。
- Silverlight のロードマップを見ると、いずれ VML の全ての機能をオーバーラップするようにも見えます。
ファイルサイズの違い
ソースコードを圧縮した状態とzipした状態のファイルサイズの比較です。
ソースコード | 圧縮 | 圧縮 + zip | |
---|---|---|---|
uupaa-excanvas.js | 99.4kB | 48.2kB | 15.4kB |
ExplorerCanvas | 26.4kB | 11kB | 4.3kB |
ExplorerCanvas の圧勝ですね。
実行速度の違い
http://uupaa-js-spinoff.googlecode.com/svn/trunk/uupaa-excanvas.js/DEMO.htm
uupaa-excanvas.js + Silverlight 環境下でのレンダリングはVMLのそれに比べかなり高速です。
VMLのレンダリング速度はほぼ互角です。uupaa-excanvas.js は ExplorerCanvas に比べ描画コストの高い機能(clip, グラデーション, globalCompositeOperation等)を実装していますが、速度的なペナルティはほとんど感じられないはずです。
ライセンスの違い
ExplorerCanvas は Apache License, Version 2.0 です。
uupaa-excanvas.js は MIT と Apache License, Version 2.0 のデュアルライセンスです。