2013年3月7日木曜日

svgのd操作を使ったcanvas要素のユーティリティー

canvas要素は一般にラスタ画像を描くものとして認識されていますが,apiが提供している描画操作にはベクタ的なものも多く,見方を変えるとcanvas要素はベクタ画像を描くと考えてもおかしくありません.その為,svgとcanvasとの間の相互変換を考えられなくはありません.

そこでcanvasによるパス操作をsvgの仕組みを利用し,バッチ化するスクリプトを作って見ました.なお,svg2や最新のcanvas要素において,似たような仕組みの導入(apiの改善・拡張)が検討されており,将来的にはより標準的な手法で同様のことが行えるようになるかも知れません.

canvas要素の課題


html5で導入されたcanvas要素を用いると,webページ上で様々なグラフィックを描くことが可能となるのですが,使いこなしていくうちに様々な課題も見えてきます.例えば描画したグラフィックを再利用したい場合です.canvas要素での描画処理は全てjavascriptのコード内部に記述されているため,再利用を考慮していなかった場合には中々難しいケースがあります.

その一方でsvgでは当初からコードの再利用を促す仕組みがたくさん定められており,様々な場面に対応出来るように設計されています.例えばpath要素のd属性はパス図形をコマンドの羅列として表しているため, 図形の形状を再利用することが容易です.

そこで,canvas要素に対するパス図形の定義をこのd操作で行えたらどうか?と考えました.そうすれば,ドローイングツールで生成した図形を簡単にcanvas要素に描画できる筈です.

補足)
この考え方は既にcanvas要素の仕様に記述されています.※なおサポートする環境は不明です
またcanvg.jsを使えば既に同様の事を行うことが可能です.

実際に作ってみた


この考え方のもと,実際に作ってみたものが下です.

また,canvas要素へのpath操作をd属性文字列として記録するスクリプトも作って見ました.

※いずれも,簡単な検証しかしていませんのでバグがあるかも知れません.

雑感


アイディア自体は単純だったのですが,やはり一筋縄では行きませんでした.
  • 円弧の定義がsvgとcanvasとで大いに異なる.
    svg・・・起点と終点を与える
    canvas・・・中心と開始角・終了角を与える
    その為,相互変換するためには足りないパラメータを算出する必要がある.
    また,arcメソッドとarcToメソッドの二つに対処しなければならない.
    →この問題は円弧をベジェ曲線で近似することで回避されます.
  • canvas要素では標準apiだけでは終点の位置を取得することが出来ない.
  • canvas要素ではtransformによる座標軸の変形をいつでも行える.
    従ってd操作にcanvasでの操作を記録するにあたっては,常に座標変換を意識しなければならない.
  • canvas要素のarcToメソッドの挙動がブラウザによってバラバラ
    なので,実装が面倒.
結論) 同様の事を自作する場合は,心して掛かったほうが良い.特に円弧の考え方の違いは非常に面倒な問題を引き起こす.

0 件のコメント:

コメントを投稿