POPSブログ

SVG.js プラグインsvg.filter.jsバージョンアップでDropShadowを処理

391

  Category:  javascript2016/08/26 pops 

SVG.js プラグインsvg.filter.js が去る、2016/03/02、v2.0.2 にバージョンアップしていました、以前のJSでは、DropShadowが処理できませんでしたのが修正され、マニュアルも充実されています。

 

SVG.js プラグインsvg.filter.js DropShadowのテスト

各種メソッド、クラスなど明らかになりましたので、DropShadowおよび各種filterの表示テストを行ってみます。


ご注意、Chrome.Firefox.IE11(一部機能しません)などSVGに対応したブラウザでご覧ください。Chromeを推奨します。

 

filter.js DropShadowのテストと問題点


前にも説明していますが、以前のプラグインsvg.filter.jsマニュアル記載のDropShadowのサンプル例ではエラーが出ますので使用できませんでした(説明なし故、修正を試み解決するに長い時間が掛かった)。ところが、当方家庭の事情で2ヶ月ほど取り込み中で、バージョンアップに気づいたのが1ヶ月半前。不具合なども解消されましたので、エライ遅れてですが早速テストします。

新しくなっても、問題が無い訳では有りませんので....


1. DropShadowの問題は新バージョンで、ほぼ解決されました。色々作れますダ。
2. Filter範囲拡張は問題点を見極めての使い分けが重要です。
3. やはり、SVGに関する基礎知識が必要です、SVG.jsでテスト実行して見ます。
4. svg()メソッドの使用も結構便利で、ブラウザでの対応の簡単なテストにもなります。
5. Firefoxでの問題が発生しますが、また2年ほど待てば良いのではと思います。
(処理が厳格か、バグか、未対応なのか、などさっぱり判らない事が多い)
6. マニュアル記載のサンプルは書式で、実際の作動するサンプルは有りません。NETを探してもほぼ見つかりません。
(個人が実際に作り確認が必要であり、間違っても参考になるものは現在有りませんので、ナヤンデクダサイ)
7. テストではTEXTを除きほぼ draggable() 設定して、ドラッグの確認をしています。


 

簡単な説明


新しいsvg.filter.js(v2.0.2)を使用する


SVG.js プラグインsvg.filter.jsは svg.filter.js で取得ください。同ページにマニュアルもあります。
当方の都合で、このページでは、svg.filter.v2.jsと名前を変えて使用しています。


Blend処理でDropShadowを作る

早速、マニュアル記載のサンプルのDropShadowを作ってみます。その他のfilterに関しては、次回にテストしてみます。
早い話1番のDropShadowさえあれば99%困らないと思います。その他は付録です。


万歳、DropShadowが正常に動作する

1番、エラー無しのDropShadow / 2番、SourceGraphicのblend方式 / 3番、分離しFilterエリア数値で拡張


