POPSブログ

SVG.js children() get()

386

  Category:  javascript2016/03/28 pops 
SVG.js children() get()について調べてみます。一部当方独自の方法をも取りますが、一応正常に可動します。何も知らない者が「SVG」を触るのですから大変無謀なことです。

 

SVG.js children getのテスト

 

ご注意、Chrome.Firefox.IE11(一部機能しません)などSVGに対応したブラウザでご覧ください。Chromeを推奨します。
このページのJSは「IE11」では実行出来ません。

 

SVG.js 使用の基本的な説明


基本的な説明下記ページ参照ください。
【参照】当方の記事: SVG.js を使用してsvgコンテンツを作り表示します

このページとデモページにサンプルと共にJSを記載しています。余り説明などしていませんので、感覚的に違いなど理解ください。
Chrome.Firefox.IE11で確認しながら進めますが、その他のブラウザは未確認です。

 

SVG.jsのDropShadowはエラーで機能しません。カスタムDropShadowは独自のもので、4個をdropshadow-custom.jsで設定している。

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


 

SVG.js children get について


エレメントの状況を調べて、特定のエレメントを指定するための処理方法であるが、多少問題となる所がある。
エレメント等の記述毎にchildren()にIDが追加されてゆきます。IDは特有の記述ですからタグ名などが判るよう妙名されています。(出力例参照)


1. 生成されるタグを良く認識しておく事が重要です。(出来ればデベロッパーツールなどで確認)
2. 最初にdefsが自動で挿入されることに注意ください。(説明には有りません)
3. children()はArrayで、中を見ると子要素の「ID」が収容されています。
4. SVG.jsのeach()メソッドを利用して、一括変更などの処理が便利です。
5. 状況に応じて、最良の処理が出来る様に考慮しますがグループ化した方が処理し易いようです。


SVG.js children書式

SVG.jsでは、インスタンス(要素)を表示する毎にchildrenとして管理されているので、あとでインスタンスを特定したい時など調べられるし、each()メソッドで一括して変更を処理できる仕組みがある。

children()はArrayですので注意ください、処理にはeach()メソッドを利用するのが便利であり、get()メソッドで要素を特定するのが確実です。

draw.each()等、draw層では注意が必要です。むしろgroup.each()等、グループ層での処理が確実ですから、処理し易く構成するのも大事です。何度か練習が必要かも知れません。


SVG.js マニュアル Child references 記載より


first()
To get the first child of a parent element:
draw.first()
returns: element

last()
To get the last child of a parent element:
draw.last()
returns: element

children()
An array of all children will can be retreives with the children method:
draw.children()
returns: array

each()
The each() allows you to iterate over the all children of a parent element:
draw.each(function(i, children) {
  this.fill({ color: '#f06' })
})

Deep traversing is also possible by passing true as the second argument:
// draw.each(block, deep)
draw.each(function(i, children) {
  this.fill({ color: '#f06' })
}, true)
Note that this refers to the current child element.
returns: itself

has()
Checking the existence of an element within a parent:
var rect  = draw.rect(100, 50)
var group = draw.group()

draw.has(rect)  //-> returns true
group.has(rect) //-> returns false
returns: boolean

index()
Returns the index of given element and returns -1 when it is not a child:
var rect  = draw.rect(100, 50)
var group = draw.group()

draw.index(rect)  //-> returns 0
group.index(rect) //-> returns -1
returns: number

get()
Get an element on a given position in the children array:
var rect   = draw.rect(20, 30)
var circle = draw.circle(50)

draw.get(0) //-> returns rect
draw.get(1) //-> returns circle
returns: element

clear()
To remove all elements from a parent element:
draw.clear()
returns: itself


children関連の簡単な説明

マニュアル通りで、一応は予測が付くと思いますが、has()、index()、get()、each() について補足説明しておきます。

● has()、index()
エレメント名としての rect circle 等である。現在実行のコードの中で、宣言無しならエラーに成る。
標準のタグ、<rect> <circle> <ellipse> <line> <polyline> <polygon> <path> <image>では無い。


次の様に実際宣言して使用されている時
違ったrectを描画する際も簡単なので同じインスタンス名rectを使用することが多い。ループの中なら尚更である。
記載順に表示はできるが、当然ながら同じ変数なので区別が付かず後で各要素を特定するのが難しくなる。


