前記事のlislis Painterについての技術的説明のまとめ。
同種のプロダクトを作成する方々の参考になれば幸いだ。
Fill Paint (Flood Paint)機能について
現在のHTML5標準では同色塗りつぶしの機能がない。
一部ブラウザの独自実装にはあるようなので、将来的には標準化される可能性が高い。
lislis Painterではどうしているかというと、ImageDataを取得して、シードフィルアルゴリズムで塗りつぶしを行っている。
これで、Chrome、FireFox、Opera、SafariのいずれでもPaint Fillが使えるようになっている。
初めは画面全体をgetImageDataして、ペイントした後にputImageDataで描き戻せばいいと思っていたけれど、これだと問題があった。
ChromeではgetImageDataして、そのままputImageDataで描き戻すだけで、色が微妙に変わってしまうのだ。
1回では気づかないくらいの微妙な変化だけど、ペイントを繰り返すと誤差が蓄積して全く違う色になっていってしまう。
これを回避するためには、新しく透明なCanvasを作り、そこに描画して、描画レイヤにdrawImageしてやる必要がある。
将来的には不要になりそうなバッドノウハウの類だけれど、ご参考までに。
レイヤについて
単純に同じサイズのCanvasエレメントを重ねて表示しているだけ。
レイヤを統合するときには、まず統合用のCanvasを生成して、下のレイヤから順番にdrawImageして合成する。
これは非常に簡単なやりかたで、動作も軽い。
レイヤの可視/不可視、レイヤごとの透明度指定などは簡単にできる。(未実装だけど)
反面、乗算/スクリーン/オーバーレイなどの合成モードの設定はできない。
Undoについて
描画した領域をgetImageDataしてImageDataをUndoバッファとして保存。
Undoするときは、新しいImageDataから順番にputImageDataでレイヤに描き戻す。
getImageData/putImageDataにはブラウザによって微妙な誤差があり、少しだけ色が変わったりぼやけたりする問題が発生する。
Undoではあまり目立たないので、この誤差には目をつぶっている。
今回のまとめ
以上、lislis Painter 1.02までの開発で、注意が要りそうだった部分を簡単にまとめた。
全般的に、Canvasの描画精度の低さには気をつけないと、どんどん誤差が蓄積して絵が荒れていくので要注意。
追記:
putImageData、drawImageの画質劣化について、Serendip様が各環境での詳細な検証をされています。
Mac版/Windows版の各ブラウザでの動作結果が掲載されており、非常に参考になります。