サンプルJS


	//対象エレメントID
	var draw=SVG('sample-shadow-1a').size(160,160)

	//TEXT
	var text=draw.text('祝い、標準DropShadow').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#00F','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//blend方式/gaussianBlur()バグが取れた
	.filter(function(add) {
		var blur=add.offset(20,20).in(add.sourceAlpha).gaussianBlur(5)
		add.blend(add.source,blur)

		//this.size('200%','200%').move('-50%','-50%')
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK

	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-1b').size(160,160)

	//TEXT
	var text=draw.text('blend source source').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//blend方式/バグが取れたので簡単になる
	.filter(function(add) {
		var blur=add.offset(10,10).in(add.source).gaussianBlur(3)
		add.blend(add.source,blur)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-1c').size(160,160)

	//TEXT
	var text=draw.text('blend 分離し数値で拡張').font({leading:0.8})

	var shadow_id//ID保存用

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//blend方式/数値で拡張
	.filter(function(add){
		var offset=add.offset(5,5).in(add.sourceAlpha)
		var blur=add.gaussianBlur(3).in(offset)
		add.blend(add.source,blur)
		//数値で拡張
		this.attr({'filterUnits':'userSpaceOnUse','x':-100,'y':-100,'width':400,'height':400})//IE OK /FirefoxfilterUnits属性必要
		//ID保存
		shadow_id=this.attr('id')
	})

	//circle
	var circle=draw.circle(60,60).attr({'fill':'#FF69B4','stroke':'#FFF','stroke-width':2}).center(80,80)
	//陰影使い回し
	.attr({'filter':'url(#'+ shadow_id +')'})


● SVG.jsマニュアル、以前、DropShadowサンプルを実行すればエラーになりました。(解決方を見つけたが必要なくなりました)

新しいsvg.filter.js(v2.0.2)では問題なく処理できます。ビールでも飲んで祝ってください。

SVG.js、標準DropShadowの書式 (以前と同じです)、サンプル1番参照。


var rect=draw.rect(100,100).radius(10).attr({'fill':'#00F','stroke':'#FFF','stroke-width':2}).center(80,80)

//blend方式/gaussianBlur()バグが取れた
.filter(function(add) {
	var blur=add.offset(20,20).in(add.sourceAlpha).gaussianBlur(5)//以前はエラー
	add.blend(add.source,blur)

	//this.size('200%','200%').move('-50%','-50%')
	this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
})
-----------------------------------------

svg.filter.jsでは
SourceAlpha は sourceAlpha で指定します
SourceGraphic は source で指定します

その他にもありますが、svg.filter.js先頭を参照ください

以上の実行でサンプル1番の様になります。生成されたSVGはdefsに収容されます。問題があれば別の形になりますし、拡張範囲設定が悪いと陰影が切れてしまいます。各要素のID名等は自動でSVG.js固有のものが付けられます。


実際のコード記述は「ストリング」なため、add.sourceAlpha、add.source と成ります。
SVG生成時はキチンと SourceAlpha SourceGraphic に変換されますので安心ください。


.in(add.sourceAlpha)
.in(add.source)

effect は add を付けずに記述します。IE、Chromeは add を付けても実行しますが、厳格なFirefoxは実行しません。
Firefoxが実行しない時はこの辺をよく再確認ください。また出力されるSVGをチェックするのも方法です。


var blur=add.........
add.blend(add.source,blur)

.in(blur)

● effectを分離して処理する場合は、共に最初 in() 処理で「受け渡し値」等を設定します。(3番参照)

メソッドチェーンが上手く行かない場合は、分離して処理するれば解決することが多い。「受け渡し値」が正確か確認の事。
(まだメソッドチェーンは完全では無い様ですから、問題があれば分離するのが得策です)


//分離して処理
.filter(function(add){

	//effectを2つに分離して処理
	var offset=add.offset(5,5).in(add.sourceAlpha)
	var blur=add.gaussianBlur(3).in(offset)
	add.blend(add.source,blur)

})

● TEXTに陰影処理の場合は「Filter範囲拡張」は不要です....。
マニュアルにその様なサンプル例があります。実際数例のテストではoffsetが小さい事もあり問題は出ていませんが、陰影が切れれば「%範囲拡張」設定なり必要と思います。(数値設定の場合IEで上手く処理出来ない事があります)


var text=text....
.filter(function(add) {

	処理略す

	//文字はFilter範囲拡張は不要とあるが
	//キレルなら必要です
	//this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})

})

TEXTの場合Fontフイールドの大きさが結構あるから「Filter範囲拡張」は無くとも良いと判断したものと思います。


通常の陰影は、SourceAlpha(黒)で処理されますが、SourceGraphicを指定すれば、2番の様になりますが透明度は考慮されません。指定色の陰影、透明度変更は、5番6番を使用ください。


sourceAlphaをsourceに変更する

var blur=add.offset(10,10).in(add.source).gaussianBlur(3)

● sourceとblurの合成は以前、blend方式でしたが、新たに、merge方式でも処理できます。書き方に注意。

最後の重ね合わせはどちらも問題は出ません。この場合、どちらかといえばblend方式が使い易い。
merge() は重ねのみだが2つ以上の リザルト、エフェクト を重ね処理出来る特徴がある(サンプル7番参照)。


//blend方式
.filter(function(add) {
	var blur=add.offset.........
	add.blend(add.source,blur)

})

-------------------------------------------------

//merge方式
.filter(function(add) {
	var blur=add.offset.........
	add.merge(blur,add.source)

})

● Filter範囲拡張「%」の場合、.size().move()処理は、IE11で上手く処理できなく、陰影が切れます。下記の様に修正すれば解決する。(IE11はSVG対応は貧弱ですから、その内姿を消すでしょう)、「DropShadowの問題点」参照。


//IEが処理しない
this.size('200%','200%').move('-50%','-50%')
-------------------------------------------------

//object形式なら全てでOK
this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK

● Filter範囲拡張「数値」の場合、.attr()処理を行うと、Firefoxで陰影が切れるなど問題がでますので、下記の様に修正します。FirefoxはfilterUnits属性が必要に成りますので注意ください。(SVG.jsでは「%」で拡張することを前提にしており、標準でfilterUnits属性を付けるようにはなっていません)、サンプル3番参照。

注意、Filter範囲拡張「%」の場合、filterUnits属性が在れば「エラー」に成ります。


//FirefoxはfilterUnits属性が必要成ります
this.attr({'filterUnits':'userSpaceOnUse','x':-100,'y':-100,'width':400,'height':400})//IE OK
this.attr({'filterUnits':'userSpaceOnUse','x':0,'y':0,'width':400,'height':400})//IE OK

● svg()メソッドの使用で、参考サイトなどのFilterを実行出来ますので、実際に動作するか等テストできます。svg.filter.jsのメソッドなどに変換させる場合の参考にもなるでショウ。注意、処理の方法次第では表示しない場合も有ります。


.filter(function(add) {
	this.svg('filterタグを除いたHTML部分を記載する')
})

関数にマトメて効率化

通常、DropShadowは比較的多く設定使用すると思いますが、その都度長くかくのは大変効率が悪いのでまとめてみます。
下記サンプル1番目参照。

● DropShadow filter 設定の効率化

DropShadow設定を関数化して少し効率的にします。filter設定は標準で%設定にしています。作り方は自由です。
出来たfilterは固有のID名を付与されて、defsに順に登録されます。このままの状態での再利用は出来ません。


//(instance,x,y,deviation,extension)
//extension=true false 'none'/falseと設定なき%設定/true数値設定/'none'は属性設定をしない

//filter数値拡張設定
createDropShadow(rect,10,20,10,true)
//filter%拡張設定
createDropShadow(rect,10,20,10)
createDropShadow(rect,10,20,10,false)
//filter属性設定なし
createDropShadow(rect,10,20,10,'none')

------------------------------------------

//DropShadow設定の効率化
function createDropShadow(instance,x,y,deviation,extension){
	//filter
	instance.filter(function(add) {
		var blur=add.offset(x,y).in(add.sourceAlpha).gaussianBlur(deviation)
		add.blend(add.source,blur)
		if(extension=='none'){return}
		//拡張
		if(!extension){
			this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
		}
		if(extension){
			this.attr({'filterUnits':'userSpaceOnUse','x':-100,'y':-100,'width':800,'height':800})//Firefox OK
		}
	})
}

1番目は効率化 / 番外、ご苦労様DropShadow / SourceGraphic


サンプルJS



	//効率化
	//対象エレメントID
	var draw=SVG('kouritu-shadow-1a').size(160,160)

	//TEXT
	var text=draw.text('効率化1 通常処理OK').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#FFD700','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//陰影処理
	//(instance,x,y,deviation,extension)
	//extension=true false 'none'/falseと設定なき%設定/true数値設定/noneは属性設定をしない
	createDropShadow(rect,5,5,10,true)

	//-------------

	//対象エレメントID
	var draw=SVG('gokurousama-1').size(160,160)

	//TEXT
	var text=draw.text('ご苦労様DropShadow').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#BC8F8F','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ


	//blend方式DropShadow
	.filter(function(add){
		var offset=add.offset(5,5).in(add.sourceAlpha)
		var blur=add.gaussianBlur(3).in(offset)
		add.blend(add.source,blur)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('gokurousama-2').size(160,160)

	//TEXT
	var text=draw.text('SourceGraphic').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#BC8F8F','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//blend方式/Source色
	.filter(function(add){
		var offset=add.offset(5,5).in(add.source)
		var blur=add.gaussianBlur(3).in(offset)
		add.blend(add.source,blur)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})


 

旧バージョン用のDropShadow

旧バージョン用に作った .filter(function(add){...}) 形式のDropShadowですが、使う事無くお蔵入りになり幻と消えました。
よって、カッコヨク「ご苦労様DropShadow」と呼びます。新バージョンでも動作しますが無意味な事です。
「役立たずDropShadow」或いは「不能DropShadow」では無いかと言えばその通りです。


● 番外、「ご苦労様DropShadow」は以前のDropShadowを動作するようにしたもので、必要がなくなりました。
以前は、マニュアルサンプルなし故、結構時間がかかったので残念。新バージョンでも動作します。
(ご苦労様ですから「暑中残暑見舞い」に一応記載しておく、笑えるナ)


下記の様に、gaussianBlur()を分離したら動作しました。(以前、詳細説明なしのためヨク判らなかった)


メソッドチェーンでない場合は、in値をin()で指定します

//blend方式
rect.filter(function(add){
	var offset=add.offset(5,5).in(add.sourceAlpha)
	var blur=add.gaussianBlur(3).in(offset)//Firefox処理OK
	add.blend(add.source,blur)

	this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
})

下記処理 .in(add.offset) はリザルト値 offset に「...function」が入り、厳格なFirefoxは処理出来ませんので注意

IE、Chromeは実行するのでマチガイに気づかない。問題があればデベロッパーツールでSVG出力を確認して原因を掴む必要があります。ほとんどはコードの記述マチガイが多いと思う。


rect.filter(function(add){
	var offset=add.offset(5,5).in(add.sourceAlpha)
	var blur=add.gaussianBlur(3).in(add.offset)//マチガイ
	add.blend(add.source,blur)
	this.attr(......)
})
-----------------------------------------

var blur=add.gaussianBlur(3).in(offset)
が正しい

メンドウならsvg()で作れば簡単です。間違いなく処理するサンプルをパクッテsvg()の中に入れるだけ。この便利さには驚く。
但し、余りにも簡易に書かれたSVGではFirefoxで実行出来ない場合があります。


//メンドウならsvg()で作れば簡単OK
.filter(function(add){
	this.svg('<feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/><feOffset in="blur" dx="5" dy="5" result="offsetBlur"/><feMerge><feMergeNode in="offsetBlur"/><feMergeNode in="SourceGraphic"/></feMerge>')

	this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
})



関連の付随説明など


/// 以後、興味のある方のみお読みください。///


Filterの使い回しと別形式のDropShadow

新しい別形式のDropShadowと問題点などについてのテスト結果です。


作ったFilterの使い回し

● 作ったFilterは url(#) で使い回しが可能です。
簡単にFilterを作れますが、同じFilterを複数個所で使用する場合、その都度書くのもメンドウです。
1. 作ったFilterは、即座に「defs」に登録されますので、以後、Filterの「ID名」が判れば再利用出来ます。
2. グローバルな変数に、Filter「ID名」を保存しておけば、url(#)で簡単に再利用できます。
3. 直接、出力のID名は使用しないでください。コードなど書き換えた際、名前が変わり易い。
次の様にID名を保存すれば良い。実際サンプルは、「サンプル3番」になります。


グローバルな変数にID名を保存
var shadow_id//ID保存用

Filter処理の中でID名を取得
.filter(function(add){

	filter処理は略す

	//ID保存
	shadow_id=this.attr('id')
})


陰影使い回し、画像  レクト などを描画する
var rect=draw.circle(60,60).......
.attr({'filter':'url(#'+ shadow_id +')'})

● svg()を利用してFilterをHTMLでdefsに登録して利用する。但しその都度記述しなければならないので面倒ですが、
ID名は自由に書けるので都合が良い。外部JSの形式で読み込みも可能のようです。

早い話、「パクリもの」も簡単に登録、利用できると言う事です。(svg構成次第ではそのまま利用できない場合もあり)

これを少し変えたものが、従来のjQuery処理をSVG.js処理で行う「従来の読み込みDropShadowをSVG.jsで作る」です。


//defs
var defs=draw.defs()
//ID/dropShadow
defs.svg('<filter id="dropShadow"/>HTML構成を記載</filter>')
必要に応じて記述する

----------------------------------------------------

利用する場合
.attr({'filter':'url(#dropShadow)'})

現時点での問題などの詳細は、下記「DropShadowの問題点」を参照ください。


形式違いのDropShadowなどの処理サンプル

マニュアルも充実してきましたので、DropShadowも形態の違うものも作ってみました。(また新しいFilter処理等は次ページで...)

SVGに関する基礎知識は、下記サイト記事、サンプルなどを参考にしました。
とは言え、サンプルの大半はこちらサンプルのパクリですが...

【参考】www.h2.dion.ne.jpの記事: svg要素の基本的な使い方まとめ、画像効果


● 陰影色を指定する場合、flood()とcomposite()を利用すると便利
メソッドチェーンで、flood-composite-marge と連結すれば良いのだが、重なり具合も変ですし、他に影響が出る恐れもある。
(途中margeが上手く処理できず、Firefox表示出来ない、その内に直るかも....)
よって、flood-composite-blend としました....サンプル、5番6番参照。

SVG2規格のfeDropShadowを利用すれば、DropShadow色も設定が簡単になりまが、まだSVG.jsでは未対応です。

1. flood()で指定色に変更。透明度設定可。
2. composite()でマスク。


flood-composite-blend方式で処理


//途中の.merge(add.source)実行はNG/Firefox表示出来ない、他にも影響あり

------------------------------------------------------

flood-composite-blend方式で処理は問題なし

//色、透明度、offset、Blurの設定/mergeの代用で、blendさせた
var blur=add.flood('#00F',0.5).composite(add.sourceAlpha,'in').blend(add.source).offset(10,10).gaussianBlur(5)

feDropShadowを svg()方式でテストできます。


//feDropShadow svg()方式 OK/IE未対応
.filter(function(add) {
	this.svg('<feDropShadow dx="5" dy="5" stdDeviation="3" flood-color="blue" flood-opacity="0.5"/>')

	this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
})

色々なDropShadowも簡単に作れる

色々なDropShadowも簡単に作れる様になりました。慣れないと大変ですが....、パクリも芸の内です。

DropShadowは色々あっても。1.5.6番、の3種類があれば事足りると思います。
5番、画像でも効果的になります。


4番、新marge方式で重ねる / 5番、flood-composite-blend / 6番、Floodは指定色に変える


サンプルJS


	//対象エレメントID
	var draw=SVG('sample-shadow-1d').size(160,160)

	//TEXT
	var text=draw.text('新marge方式重ね').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#00CED1','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//marge方式
	.filter(function(add) {
		//blur
		var blur=add.offset(5,5).in(add.sourceAlpha).gaussianBlur(3)
		//var blur=add.gaussianBlur(3).in(add.sourceAlpha).offset(5,5)//こちらもOK
		//margeでかさねる
		add.merge(blur,add.source)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-1e').size(160,160)

	//TEXT
	var text=draw.text('flood-composite-blend').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#555','stroke':'#F00','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//
	.filter(function(add) {

		//色、透明度、offset、Blurの設定/blendさせた
		var blur=add.flood('#00F',0.5).composite(add.sourceAlpha,'in').blend(add.source).offset(10,10).gaussianBlur(5)
		//mergeはこの形が無難
		add.merge(blur,add.source)
		//blendで重ねの場合
		//add.blend(add.source,blur)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-1f').size(160,160)

	//TEXT
	var text=draw.text('flood-composite').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#CCC','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//flood(color,opacity)
	.filter(function(add){

		//mergeでsourceを重ねていないのでopacityは1
		var blur=add.flood('#00F',1).composite(add.sourceAlpha,'in').offset(5,5).gaussianBlur(5)
		//blend
		add.blend(add.source,blur)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK

	})


flood-composite-marge のメソッドチェーンは機能しません

5番をmergeでチェーンするのは問題がある。下のサンプルAB参照ください。(blendするほうが無難、将来的に直るか不明)
A. 正しくmergeされてない。B. 分離して処理すればOKですが、重なりの順に注意。 / C. B方式での画像の場合。


A
これがあると、他の処理も遅延して表示しないなどの影響がでることもある様です
説明用のキャプチャー画像を表示しています
//途中の.merge(add.source)実行はFirefoxダメなので使えない/使用しないほうが無難
var blur=add.flood('#00F',0.5).composite(add.sourceAlpha,'in').merge(add.source).offset(10,10).gaussianBlur(5)

-------------------------------------------------
B
//分離して処理OK
var flood=add.flood('#00F',0.2).composite(add.sourceAlpha,'in')
var blur=add.merge(add.source,flood).offset(10,10).gaussianBlur(5)

-------------------------------------------------
merge、offsetの順序を反対にしないでください、他のステージまで影響が出る
//絶対ダメ
var blur=add.flood('#00F',0.5).composite(add.sourceAlpha,'in').offset(10,10).merge(add.source).gaussianBlur(5)

A、merge処理部分を調べ、簡略して列記すれば以下のようである。inに正しい値が入っていない。Firefox以外は曖昧であっても処理するが、Firefoxは厳格であるから処理しない。バージョンが変わればその内に直るでショウ。
表示しているのはステージ大のキャプチャー画像で、正しくmerge()されてはいない。


<feMerge>
<feMergeNode in="SvgjsFeComposite1076Out"></feMergeNode>
<feMergeNode in="[object Arguments]"></feMergeNode>
</feMerge>

NG

1. NGで在るが、feMergeNodeにSourceGraphicを入れるように修正してみる。メソッドチェーンなのでfeMergeNodeの特定はメンドウである。サンプル自体が単に思い付きで意味のないものだろう。

2. この構造では、this.get(2).get(1)でインスタンスを得ることが出来るので、attr()でSourceGraphicを入れる。
mergeのためrectの灰色が上に重なり、青はみえない。

3. rectの色をrgba(255,0,0,0.5)にすれば透過するので、ある程度効果は出るようである。

一応は修正は可能のようだが、確実かどうかの判定が出来ないので、余り薦めるものではない。(影響ないように感じるが)


.filter(function(add) {

	var blur=add.flood('#00F',0.5).composite(add.sourceAlpha,'in').merge(add.source).offset(10,10).gaussianBlur(5)
	//重ね
	add.merge(blur,add.source)

	//修正/Firefox OK
	var merge_child=this.get(2).get(1)
	merge_child.attr({'in':'SourceGraphic'})

	this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
})

--------------------------------------------------
2番目のNode
<feMergeNode in="[object Arguments]"></feMergeNode>
を無理やり下の様に書き換えているだけ
<feMergeNode in="SourceGraphic"></feMergeNode>

● メソッドチェーンは有り難いが、Firefoxで上手く処理出来ない場合がある。マニュアルにも記載があるがまだ完全ではない。デベロッパーツールで生成されるHTMLを確認して修正すればある程度直せる。現在は「苦労シナハレヤ」と言う事です。


A Firefoxチェーンは処理できずNG(下記表示は全て画像です) / B 分離しての処理はOKである / C 画像にした場合


サンプルJS


	//flood-composite-mergeテスト
	//対象エレメントID
	var draw=SVG('merge-test-1').size(160,160)

	//キャプチャー画像を表示する
	draw.image('/main/images/dk_zu522.jpg')

/*
	//影響があるので実行しない
	//TEXT
	var text=draw.text('A flood...marge ダメ').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'rgba(255,0,0,0.5)','stroke':'#F00','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//Firefox処理できず
	.filter(function(add) {

		//途中の.merge(add.source)実行はFirefoxダメなので使えない/他もおかしい
		var blur=add.flood('#00F',0.5).composite(add.sourceAlpha,'in').merge(add.source).offset(10,10).gaussianBlur(5)
		//重ね
		add.merge(blur,add.source)

		//修正は可能のようだが
		//var merge_child=this.get(2).get(1)
		//merge_child.attr({'in':'SourceGraphic'})

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})
*/

	//-------------

	//flood-composite-mergeテスト2
	//対象エレメントID
	var draw=SVG('merge-test-2').size(160,160)

	//TEXT
	var text=draw.text('B flood...marge OK').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#555','stroke':'#F00','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//FirefoxOK
	.filter(function(add) {

		//分離して処理OK
		var flood=add.flood('#00F',0.5).composite(add.sourceAlpha,'in')
		var blur=add.merge(add.source,flood).offset(10,10).gaussianBlur(5)
		//重ね
		add.merge(blur,add.source)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//flood-composite-mergeテスト3
	//対象エレメントID
	var draw=SVG('merge-test-3').size(160,160)

	//TEXT
	var text=draw.text('C flood...marge 画像').font({leading:0.8})

	//var rect=draw.rect(100,100).radius(10).attr({'fill':'#555','stroke':'#F00','stroke-width':2}).center(80,80)
	//image
	var image=draw.image('/main/images/testImage102.jpg').size(100,100).center(80,80)
	.draggable()//ドラッグ

	//FirefoxOK
	.filter(function(add) {

		//分離して処理OK
		var flood=add.flood('#00F',0.5).composite(add.sourceAlpha,'in')
		var blur=add.merge(add.source,flood).offset(10,10).gaussianBlur(5)
		//重ね
		add.merge(blur,add.source)

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})


●Flood、Morphology、など新たにマニュアルに追加解説になったクラスを利用して、サンプルを作成してみました。
7番は途中blendしていません。(Firefox OKです)
8番はfeMorphology処理に拠る「Morphed text outline」です。
9番はstrokeの幅が大きいだけです。

7番、ネオン風Shadow / 8番、文字のMorphology拡張 / 9番、DropShadow組み合わせ


merge

7番、ネオン風グロー効果を大きくする。
黒地に明るい色をぼかして重ねると、透明度1でも色が薄くなり余り判りませんが、merge()の際にblurを多く重ねれば色が濃くなります。使用色と目的により調整ください。


//merge重ね/blurを多く重ねれば濃くなる
add.merge(blur,add.source)
//add.merge(blur,blur,add.source)
//add.merge(blur,blur,blur,add.source)

サンプルJS


	//対象エレメントID
	var draw=SVG('sample-shadow-1g').size(160,160)

	//back-rect
	var back_rect=draw.rect(160,160).attr({'fill':'#000'})
	//TEXT
	var text=draw.text('flood-composite').font({fill:'#FFF',leading:0.8})

	//SVG文字
	var text=draw.text('POPS').attr({'fill':'#E0FFFF'}).move(80,60)
	.font({
		family:'Arial'
		,'size':50
		,'font-weight':'bold'
		,anchor:'middle'
		,leading:1
	})

	//ネオン風グロー効果
	.filter(function(add) {
		//色、透明度、offset、Blurの設定
		var blur=add.flood('#00FFFF',1).composite(add.sourceAlpha,'in').offset(0,0).gaussianBlur(10)
		//merge重ね/blurを多く重ねれば濃くなる
		add.merge(blur,add.source)
		//add.merge(blur,blur,add.source)

		//this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-1h').size(160,160)

	var backrect=draw.rect(160,160).attr({'fill':'#F0F8FF'})

	var text_group10=draw.group()
	text_group10.rect(0,0,160,160)

	//SVG文字
	var logo_text10=draw.text('POPS').attr({'fill':'#F00','stroke':'#00F','stroke-width':2})
	.font({
		family:'Arial'
		,'size':50
		,'font-weight':'bold'
		,anchor:'middle'
		,leading:1
	})

	//morphology
	logo_text10.filter(function(add){

		//Firefox修正radius値文字形のこと
		var morphology=add.morphology('dilate','3').in(add.sourceAlpha)
		var cmatrix=add.colorMatrix('matrix','-1 0 0 1 0, 0 -1 0 1 0, 0 0 -1 1 0, 0 0 0 1 0').in(morphology)
		add.merge(cmatrix,add.source)//merge
		//add.blend(add.source,cmatrix)//blend
	})

	text_group10.add(logo_text10)
	text_group10.attr({'filter':'url(#dropShadow)'})//陰影

	logo_text10.move(80,60)

	//TEXT
	var text=draw.text('feMorphology').font({leading:0.8})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-1i').size(160,160)

	var backrect=draw.rect(160,160).attr({'fill':'#F0F8FF'})

	//TEXT
	var text=draw.text('StrokeとDropShadow').font({leading:0.8})

	var text_group11=draw.group()
	text_group11.rect(0,0,160,160)

	//SVG文字
	var logo_text11=draw.text('POPS').attr({'fill':'#F00','stroke':'#FFF','stroke-width':3})
	.font({
		family:'Arial'
		,'size':50
		,'font-weight':'bold'
		,anchor:'middle'
		,leading:1
	})

	//Firefox radius値文字形のこと
	logo_text11.filter(function(add){

		//mergeでsourceを重ねていないのでopacityは1
		var blur=add.flood('#F00',1).composite(add.sourceAlpha,'in').offset(0,0).gaussianBlur(3)
		//blendする
		add.blend(add.source,blur)

	})

	text_group11.add(logo_text11)
	text_group11.attr({'filter':'url(#dropShadow)'})//陰影

	logo_text11.move(80,60)


従来の画像Filterの動作確認

従来の hue colorize posterize 等の画像処理Filterが有りましたが、新しいバージョンでも全て正常動作を確認しました。
【参照】当方の記事: SVG.js filterとDropShadow


標準DropShadowの検証

「標準DropShadow」での設定値変更と、各種グラフイック、画像等に処理した場合の検証テストです。別段問題は無いような気がします。振る舞いが明らかになっていますので、問題が出ればすぐ解決するでしょう。


blend方式DropShadow、「%」で拡張しています。ドラッグ出来ます。

10番、 / 11番、 / 12番、


サンプルJS


	//対象エレメントID
	var draw=SVG('sample-shadow-2a').size(160,160)

	//TEXT
	var text=draw.text('blend offset(5,5) blur(3)').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#DAA520','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(5,5).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-2b').size(160,160)

	//TEXT
	var text=draw.text('blend offset(5,5) blur(10)').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#9370DB','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(5,5).in(add.sourceAlpha).gaussianBlur(10)
		add.blend(add.source,blur)
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-2c').size(160,160)

	//TEXT
	var text=draw.text('blend offset(0,0) blur(3)').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#3CB371','stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()//ドラッグ

	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})


13番、画像塗りグループ化 / 14番、 / 15番、


サンプルJS


	//対象エレメントID
	var draw=SVG('sample-shadow-2d').size(160,160)

	//TEXT
	var text=draw.text('画像塗り グループ').font({leading:0.8})

	//グループ
	var group1=draw.group()
	var image=draw.image('/main/images/testImage101.jpg').size(160,160).center(80,80).scale(100/160)
	//画像塗り
	var rect=draw.rect(100,100).radius(10).attr({'fill':image,'stroke':'#FFF','stroke-width':2}).center(80,80)
	group1.add(rect)
	.draggable()//グループドラッグ

	//blend方式DropShadow/グループ
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//SVG.jsメソッド
	//対象エレメントID
	var draw=SVG('sample-shadow-2e').size(160,160)

	//TEXT
	var text=draw.text('グラデ塗り').font({leading:0.8})

	var gradient2=draw.gradient('linear',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#008B8B')
	})

	//translate0.5中心に移動
	gradient2.scale(0.25).rotate(30).translate(0.5,0.5)
	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect2=draw.rect(100,100).radius(10).attr({'fill':gradient2,'stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()

	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})
	

	//-------------

	//ラインパターンで塗る
	//対象エレメントID
	var draw=SVG('sample-shadow-2f').size(160,160)

	var text=draw.text('パターン塗り グループ').font({leading:0.8})

	//X図形10x10パターン登録
	var rect_defs=draw.defs().path('M 0 0 L 10 10 M 10 0 L 0 10 Z')

	//グループ
	var group2=draw.group()
	//1
	var rect=draw.rect(100,100).attr({'fill':'#BA55D3'}).center(80,80)
	group2.add(rect)//下の背景
	//2
	var patn_rect=draw.rect(100,100).attr({'fill':'none','stroke':'#FFF','stroke-width':2}).center(80,80)
	//pattern
	var pattern=draw.pattern(10,10,function(add) {
		//パターンを重ねる
  		add.use(rect_defs).attr({'fill':'none','stroke':'#ccc','stroke-width':1})//ライン
	})
	//パターン塗りの実行
	patn_rect.attr({fill:pattern})

	group2.add(patn_rect)//グループ
	.draggable()
	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})


DropShadowのfilter拡張設定の問題点

一応、DropShadowを描画できますが、設定次第では問題が発生しますので、状況に応じて「的確な拡張設定」を行います。


peke

 

● %拡張設定で個別陰影処理した場合に、インスタンスが小さい、単独の水平、垂直のラインの場合などで、「陰影キレ」「 消滅」が起こりえます(7番参照)。グループにして陰影処理すれば正常になる事が多い。
「数値」設定拡張処理では起こらない。よって幾らか大きめに設定している。

%拡張設定 個別陰影処理 NG 陰影キレル 消滅 グループ陰影 OK


rectは等キレル場合がある

this.attr({'x':'-50%','y':'-50%','width':'200%','height':'200%'})
-------------------------------------------------
groupはキレルない場合が多い

this.attr({'x':'-50%','y':'-50%','width':'200%','height':'200%'})

-------------------------------------------------

%拡張設定に、filterUnits:userSpaceOnUse設定はしないでください、停止します

小さなものなら「数値」設定が無難です。


filterUnits:userSpaceOnUse設定は「数値」のみ
this.attr({'filterUnits':'userSpaceOnUse','x':0,'y':0,'width':400,'height':400})

● 数値拡張処理の場合は、16番の様な「陰影キレル」「消滅」は起こりませんが、拡張の設定、構造、移動の設定などの理由で「陰影キレ」が起こる場合があります。(17番参照)


//1陰影キレル
var rect=draw.circle(4,4).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(80,40)
//blend方式DropShadow
.filter(function(add){
	var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
	add.blend(add.source,blur)

	this.attr({'x':'-50%','y':'-50%','width':'200%','height':'200%'})
})

-------------------------------------------------

xyマイナス方向設定なら切れない
this.attr({'filterUnits':'userSpaceOnUse','x':-100,'y':-100,'width':400,'height':400})

● 数値拡張処理の場合、size().move()で処理するとIEで認識されず「陰影キレ」が起こります。(18番参照)


//IE陰影キレル
var rect=draw.rect(100,100).radius(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(80,80)
//blend方式DropShadow
.filter(function(add){
	var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
	add.blend(add.source,blur)

	this.size('200%','200%').move('-50%','-50%')//IE NG
})

-------------------------------------------------

attr設定ならOK
this.attr({'x':'-50%','y':'-50%','width':'200%','height':'200%'})//IE OK

16番、%拡張設定で「陰影キレ消滅」 / 17番、数値拡張設定で「陰影キレ」 / 18番、size().move()はIE NG


サンプルJS


	//問題点
	//対象エレメントID
	var draw=SVG('sample-shadow-3a').size(160,160)

	//TEXT
	var text=draw.text('blend 陰影キレル').font({leading:0.8})

	//1陰影キレル
	var rect=draw.circle(4,4).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(80,40)
	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)

		this.attr({'x':'-50%','y':'-50%','width':'200%','height':'200%'})//IE OK
	})
	//2見えない
	var line=draw.line(50,80,150,80).attr({'fill':'none','stroke':'#00F','stroke-width':1}).center(80,80)
	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)

		this.attr({'x':'-50%','y':'-50%','width':'200%','height':'200%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-3b').size(160,160)

	//TEXT
	var text=draw.text('blend 陰影キレル').font({leading:0.8})

	//translate陰影キレル
	var rect=draw.rect(100,100).radius(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).translate(30,30)
	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)

		this.attr({'filterUnits':'userSpaceOnUse','x':0,'y':0,'width':400,'height':400})
	})

	//-------------

	//対象エレメントID
	var draw=SVG('sample-shadow-3c').size(160,160)

	//TEXT
	var text=draw.text('size move設定 IE NG').font({leading:0.8})

	//IE陰影キレル
	var rect=draw.rect(100,100).radius(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(80,80)
	//blend方式DropShadow
	.filter(function(add){
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(10)
		add.blend(add.source,blur)

		this.size('200%','200%').move('-50%','-50%')//IE NG
	})


大きなTEXTに設定した場合の例

TEXT部分のDropShadowは「Filter範囲拡張」は行っていません。このサンプルではoffset値が小さいので問題はないようです。必要があれば範囲拡張はしなければならない。

TEXT-1、TEXT-3、は新しいDropShadowでそのままテキストに陰影を掛けます。
TEXT-2は文字をMorphology拡張、グループに読み込みのDropShadow処理をしています。
共に何ら問題は無いようです。

TEXT-1、


TEXT-2、文字のMorphology拡張、東京五輪ピック2020


TEXT-3、


サンプルJS


	//TEXT-1
	//エレメントID
	var draw=SVG('svgtext-fliter-1a').size(640,100)

	//文字描画
	var text1=draw.text('POPSWEB KOUBOU')
	.font({
		family:'Arial'
		,size:50
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})

	//move暫定値で配置
	text1.attr({fill:'#00CED1','stroke':'#FFF','stroke-width':1}).move(70,25)

	.filter(function(add) {
		var blur=add.offset(0,0).in(add.sourceAlpha).gaussianBlur(3)
		add.blend(add.source,blur)
	})

	//-------------

	//TEXT-2
	//エレメントID
	var draw=SVG('svgtext-fliter-1b').size(640,100)

	//ストリング
	var main_strings="ViVa Tokyo Golympic 2020!"
	//グループ
	var text_group=draw.group()

	//空文字
	var k_text=draw.text('')
	.font({
		family:'Times New Roman'
		,size:65
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})
	//add
	text_group.add(k_text)

	//カーニングと画像塗り
	var spikes=main_strings.length
	k_text.text(function(add) {
		for (var i=0; i<spikes;i++){

			//虹色hsl直接
			var angle_no=Math.floor(i/spikes*360)//0-360
			var color='hsl(' + angle_no + ',100%,50%)'
			//1文字
			var tx=main_strings.charAt(i)
			add.tspan(tx).attr({'dx':-10,'fill':color,'stroke':'#CCC','stroke-width':1})
			//ここでのfilter、Firefox対応していません
		}
	})

	//move位置移動
	k_text.move(50,15)

	.filter(function(add) {

		/*
		var blur=add.offset(2,2).in(add.sourceAlpha).gaussianBlur(5)
		add.blend(add.source,blur)
		*/

		//morph
		var morphology=add.morphology('dilate','3').in(add.sourceAlpha)
		var cmatrix=add.colorMatrix('matrix','-1 0 0 1 0, 0 -1 0 1 0, 0 0 -1 1 0, 0 0 0 1 0').in(morphology)
		add.merge(cmatrix,add.source)//merge
		//add.blend(add.source,cmatrix)//blend
	})

	text_group.attr({'filter':'url(#dropShadow2)'})//陰影

	var txt=draw.text('2 カーニングと虹色塗り move位置移動').font({leading:0.8})

	//-------------

	//TEXT-3
	//エレメントID
	var draw=SVG('svgtext-fliter-1c').size(640,100)

	//文字描画
	var text3=draw.text('POPSWEB KOUBOU')
	.font({
		family:'Arial'
		,size:50
		,'font-weight':'bolder'
		,anchor:'left'
		,leading:1
	})

	//move暫定値で配置
	text3.attr({fill:'#DC143C','stroke':'#FFF','stroke-width':1}).move(70,25)

	.filter(function(add) {
		var blur=add.offset(4,4).in(add.source).gaussianBlur(2)
		add.blend(add.source,blur)
	})



 

● defsに収容する場合。
単なる収容場所のためか「SVG-HTML記述部分」が曖昧でも、Firefoxで処理してくれる場合が多い。もし、filterタグに必要な属性があれば事前に設定しておく。SVG.jsで未対応でも記述できますネ。
どちらかと言えばこの方式が一応安心です。ブラウザ毎の確認は必要です。


//defs収容方式の一例
var defs=draw.defs()
defs.svg('<filter id="papipupepo" color-interpolation-filters="sRGB"> SVG-HTML記述部分 </filter>')

//呼び出し
.attr({'filter':'url(#papipupepo)'})

そのほか、簡単な例。但し、filter関数内では上手くゆくとは限らないので注意。

19番、svg処理 / 20番、svg処理 / 21番、SVG2規格、feDropShadow IE未対応


サンプルJS


	//対象エレメントID
	var draw=SVG('svg-filter-1a').size(160,160)

	//TEXT
	var text=draw.text('svg処理1').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#CD5C5C','stroke':'#FFF','stroke-width':2}).center(80,80)

	//svg方式補正
	.filter(function(add){
		var offset=add.offset(5,5).in(add.sourceAlpha)
		var blur=add.gaussianBlur(3).in(offset)
		//svg方式
		this.svg('<feMerge><feMergeNode /><feMergeNode in="SourceGraphic" /></feMerge>')

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('svg-filter-1b').size(160,160)

	//TEXT
	var text=draw.text('svg処理2').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#87CEFA','stroke':'#F00','stroke-width':2}).center(80,80)
	//svg方式
	.filter(function(add){
		this.svg('<feOffset result="offOut" in="SourceGraphic" dx="10" dy="10"/><feColorMatrix result="matrixOut" in="offOut" type="matrix" values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0"/><feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="5"/><feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>')

		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})

	//-------------

	//対象エレメントID
	var draw=SVG('svg-filter-1c').size(160,160)

	//TEXT
	var text=draw.text('feDropShadow IE未対応').font({leading:0.8})

	var rect=draw.rect(100,100).radius(10).attr({'fill':'#C71585','stroke':'#FFF','stroke-width':2}).center(80,80)

	//feDropShadow svg()方式 OK/IE未対応
	.filter(function(add) {
		this.svg('<feDropShadow dx="5" dy="5" stdDeviation="3" flood-color="blue" flood-opacity="0.5"/>')
		this.attr({'x':'-100%','y':'-100%','width':'400%','height':'400%'})//IE OK
	})


 

従来の読み込みDropShadowをSVG.jsで作る

今回のバージョンアップ以前は、DropShadow処理は困難なため、ページ欄外にライブラリーの様にJSで読み込み利用する形で、DropShadow処理をしていました。

今回のバージョンアップまでは、DropShadowを処理するのが困難でしたので、url()で処理していましたが、簡単に設定できますのでそのままにしておきます。おそらく90%以上はこちらで設定することが多いと思いますが、.....


とにかく設定が簡単です。数多い箇所にDropShadow処理するには効率が良い。


.attr({'filter':'url(#dropShadow2)'})

従来はjQueryで作っていましたが、jQueryのバージョンによって処理が違いましたが、下記のものは、SVG.jsで作っています。このページ以前はすべてこの形式でした。


1. 使用頻度の高いDropShadowの形は、登録のものを利用する。
2. 特別な形のDropShadowはその都度作る。
3. 下記の様に、JSの形で登録して読み出すのが簡単と思います。(他にも方法があるが、以外とメンドウです)


多少の工夫が必要と思います。


SVG.jsで作る

SVG.jsはID名が自動で挿入されますので、場合により競合しますから、ID名を意図的に強制補正して、競合を防ぎました。
自動で処理されるので、競合が怖いので作れませんでした。jQueryと違い、1つのJSで処理できますし、一応テスト結果は良好ですが、絶対に間違いない保障はありません。また中の要素へのアクセスはセキュリティ上困難です。


SVG.js処理用ですから、svg.jsを読み込み後にsvg-dropshadow.jsを読み込みます。ほぼjQuery用をSVG.js処理用に置き換えただけです。jsの名前は自由です。


<script type="text/javascript" src="js/svg.js"></script>
<script type="text/javascript" src="js/svg-dropshadow.js"></script>

追加などあれば、内容を書き換えて保存します。ここでは svg-dropshadow.js としました。
読み込み時期で問題がでるので、addEventListener方式に修正しました。2016/09/10


実際はoffset値とblur値を変え、ID名をつけて保存するだけです、それ以外の処理はしないでください

defs.svg('<filter id="dropShadow"/>HTML構成を記載</filter>')

---------------------------------------
//svg-dropshadow.js
(function(window) {

	function svgShadowSet() {

		//DIV-BOX/大きさ0
		var divElm=document.createElement("div");
		divElm.setAttribute("id","svg-dropshadow-box");
		divElm.setAttribute("width",0);
		divElm.setAttribute("height",0);
		//append-body
		document.body.appendChild(divElm);

		//------------------------------------

		//SVG.jsコード
		var draw=SVG('svg-dropshadow-box').size(0,0)//0 問題あれば1
		draw.style({'opacity':0,'overflow':'hidden'})//非表示

		//defs
		var defs=draw.defs()
		//ID/dropShadow
		defs.svg('<filter id="dropShadow"/>HTML構成を記載</filter>')


		//切れ防止用
		//ID/drop-shadow2
		defs.svg('<filter id="drop-shadow2">HTML構成を記載</filter>')


		//------------------------------------

		//idを強制修正/競合防止
		defs.attr({'id':'svg-dorpshadow-defs'})
		draw.attr({'id':'svg-dorpshadow-stage'})

	}

	window.addEventListener("load", function loadHandler(evt) {
		removeEventListener("load",loadHandler);
		svgShadowSet();
	});

})(window);

登録のDropShadowをレクトに処理すれば下記図の通りです(ページ容量の都合)。書き換えは自由になります。

私の場合この3種があれば、ほぼ間に合います。必要なFilterは自由に登録できます。

shadow

 

svg-dropshadow.jsの全表示

Chromeは文字化けしますのでエンコード(UTF-8)してご覧ください。

● SVG.jsでつくる読み込みdropshadowの全表示 svg-dropshadow.js


サンプルJSの全表示

Chromeは文字化けしますのでエンコード(UTF-8)してご覧ください。

● サンプルJSの全表示1(解説ページ用) svg-sample18.js

使用画像

画像は原則使用者が用意ください。デモなどで使用した画像は下記に有ります。

使用画像サンプル

 


 

このページではテストのため、上記で説明の、読み込みsvg-dropshadow.jsを使用しています。

アニメーション書式などは下記の記事を参照ください参照ください。

【参照】当方の記事: SVG.js を使用してsvgコンテンツを作り表示します

【参照】当方の記事: SVG.js DropShadowの自作とBlur


 

以外とFirefoxで手間取ります。Firefoxに対応させないと専門家から笑われます。以上です。



[ この記事のURL ]


タグ:SVG , javascript

 

ブログ記事一覧



[1]