var rect=draw.rect(50,50)...
var rect=draw.rect(20,20)...
var rect=draw.rect(10,10)...
var circle=draw.circle(10)...

下記でも同じです。私は上の様に書いています。宣言無しなら.has(rect)などエラーに成るので注意。


var rect,circle
rect=draw.rect(50,50)...
rect=draw.rect(20,20)...
rect=draw.rect(10,10)...
circle=draw.circle(10)...

インスタンス名「rect」の存在を確認する。
(実際使用することは少ないと思いますが...)


draw層にrectはあるか、在れば true 無ければ false 数はわからない
draw.has(rect)

draw層にrectはあるか、順序は並び順とはかぎらない、なければ-1
draw.index(rect)
group層にrectはあるか、順序は並び順になり易い、なければ-1
group.index(rect)
もし、7を返せば8個存在すると考えられる

便利のようで以外と面倒な面もあるので事前の設計が大事である。構成、処理の都合により同じインスタンス名を使用出来ない場合もあります。


● get()
children()配列で何番目に保存されているか指定すれば、そのインスタンスを取得できるので、
get()の方がむしろ使い易い。グループに整然と要素が並ぶように設計をすれば「番号順」なので便利であると言える。
draw層は要素種類がマチマチであり、追加変更を考えれば間違い易いので余り使用したくは無い。
意図的に同種のものをグループ化した、group層では各要素特定の有効な手段となる。共に設計次第ではあるが....


draw層の場合最初はdefsに成るので注意(ジャマダと思う)
draw.get(0)
draw層に初めて書いた要素
draw.get(1)

group層の最初の要素
group.get(0)
group層の次の要素
group.get(1)

範囲を設定した場合は、最初が範囲のrectになるので注意
var group=draw.group()
group.rect(0,0,160,160)//get(0)に成る

● each()
jQueryのeach()とは異なります。単にchildren()配列の条件内で繰り返すだけの処理のようです。第二引数をtrueにすれば1段深い部分の処理が出来る。サンプル3番参照
i値、index()、get()などで判定、分類操作をして処理します。thisが機能します。forEach文と同様に途中でループを抜け出すことは出来ない様ですが、each()が在れば結構重宝です。


親要素の持つ子要素に対するeach()ですから、対象は親要素になります。
children()が存在しない場合はエラーになります。特にTEXT関連は注意ください。


指定層である親.each(function(i,children){
	//処理
	this....
})

サンプル、1番出力、最初にdefsがあることに注意ください。defsに収容するものが無くとも生成されます。


<div id="children-1a" class="graphic-elm">
<svg id="SvgjsSvg1000" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="160" height="160">
<defs id="SvgjsDefs1001"></defs>
<rect id="SvgjsRect1007" width="40" height="40" fill="#ff0000" rx="10" ry="10" x="10" y="60"></rect>
<rect id="SvgjsRect1008" width="40" height="40" fill="#0000ff" rx="10" ry="10" x="60" y="60"></rect>
<circle id="SvgjsCircle1009" r="20" cx="130" cy="80" fill="#ffff00"></circle>
<text id="SvgjsText1010" font-family="Helvetica, Arial, sans-serif"><tspan id="SvgjsTspan1011" dy="12.8" x="0">1</tspan></text>
</svg>
</div>

draw層ではdefsがあるので注意が必要です。1番目のrect要素はget(0)では無くget(1)である。これには非常にたまげた...

defsは勝手にSVG.jsが作って挿入しているものであるから、誰しも1番目のrect要素はget(0)で在ると思う。


draw層は処理し難い。


<defs></defs>		get(0)に成る
<rect></rect>		get(1)に成る
<rect></rect>		get(2)に成る
<circle></circle>	get(3)に成る

group層は整然として処理し易い。(但し、g直下に範囲指定のrectが入る場合もあるので注意)


<g>
<rect></rect>	get(0)に成る、first()でもある
<rect></rect>	get(1)に成る
<rect></rect>	get(2)に成る
<rect></rect>	get(3)に成る
<rect></rect>	get(4)に成る、last()でもある
</g>

get()で変更する。下記ではfill色が変わる。
(ドラッグ設定で、ドラッグ処理の相違で番号が変わる場合も有りますので注意)


draw.get(1).attr({fill:'#ccc'})
draw.get(2).attr({fill:'#f8f'})

全てrectなど同一のインスタンス名で処理すると便利ではあるが、反面メモリは増えますがインスタンス名が違えばスグに特定できる。この辺は人により考えが違うので使用者の自由ではある。


