2009年10月1日木曜日

bloggerでcanvasを使ってみる(IEにも対応)

JavaScript で、図表や記号、例えば簡単な譜面の断片のようなものを描けないかと思って調べていると、canvas タグと言うものでかなりの図形描画ができるらしい。ただし、やはりというか、またしてもというか、ここでもIE が問題になる。

まずcanvas タグがそもそもサポートされていない。これは ExplorerCanvas というスクリプトがあって、これを読み込んでおけば canvas への操作を VML でエミュレートして同等の効果が得られるらしい。パフォーマンスが悪くなるという指摘もあるみたいだが、こここまでは、まあ、とりあえず良し。

で、blogger でも使ってみようと思うのだが、ブログの性質上 JavaScript は <body>内に記述されることになる。ところが、またまた IE で問題が生じる。普通に body 内の script タグ中に記述した canvas 操作コードが思ったとおりに実行されない。ExplorerCanvas がちゃんと効いていないのか、canvas のgetContent()を呼んだところでエラーになる。どうも onload 以降のタイミングでないとちゃんと動かないらしい。

そこで blogger の「HTML/JavaScript の設定」で以下のようなコードを追加して、canvas タグの直後の要素を描画コード記述部とみなして、その innerHTML が onload のタイミングでJavaScriptとして実行されるようにしてみた。
function drawAll() {
  canvases = document.getElementsByTagName('canvas');
  for (var i = 0; i < canvases.length; i++) {
    var canvas = canvases[i];
    var className = canvas.getAttribute('class')||canvas.getAttribute('className');
    if ('blogger' == className) {
      var script = canvas.nextSibling;
      if (script.nodeName=='/CANVAS') script = script.nextSibling
      eval(script.innerHTML.replace(/&gt;/g, ">").replace(/&lt;/g, "<"));
    }
  }
}
if (window.addEventListener) {
・・・他のイベントリスナ
  window.addEventListener('load', drawAll, false);
} else if (window.attachEvent) {
・・・他のイベントハンドラ
  window.attachEvent('onload', drawAll);
} else {
・・・他のイベントハンドラ
  window.onload = drawAll;
}
個々のブログエントリには、例えば以下のように canvas と描画コードを記述する。(本来は改行を削除して、"<"と">"をエスケープする必要があるが、わかりにくくなるため省略した。)
<canvas id="c1" width="150" height="150" class="blogger" style="border:1px solid black;background-color:#FFFFCC;"></canvas>
<pre style="display:none;">
  var canvas = document.getElementById('c1');
  var ctx = canvas.getContext('2d');
  for (i=0;i<6;i++){
    for (j=0;j<6;j++){
      ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +
                        Math.floor(255-42.5*j) + ')';
      ctx.beginPath();
      ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
      ctx.stroke();
    }
  }</pre>
JavaScriptコードは canvas tutorial から取ったサンプルだが、参照先と同じ図形群が以下のように表示されていることを、FireFox、Safari、Opera、IE の最新版で確認した。(確認していないブラウザだと表示されていないかもしれない。)
var canvas = document.getElementById('c1');var ctx = canvas.getContext('2d');  for (i=0;i<6;i++){    for (j=0;j<6;j++){      ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +                        Math.floor(255-42.5*j) + ')';      ctx.beginPath();      ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);      ctx.stroke();    }  }

それにしても、IEはなにかと面倒くさいなあ。DHTML や JavaScript で何かやろうとするたびに、IEでイライラする。すでに使い勝手やパフォーマンスの面では、(ちょっと言葉は悪いが)「糞ブラウザ」という評価もあるようだけど、Web アプリ開発者にとっても何か嫌な感じだ。IE のシェアがもっと落ち込んで、無視しても問題ないくらいになれば良いのに、こんなのが OS と抱き合わせだからタチが悪い・・・

0 件のコメント:

コメントを投稿