CSS custom filters (CSS shaders) が Chrome canary の about:flags で有効化できるようになって から 1 年たったので現状メモ。 とはいえ、1 年前から対応が広がったものの、あまり新しいことができるようにはなっていない。
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1652.0 Safari/537.36
- CSS Shaders with WebGL カスタムフィルタを HTML2Canvas + WebGL でシミュレートする。 WebGL Inspector などの、WebGL のデバッグに使うものが使えるようになるので便利
- [library] customfiltergl.coffee - jsdo.it 拙作、上の使えばいいと思うけど、blend mode / alpha compositing に対応している
- WebGLTools/GL-Shader-Validator Sublime Text 用のシェーダのバリデータ、便利っぽい
- CSS FilterLab
バグっぽいの見つけたので回避策も書いておく。環境依存かもしれない。
→ div とかでくるんでそこに filter を指定すればインラインフレームの中でも問題なく効く。
→ Flash など埋め込んであると効かない (thanks: GeckoTang)。
→ <style>
要素挿入するようにする。
# だめ
addFilterInline = (filterString) ->
$('#target').css {
WebkitFilter: filterString
filter: filterString
}
# これなら大丈夫
addFilterAsStyleElement = (filterString) ->
$('<style>').text("""
#target {
-webkit-filter: #{filterString};
filter: #{filterString};
}
""").appendTo(document.head)
つまりこのような状態。
この場合、フィルタが効いている #target
は、シアン色でなければいけないはずだが、
style.background = 'red'
するとフィルタが解消されてしまうのがわかる。
またほかにも、Developer Tools を開いたり閉じたりしたときに解消されてしまうこともある。
しかもその間、大量のスタイル再計算が発生しており、CPU に負荷がかかるので危ないとおもう。
Dev Tools の Timeline タブを見ると、この環境では 1 フレームに 150 回くらい recalculate style してる。
回避策 → [style]
ルールに対しても filter
を設定する
上の場合では
#target[style] { -webkit-filter: custom( ... ); }
/* #target, #target[style] { ... } としてもなぜか効かない */
とすればよい (デモ)。
chromium の該当 issue の例が簡潔。 Support Matrix ではチェックされていて、パースはしてくれるみたいだけど、対応していない。 状態によってパラメータ (uniform 変数) だけ変化させるということが簡単になりそう。
mat2()
, mat3()
, mat4()
, texture()