これは何?
本モジュール「Canvas Filter Extention(cfe.js)」は,既存のHTMLCanvasElement(CanvasRenderingContext2D)を拡張し,canvas要素で描いたグラフィックに対し,svgのfilterを直接適用可能とします.
一般にsvg-filterをcss等からimg要素もしくはcanvas要素に適用した場合,その処理結果を保存することが出来ません.本スクリプトではこの処理結果を元のcanvas要素に書き戻すことにより,画像ファイルとして外部に保存することを可能としています.
特徴
フィルタ定義をsvgのfilter要素と同等に行うことが出来ます.また,filter要素に相当するSVGFilterElementオブジェクトを直接渡すことも出来るため,一般に煩雑なフィルタ定義を簡潔に記述・管理することが出来ます.
動作環境
- firefox,chromeのなるべく新しいもの.古いバージョンでは動作しません.
- ieでは動作しません.safariでも動作するとは限りません.
※なお,今後HTML5仕様の動向によっては本スクリプトが動作しなくなる可能性がある点にご注意下さい.
ライセンス
本スクリプトはMITライセンスのもとで自由に利用・配布が可能です.
使い方
ダウンロード
ここからjsファイルをダウンロードして下さい.
導入
任意のhtml文書にてcfe.jsを読みこむだけです.
api
本モジュールを読み込むことでcanvas要素のgetContext("2d")で得られるCanvasRenderingContext2Dオブジェクトに下記の関数が追加されます.
ctx.applyFilter(filter, callback, x, y, width, height)
filter
- 画像に施したいフィルタの設定オブジェクトを渡します.json形式かSVGFilterElementオブジェクトを渡すことが出来ます.
callback
- フィルタ処理が完了したあとで呼び出される関数オブジェクトを渡します.特に何もする必要がなければ
null
を渡します.
エラーが発生した場合は,引数にその内容が渡されます. x, y, width, height
- フィルタを掛けたい画像の範囲を指定します.省略すると自動的にcanvas全体にフィルタを掛けます.
filter指定の方法
filterパラメータの指定方法には(1)jsonによる方法,(2)SVGFilterElementによる方法の二つがあります.
-
json形式による方法
必要となるパラメータは全てsvgのfilter仕様に準じます.要素名としては
tagName
を,子要素としてはchildeNodes
をキーに与えて下さい.- 単体の原始フィルタのみの場合
{felist:{tagName: "feGaussianBlur", stdDeviation: "5"}}
- 複数の原始フィルタを重ねる場合
{felist:[ {tagName: "feGaussianBlur", stdDeviation: "5"}, {tagName: "feOffset", dx: "15", dy: "15"} ]}
- 子要素を持つ原始フィルタを指定する場合
{felist:{tagName: "feComponentTransfer", childNodes: {tagName: "feFuncR", type:"linear", slope:"-1", intercept:"1"} }}
{felist:{tagName: "feComponentTransfer", childNodes: [ {tagName: "feFuncR", type:"linear", slope:"-1", intercept:"1"}, {tagName: "feFuncB", type:"linear", slope:"-1", intercept:"1"} ] }}
- 単体の原始フィルタのみの場合
-
SVGFilterElementによる方法
適用したいfilterを予めhtmlドキュメント中に記述しておく方法です.例えば次のようなfilterを定義していたとします.
<svg display="none"> <defs> <filter id="gray"> <!--グレイスケール--> <feColorMatrix type="saturate" values="0" result="gray"/> </filter> </defs> </svg>
これをcanvasに適用する場合は次のようにします.
ctx.applyFilter(document.getElementById("gray"));
注意点
- 複数のフィルタを連続して施す場合は単一のfilter設定で済むようにするか,もしくはcallback関数内部でもう一度applyFilterメソッドを呼ぶようにします.applyFilterメソッドを連続して実行した場合,処理結果の重なりあいがおかしくなる場合があります.
- 本メソッドは本質的に重い処理を行っているため,パフォーマンスが優先されるような環境(例えば頻繁にcanvasを書き換えるもの)には向きません.
- canvasのorigin cleanフラグがfalseとなるような処理(外部画像をcanvasに描き込んだ場合など)を施すと,applyFilterメソッドはエラーを発生します.(これはcanvas要素そのものの仕様です.)
動作原理
本スクリプトではcanvas要素の中身を一旦svgファイルに挿入し,それを再度canvas要素に書き戻しています.その際にsvgファイル内部でフィルタを掛けているので,canvas要素で描いたグラフィックにあたかもフィルタが掛かったように動作します.
ブラウザによっては上記のようなsvg画像をcanvas要素に描き込んだ時にorigin cleanフラグがfalseに設定されるため,途中でセキュリティエラーを発生します(ie).このように,本スクリプトで利用しているテクニックはセキュリティ的な観点から将来的に利用できなくなる可能性があります.