2010年06月27日

Internet Explorer 9 Platform Preview 3 を試してみた。

先日の記事で書いたように、Internet Explorer 9 Platform Preview 3で Canvas エレメントが使えるようになったので、当ブログで公開したデモの動作を確認してみた。

lislis Painter

・ダイアログがドラッグできない。
・スライドバーも動かない。
これらjQuery uiを使っている部分のドラッグ&ドロップ系が全く動作しない模様。
いずれIEかjQueryのどちらかが改善すると思われるので対処しない。

・消しゴムをかけると真っ黒になる。
UNDOがなければ涙目レベルの不具合である。
var ctx = canvas.getContext("2d"); ctx.globalCompositeOperation = "destination-out"; と設定しても、現状の IE9 Preview が仕様通りに動作せず、無視されていることが原因。
これも時が解決することを期待して対処せず。

ArrowMark

正常に動作する。
特に問題は見つからない。

Wave

・波が全く動かない。
さらに、画像を何度クリックしても、最初にクリックした位置に動かない波が一定時間表示されるだけという状態になる。
動作を追いかけてみると、以下のような謎な挙動が原因と判った。

  1. 最初にImageData.dataを取得してピクセルを書き換える。←ImageDataの画像が書き換わる。
  2. 再度ImageData.dataを取得してピクセルを書き換える。←なぜかImageDataの画像が書き換わらない。
  3. 以下同文
これも IE9 Preview のバグと思われる。

Clock

特に問題はなく、きれいに表示される。
ちゃんと影が出るので、Chromeよりまともな動作と言える。

posted by lislis at 12:50| Comment(0) | TrackBack(0) | HTML5

2010年06月24日

IE9 Platform Preview 最新版がCanvasをサポート

最新版のInternet Explorer 9 Platform Preview で、ついに Canvas エレメントが使えるようになった模様。
参照→ HTML5, Native: Third IE9 Platform Preview Available for Developers
これで名実ともにCanvasを標準として扱っていけそうだ。
まだ試していないけれど、とりあえず速報。
posted by lislis at 07:15| Comment(0) | TrackBack(0) | HTML5

2010年05月02日

ExploerCanvasとFlashCanvasの比較表

HTML5のCanvasエレメントをInternetExplorerで使うための2つのライブラリ、ExplorerCanvasFlashCanvasの機能サポート状況を表にまとめてみた。

HTMLCanvasElement

  ExplorerCanvas FlashCanvas FlashCanvas Pro
width
height
getContext()
toDataURL() ×

CanvasRenderingContext2D

  ExplorerCanvas FlashCanvas FlashCanvas Pro
addColorStop()
arc()
arcTo() ×
beginPath()
bezierCurveTo()
clip() ×
closePath()
clearRect() △※引数を無視してCanvas全体を消去
createLinearGradient()
createImageData() × ×
createPattern()
drawImage() △※ソースはimageエレメントのみ △※ソースはimageエレメントのみ
fill()
fillRect()
fillStyle
fillText() ※要canvas-text ×
font ※要canvas-text ×
getImageData() × × ○※遅い
globalAlpha
globalCompositeOperation × ×
isPointInPath() × ×
lineJoin
lineTo()
lineWidth
measureText() ※要canvas-text ×
miterLimit
moveTo()
putImageData() × × ○※遅い
quadraticCurveTo()
rect()
restore()
save()
scale()
setTransform()
shadowBlur × ×
shadowColor × ×
shadowOffsetX × ×
shadowOffsetY × ×
stroke() ×
strokeRect()
strokeText() ※要canvas-text ×
textAlign × ×
textBaseline × ×
transform
translate()

その他

  ExplorerCanvas FlashCanvas FlashCanvas Pro
ライセンス オープンソース
(Apache License V2.0)
オープンソース
(The MIT License)
クローズドソース
(非営利使用は無償、商用使用は有償)
Canvas代替技術 VML Flash Player 9 Flash Player 10 (Flash Player 9 もサポート)

注意点

これらライブラリの使用により、Canvasエレメントを使ったページがすべて無改造で動くわけではない。
サポートされていない機能が使えないのはもちろんだけど、他にも細かい動作の違いは多々ある。
特に注意が必要なのは、document.createElement("canvas")などでCanvasを動的に生成する場合だ。
ExplorerCanvasなら var canvas = document.createElement("canvas"); document.getElementById("target").appendChild(canvas); if (typeof initElement != "undefined") { canvas = initElement(canvas); } FlashCanvasだと var canvas = document.createElement("canvas"); document.getElementById("target").appendChild(canvas); if (typeof FlashCanvas != "undefined") { FlashCanvas.initElement(canvas); } のようにおまじないが必要になる。
このおまじないは、CanvasエレメントをdocumentのDOMツリー内にバインドしてから行う必要がある。
Canvasエレメントをどこにもappendせずに作業用のフレームバッファとして扱いたい場合は面倒だ。


まとめ

lislis PainterをIE対応にできないものかと思って調べてみたけど、現状ではどちらも肝心な機能が欠けているので使えないと結論。
InternetExplorer 9のPreview版でも、Canvasをサポートしていないけど、正式版では対応してくれるといいなあ・・・

posted by lislis at 22:21| Comment(0) | TrackBack(0) | HTML5

2010年04月17日

lislis Paintの技術的説明まとめ

前記事の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版の各ブラウザでの動作結果が掲載されており、非常に参考になります。

posted by lislis at 14:35| Comment(0) | TrackBack(1) | HTML5