//rect
var rect=draw.rect(40,40)...
var rect=draw.rect(40,40)...
var rect=draw.circle(40)...

下記は、変数が増えるが、get()しなくともダイレクトに指定できる。一応設計者の好みだと思います。
(jQueryと違いますので、全て変数なしで処理を出来ない部分も有り、変数が必要な場合も結構あります)


//rect1-3
var rect1=draw.rect(40,40)...
var rect2=draw.rect(40,40)...
var rect3=draw.circle(40)...

//配列
var rects=[]
var rects[0]=draw.rect(40,40)...
var rects[1]=draw.rect(40,40)...
var rects[2]=draw.circle(40)...

children()はArrayであるから、下記の様にもなるが、一般的には利用しないでショウ。(.toString()無くとも良い様です)
ドラッグ操作の処理次第では、children()配列の順序が変わることが有ります。


children()からID配列を作成(コピー)
var svgjs_ids=[]
svgjs_ids=draw.children()
var str1=svgjs_ids[1]//.toString()

ID名からインスタンスをつくる。(このような方法もあるが、一般的には使わないと思う)


書式、ID名でエレメント(インスタンス)をつくる
var element=SVG.get(ID名)
であるから
var rect_elem=SVG.get(str1)

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

素直に書けば、下と同じです
var rect_elem=draw.get(1)

実際の処理サンプル

1番、のchildren()の内容を文字列にして下記に表示してみます。最初にdefsがあるのがわかる。


DATA


fillの変更を行ってみます。但し画像はアニメでないので変化ありません。(コード参照)
1番、children()の内容 / 2番、draw層のeach()処理/ 3番、第二引数trueのeach()処理


サンプルJS


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

	//rect
	var rect=draw.rect(40,40).attr({'fill':'#f00'}).radius(10).center(30,80)
	var rect=draw.rect(40,40).attr({'fill':'#00f'}).radius(10).center(80,80)
	var rect=draw.circle(40).attr({'fill':'#ff0'}).center(130,80)

	//jQuery
	var str=draw.children().toString()
	$('#showtext').text(str)

	var svgjs_ids=[]
	svgjs_ids=draw.children()
	var str1=svgjs_ids[1]//.toString()

	var element=SVG.get(str1)
	element.attr({'fill':'#CCC'})

	var txt=draw.text('1/ '+str1).font({leading:0.8})

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

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

	//image 100x100
	var image=draw.image('/main/images/testImage108.jpg').size(100,100).center(80,80)

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

	//rect
	var group=draw.group()
	var rect=group.rect(40,40).attr({'fill':'#00f'}).radius(10).center(80,120)
	.attr({'filter':'url(#dropShadow2)'})//陰影

	//children処理children.length()
	draw.each(function(i,children){
		this.attr({fill:'#f06'})
	})

	draw.get(2).attr({fill:'#fff'})

	var data_text=draw.text(''+draw.index(rect)).font({leading:0.8}).move(10,0)

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

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

	//image 100x100
	var image=draw.image('/main/images/testImage108.jpg').size(100,100).center(80,80)

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

	//rect
	var group=draw.group()
	var rect=group.rect(40,40).attr({'fill':'#00f'}).radius(10).center(80,120)
	.attr({'filter':'url(#dropShadow2)'})//陰影

	//children処理
	draw.each(function(i,children){
		this.attr({fill:'#f0f'})
	},true)

	var txt=draw.text('3').font({leading:0.8})


.each()の色変更テストである。each()処理でなくとも着色は出来るが、あえてeach()でやってみる。


