ブラウザ上でお絵かき2005年09月27日 02時37分

Ajax を使った手書き文字認識」を見て。ここでは線を描くのに絶対配置の span 要素を大量生成しているけど、最近のブラウザってベクター描画エンジン付きのものが多いわけで。WinIE 5 以降の VML 、Opera 8 ・ Firefox 1.5 以降の SVG 、Safari 1.3 ・ Firefox 1.5 以降の canvas 要素といった具合に。

ということで各ブラウザでベクター描画エンジンが使えればそれを使い、なければ絶対配置の HTML 要素を大量生成することで、ブラウザ上でお絵かきできるというものを作ってみた。元に戻す / やり直すこともできる。線を描くだけで塗りつぶしはできないが。

その線を描くために作ったのが DrawingCanvas クラス。以下のようにすることで三角形が描ける。実際の描画部分には SVG Tiny 、HTML Canvas 、CSS Positioning 、VML の 4 つのバックエンドがあり、ブラウザによってそれらを切り替えている。

var canvas = new DrawingCanvas(element, width, height);
canvas.setBgColor("#fff");
canvas.setLineColor("#000");
canvas.setLineWidth(5);

canvas.startLine(10, 10);
canvas.lineTo(50, 50);
canvas.lineTo(50, 10);
canvas.lineTo(10, 10);
canvas.endLine();

CSS Positioning バックエンド (絶対配置の HTML 要素を大量生成) の作成にあたっては線分描画のアルゴリズム (Fussy's HOMEPAGE) を参考にした。Bresenham ね、なるほど。(しかしこうしたアルゴリズムを自分で考えずに、すぐ検索に走ってしまうのは悪い癖か?)

作成にあたってつまずいた点などは以下のとおり。

  • Opera 8 がサポートしているのは SVG Tiny 。よって SVG DOM には対応していない。
  • Opera 8 では SVG 要素を文書に追加 / 削除しただけでは描画に反映されない。そのあと要素の属性値などを変更する必要がある。
  • Canvas の save() / restore() はパスの線の太さ・色といった状態を保存 / 復元するのであって、描画された画像そのものを保存 / 復元するわけではない。

スタイル変更2005年09月27日 04時41分

これまでここのスタイルシートはあらかじめ用意されたものにちょっと手を加えただけだったが、一念発起して一から書き直し。色使いは以前のものとそう変わらず。でもちょっとあっさりした感じになったかと思う。

それにしても IE には散々てこずらされた。そのうち 5 割くらいはボックスが内容の大きさに合わせて拡張されるバグに起因すると思う。IE7 ではこれは是が非でも直してもらいたいところ。その他原因を追究する気にもならない症状も多々あり。バグを使ったブラウザ振り分けはできるだけしたくなかったのだが、何箇所かでアンダースコアハックを使った。

正直今 CSS を組むときの IE の存在というのは (IE6 の標準モードであっても) 、昔 CSS を組んでいたときの NN4 の存在に匹敵するような気がしてきた。(当時は IE5 だか IE5.5 だかに満足していたはずなのに……なぜだろう。)