2010年04月13日

HTML5のCanvasでペイントツールを作る

今回はCanvasを利用したペイントツールを作った。
Wacomペンタブレットの筆圧感知にも対応した。
筆圧感知のためにはここから使用環境にあわせたプラグインをインストールする必要がある。

lislis Painter 1.04
lislis Paint Image
Show me
/ Download zip


機能について

Tools (ツール)

Brush (ブラシ)

ペン先が平坦なブラシツール
太さを1くらいにしてペンタブレットで描くと、鉛筆っぽいタッチになる。

Air Brush (エアブラシ)

輪郭がぼやけたブラシツール
※現状では色を塗り重ねると、グラデーションに段々が出たり、ブラシの縁が微妙に黒ずんで、まるでクリームを盛りつけたようになることがある。

Syringe (スポイト)

クリックすると表示されている画像から色を取得する。
alt+clickでも同様の動作。

Eraser (消しゴム)

透明色で塗るブラシ。
Brushと同じくペン先は平坦

Fill Rect (矩形塗りつぶし)

矩形領域を選択色で塗りつぶす。

Clear Rect (矩形消去)

矩形領域を透明色で塗りつぶす。

Paint Fill (領域塗りつぶし:バケツツール)

クリックした場所と同じ色の閉領域を塗りつぶす。
Paint Fillダイアログでいくつかの設定が可能。

  • Paint By:
    塗りつぶし時の参照レイヤを設定する。
    • Integrated Layer: (デフォルト)
      全てのレイヤを重ねた状態の(見たままの)画像を参照してペイントする。
    • Current Layer:
      現在の描画先レイヤを参照してペイントする。
    • Current Layer 1 or 2...:
      指定した番号のレイヤを参照してペイントする。
  • Antialias:
    アンチエイリアスをかける。デフォルトでONになっている。
    Brushツールで描いた線はアンチエイリアスがかかっているので、これをONにしないと塗りに隙間があいてしまう。
    細い線は塗りに削られて消えてしまうので、細い線で描いた領域を塗る場合は、レイヤ1に線を描いてレイヤ2でPaint Fillすると良好な結果を得られる。
  • Threshold:
    同色範囲のしきい値。
    Brushで塗りつぶした領域は色が均等でないため、全体を塗りつぶすにはこの値を10程度まで上げる必要がある。

Layers (レイヤ)

描画先のレイヤを選択する。
眼のアイコンでレイヤーの可視/不可視切り替え。

Edit (編集)

Undo (元に戻す)

直前の描画をキャンセルして元に戻す。
ctrl+zでも同様の動作。
※Operaではデフォルトで、ctrl+zを押すと直前に閉じたタブを開き直す機能が同時に働いてしまう。

Clear All (全消去)

全てのレイヤを消去する。
Undoで元に戻すことはできないので注意。

Post Image (画像投稿)

描いた絵をギャラリーページに投稿する。
投稿後は強制的にギャラリーページに移動する。

Color (色選択)

RGBもしくはHSLで描画色を選択する。
Aは描画色の透明度を指定する。

Brush (ブラシサイズ)

ブラシサイズの指定
四角い領域をクリックするとブラシサイズを変更できる。
1,2,4,8...と書かれたボタンをクリックすることでもサイズを選択できる。
このブラシサイズはBrush, Air Brush, Eraserに適応される。


互換性

Chrome 4.1: ○
FireFox 3.6.3: ○
Opera 10.51: ○
IE 8.0: ×

IEでは全く動作しない。ExplorerCanvasがサポートしていないImageDataやtoDataURLを使うことを最初から予定していたので、現行のIEへの対応はあきらめている。
Chrome、FireFox、Operaではいずれも正常に動作する。
ただ、ブラウザによって動作の重さや画質に違いがある。Operaでは特に消しゴムツールが重い。


今回のまとめ

欲しい機能はまだまだ一杯あるが、まずは自分が絵を描くのに最低限必要な機能だけ実装した。
追加したい機能としては、、レイヤー関係の統合・追加/削除、範囲選択(マスク)、直線描画など。
色選択はカラーホイールでも選択できるようにしたい。

エアブラシの画質が汚いのはCanvasのビット深度が8ビットなので致し方ない。
RGBAをそれぞれ実数で保持する仮想キャンバスに描画して、それをCanvasのImageDataに描画する形にすれば画質は改善されるだろう。
でも今のところそこまでやるつもりはなく、うまく誤魔化す方法を思案中。

あとはサーバ側のプログラム。
描いた絵をサーバにPOSTして保存するのは簡単なので、掲示板やSNSと組み合わせれば、ちょっとしたWebサービスが出来る。


本ソフトウェアはjQueryを使用しています。


追記:
Syringeはレイヤー上の色を取る仕様だったが、非常にわかりにくいので、実際に目に見えている色を取得するように変更した。


追記:
ツールにPaint Fill(Flood Fill)を追加


追記:
UIの一部をテキストからアイコンに変更。
色選択でHSLとRGBをタブで切り替えられるようにした。
レイヤの可視/不可視アイコン追加。


追記:
投稿機能と投稿画像ギャラリーを試験的設置。
クライアント側ではCanvas.toDataURL()でPNG形式のDataURLを取得し、jQuery.post()でサーバーに送信している。
サーバ側では、POSTされたデータがPNGのDataURLであることを確認して、DBに記録している。

posted by lislis at 19:07| Comment(7) | TrackBack(0) | HTML5