//each()処理でなくとも着色は出来る
for (i=0; i < spikes; i++){

	//虹色hsl直接
	var angle_no=Math.floor(i/spikes*360)//0-360
	var color='hsl(' + angle_no + ',100%,50%)'

	var x=point_x+radius_v*Math.cos((i*a+angle12)*Math.PI/180)
	var y=point_y+radius_v*Math.sin((i*a+angle12)*Math.PI/180)
	//rect
	var rect=draw.rect(20,20).attr({'fill':color,'stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
	.attr({'filter':'url(#dropShadow2)'})//陰影
}

円周にrectを配置して、each()で色変更している。draw層にそのまま配置は「要素特定」が面倒であり、グループ化した場合は処理が簡単である例である。色環は赤色が12時方向になる様に90度修正して配置する。

ドラッグ設定の場合は現在の段階では90度の修正が出来ません。(問題あり)


4番、draw層defs考慮しないNG / 5番、draw層defs考慮する / 6番、group層処理、確実で簡単に色々出来る



サンプルJS


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

	var spikes,a,point_x,point_y,radius_v,angle12
	spikes=8,a=360/spikes,point_x=80,point_y=80,radius_v=50,angle12=-90 //12時補正

	//rect配置描画/12時補正
	for (i=0; i < spikes; i++){

		var x=point_x+radius_v*Math.cos((i*a+angle12)*Math.PI/180)
		var y=point_y+radius_v*Math.sin((i*a+angle12)*Math.PI/180)
		//rect
		var rect=draw.rect(20,20).attr({'fill':'#000','stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
		.attr({'filter':'url(#dropShadow2)'})//陰影
	}

	//children処理/defsを考慮しない
	draw.each(function(i,children){

		//虹色hsl直接
		var angle_no=Math.floor(i/spikes*360)//0-360
		var color='hsl(' + angle_no + ',100%,50%)'

		this.attr({fill:color})
	})

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

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

	var spikes,a,point_x,point_y,radius_v,angle12
	spikes=8,a=360/spikes,point_x=80,point_y=80,radius_v=50,angle12=-90 //12時補正
	var rects=[]

	//rect配置描画/12時補正
	for (i=0; i < spikes; i++){

		var x=point_x+radius_v*Math.cos((i*a+angle12)*Math.PI/180)
		var y=point_y+radius_v*Math.sin((i*a+angle12)*Math.PI/180)

		//rect
		var rect=draw.rect(20,20).attr({'fill':'#000','stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
		.attr({'filter':'url(#dropShadow2)'})//陰影
		rects[i]=rect

	}

	//defsが這いり込んで不正確だ
	//children処理
	draw.each(function(i,children){
		//defsは処理しない
		if(i > 0){
			//虹色hsl直接
			var angle_no=Math.floor((i-1)/spikes*360)//0-360
			var color='hsl(' + angle_no + ',100%,50%)'

			this.attr({fill:color})
		}
	})

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

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

	var spikes,a,point_x,point_y,radius_v,angle12
	spikes=8,a=360/spikes,point_x=80,point_y=80,radius_v=50,angle12=-90 //12時補正

	var group2=draw.group()

	//rect配置描画/12時補正
	for (i=0; i < spikes; i++){

		var x=point_x+radius_v*Math.cos((i*a+angle12)*Math.PI/180)
		var y=point_y+radius_v*Math.sin((i*a+angle12)*Math.PI/180)

		//rect
		var rect=group2.rect(20,20).attr({'fill':'#000','stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
		.attr({'filter':'url(#dropShadow2)'})//陰影

	}

	//children処理
	group2.each(function(i,children){

		//虹色hsl直接
		var angle_no=Math.floor(i/spikes*360)//0-360
		var color='hsl(' + angle_no + ',100%,50%)'

		this.attr({fill:color})
	})

	var elm=group2.get(4)
	elm.attr({fill:'#000'})


6番、children()の例
グループ範囲設定無しのグループなので、IDが整然と並んでいる。each()処理し易い形といえる。


SvgjsRect1026,SvgjsRect1027,SvgjsRect1028,SvgjsRect1029,SvgjsRect1030,SvgjsRect1031,SvgjsRect1032,SvgjsRect1033

7番、groupの範囲設定のためグループのrectが1個多くなっているのでそれを考慮する。特別な事情があり範囲を設定する場合がまれにあります。


var group3=draw.group()
group3.rect(0,0,160,160)//groupの範囲

 

ドラッグで重ね順の変更とget()

● ドラッグで重ね順を変更する場合の注意

ドラッグで重ね順を変更する場合、rect要素に角度があると「切れ」が発生しますのでグループ範囲を大きくしておく必要があります。その辺を考慮して作ったサンプルが3番です。(ドラッグで重ね順を1番上に)


1. 角度を付ける場合は注意が必要です。(12時方向の修正は出来ませんので、必要ならグループを回転します)
(主にドラッグ時の問題だが、12時方向の修正が原因とは考えが及ばなかった、ビビルなア)
2. ドラッグ後の切れを防止するため、グループ範囲を大きく設定しなければなりません。(切れは前ページのデモ参照)
3. ドラッグ前後のindexは取得のタイミングが重要です。draggable()内での取得値は正確でないため、get()で利用することは出来ません。
(dragstart、dragendでなら取得値が正確、但しドラッグ後は一番上に移動後ですから同じ数値です)
4. 各rect要素を特定するのに、並べ替えられてindexを利用できないので、事前に番号などをattr()しておきます。
(ドラッグしたインスタンスは常に this である、画像サムネール処理などは工夫が必要かナ)
5. 構造の違いにより違う設定にしなければならない事もあるかも知れません。(問題がでたら自己解決)


● ドラッグで重ね順を変更する場合のグループ範囲計算

ステージ中に配置する場合、要素に角度を付ける事を考慮すればグループ範囲の大きさは「ステージの対角線の長さ」を半径とする「大きさ以上」が必要になります。
グループ中央をステージ中央に合わせるように配置すれば、要素をステージのどこにドラッグ移動しても切れを発生しないようです。(最初の描画要素は3時方向になる、全体の回転は「必ずグループを回転」する事)
例では500x500の大きさにしています。これ以外の方法があるか不明。



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

//ドラッグ後のはindexは同じなので事前にNOなど書き込んでおく必要がある
var rect=group5.rect(40,40).attr({'fill':color,'stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
.attr({'no':i+1})
.draggable(function(x,y){

	//必要な処理も書ける
	this.front()
	var no=this.attr('no')
	d_txt.text('drag-no ' + no)
	//siblings文字列
	//var str=this.siblings().toString()

	return {x:x,y:y}
})

----------------------------------------------
最初のindex値
dragstartで取得できる

rect.on('dragstart.namespace', function(event){
	//index値
	var index_v=group5.index(this)

})
----------------------------------------------
最後のindex値
dragendで取得できる

rect.on('dragend.namespace', function(event){
	//index値は同じ値
	var index_v=group5.index(this)
})

下記は構造を略して記述したものです。
最初の、#SvgjsRect1093 は範囲のためrect要素をドラッグしても位置の変更はありません。
rect要素はドラッグすれば一番下(重なりは一番上)に移動します。


<g id="SvgjsG1092" transform="matrix(1,0,0,1,-170,-170)">
<rect id="SvgjsRect1093" width="0" height="0"></rect>
<rect id="SvgjsRect1094" width="40" height="40"></rect>
<rect id="SvgjsRect1095" width="40" height="40"></rect>
<rect id="SvgjsRect1096" width="40" height="40"></rect>
<rect id="SvgjsRect1097" width="40" height="40"></rect>
<rect id="SvgjsRect1098" width="40" height="40"></rect>
<rect id="SvgjsRect1099" width="40" height="40"></rect>
<rect id="SvgjsRect1100" width="40" height="40"></rect>
<rect id="SvgjsRect1101" width="40" height="40"></rect>
ドラッグthis.front()でここに移動する(index値は同じ値、この例では8)
</g>

siblings()の値はどの要素で取得してもその時点(ドラッグ)での同じを返します。その値はグループのchildren()と同じArray値です。つまりその時点での並び順の配列で、toString()すれば「ID名リスト」に成ります。
要するに、thisからchildren()値を取れるように工夫したもののようです。


siblings()もIDのARRAY
children()値と同じ
SvgjsRect1093,SvgjsRect1094,SvgjsRect1095,SvgjsRect1096,SvgjsRect1097,SvgjsRect1098,SvgjsRect1099,SvgjsRect1100,SvgjsRect1101

7番、groupの範囲設定 /8番、指定位置を別色で染める /9番、each()処理無しのグループ化とドラッグ


サンプルJS


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

	var spikes,a,point_x,point_y,radius_v,angle12
	spikes=8,a=360/spikes,point_x=80,point_y=80,radius_v=50,angle12=-90 //12時補正

	var group3=draw.group()
	group3.rect(0,0,160,160)//groupの範囲
	//rect配置描画/12時補正
	for (i=0; i < spikes; i++){

		var x=point_x+radius_v*Math.cos((i*a+angle12)*Math.PI/180)
		var y=point_y+radius_v*Math.sin((i*a+angle12)*Math.PI/180)

		//rect
		var rect=group3.rect(20,20).attr({'fill':'#000','stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
		.attr({'filter':'url(#dropShadow2)'})//陰影

	}

	//children処理
	group3.each(function(i,children){
		if(i>0){
			//虹色hsl直接
			var angle_no=Math.floor((i-1)/spikes*360)
			var color='hsl(' + angle_no + ',100%,50%)'

			this.attr({fill:color})
		}
	})

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

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

	var spikes,a,point_x,point_y,radius_v,angle12
	spikes=12,a=360/spikes,point_x=80,point_y=80,radius_v=55,angle12=0 //12時補正

	var group4=draw.group()
	//rect配置描画/12時補正
	for (i=0; i < spikes; i++){

		var x=point_x+radius_v*Math.cos((i*a+angle12)*Math.PI/180)
		var y=point_y+radius_v*Math.sin((i*a+angle12)*Math.PI/180)

		//rect
		var rect=group4.rect(20,20).radius(5).attr({'fill':'#000','stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a+30)
		.attr({'filter':'url(#dropShadow2)'})//陰影

	}

	//children処理
	group4.each(function(i,children){

		if(i==0||i==3||i==6||i==9){
			this.attr({'fill':'#F00'})
		}else{
			this.attr({'fill':'#CCC'})
		}

	})

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

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

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

	//角度補正は行わないこと
	var spikes,a,point_x,point_y,radius_v,angle12
	spikes=8,a=360/spikes,point_x=250,point_y=250,radius_v=50,angle12=0 //3時方向

	var group5=draw.group()
	group5.rect(0,0,500,500)

	//each()処理でなくとも着色は出来る
	for (i=0; i < spikes; i++){

		//虹色hsl直接
		var angle_no=Math.floor(i/spikes*360)//0-360
		var color='hsl(' + angle_no + ',100%,50%)'

		var x=point_x+radius_v*Math.cos((i*a+angle12)*Math.PI/180)
		var y=point_y+radius_v*Math.sin((i*a+angle12)*Math.PI/180)
		//rect
		var rect=group5.rect(40,40).attr({'fill':color,'stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
		.attr({'no':i+1})
		.attr({'filter':'url(#dropShadow2)'})//陰影
		.draggable(function(x,y){

			//必要な処理も書ける
			this.front()
			//識別番号
			var no=this.attr('no')
			d_txt.text('drag-no ' + no)
			//siblings文字列
			//var str=this.siblings().toString()

			return {x:x,y:y}
		})
		rect.on('dragstart.namespace', function(event){
			//index値
			var index_v=group5.index(this)
		})

	}
	group5.x(-170).y(-170)//.rotate(-90)


 

children()が作られない場合もある

● children()が作られない場合もあります。これは特殊です。
下記は、中に文字数分「tspan」を入れていますが children() は作られていません。そのため個々の文字を特定できません。
これはadd処理であることも起因して特殊なようです。Firefoxでの振舞いも違いがある。



var tspan=... にしても children() は作られていませんのでeach()処理はエラーになる。


意味が無い
var tspan=add.tspan(tx).attr({'dx':-10,'fill':color,'stroke':'#FFF','stroke-width':1})

そこで、tspan要素をtspans[]に取り込んで、色変更を行いました。Firefoxで陰影を個別に処理できません。


サンプルJS


	//対象エレメントID
	var draw=SVG('svgtext-5a').size(640,100)

	//ストリング
	var main_strings="Merry Christmas 2016.dazo"

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

	var tspans=[]

	//カーニングと着色
	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%)'

			var tx=main_strings.charAt(i)
			//add.tspan(tx).attr({'dx':-10,'fill':color,'stroke':'#FFF','stroke-width':1})
			tspans[i]=add.tspan(tx).attr({'dx':-10,'fill':color,'stroke':'#FFF','stroke-width':1})
		}
	})

	//色替え、Firefox陰影個別に処理出来ない
	for (i=0; i < spikes; i++){
		if(i>14){
			tspans[i].attr({'fill':'#888'})
		}
	}

	//move位置移動と陰影
	k_text.move(50,15)
	.attr({'filter':'url(#dropShadow)'})//Firefox対策

	var txt=draw.text('TEXTにchildren()は有りません').font({leading:0.8})


 

サンプルJSの全表示

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

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

使用画像

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

使用画像サンプル

 


 

dropshadowは当方自作の dropshadow-custom.js を使用します。
なおこのページはjQuery1.6.4のため dropshadow-custom-ie.js に成ります。

DropShadowと基本的なことは下記記事を参照ください。

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

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


以上。

 


[ この記事のURL ]


タグ:javascript , SVG

 

ブログ記事一覧



[1]