POPSブログ

SVG.js GradientとPatternについて(追加)

390

  Category:  javascript2016/08/01 pops 
SVG.js GradientとPatternについては別ページでも書いているが、同心円Gradientなど追加の事柄である。当方独自の方法をも取りますが、一応正常に可動します。何も知らない者が「SVG」を触るのですから大変無謀なことです。

 

SVG.js GradientとPatternについて(追加)の表示のテスト

 

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


このページは下記ページの追加です。SVG.js GradientとPatternについて基本的な説明等は下記ページ参照ください。
【参照】当方の記事: SVG.js グラデーションとパターン

SVGグラデーションとパターンの基礎的な解説は、「svg要素の基本的な使い方まとめ」の下記記事が参考になります。
【参考】h2.dion.ne.jpの記事: グラデーションとパターン

 

 

SVG.js GradientとPatternについて


時間も経過すると、理解も進み、未熟故以前は出来なかった事も可能になるものである。よって、GradientとPatternについて追加の表示のテストを行います。SVGの場合は実際作らないと判らない事が多いので閉口する。
陰影、ドラッグ処理も問題が出やすいのでテストする。問題がある場合は共に「グループ」でラップすれば解決する事が多い。
また、SVG.jsのメソッドでは簡単な操作しか出来ずサンプルなども乏しいので、基礎的なSVGの知識が必要になります。

 

簡単な説明


Patternで画像を表示する


SVG.jsにおいてPatternで画像を表示説明はマニュアルにも無いが、以下の様にして表示は可能である。

SVG規格においてもimageが使えるような説明はあるが、詳細には言及していないので将来的には何らかの規格が出来るものと思います。次の方法は当方独自のものである。


pattern画像設定

以前は上手く出来なかったが、patternを設定する場合の大きさをステージの大きさに合わせて処理すれば上手く行く。
ドラッグすると中のパターンが追従しないのでグループにドラッグ設定。
ドラッグ可能なインスタンスにアニメ処理をすれば、中の「Gradient、Pattern」は動かない理屈です。


1. リピートしないように、一旦ステージ全体に画像の大きさを展開させる(画像塗りの手法と同じ)。
2. 最終的に表示するスケールに戻してpattern表示する。表示するスケールに戻しても画像の中心は中央に保持されます。CSS3画像処理の面白い特性です。(画像が四角である事を、2番で参照確認できます)
3. レクト要素とpattern要素のcenter()値を合わせてください。
レクト要素がステージ中央なら、pattern要素のcenter()ははぶけます。(初期時中央に配置されているので)
4. これ以外の方法があるかは不明、考えてください。
5. 当方が画像に固執するのは、パターンを作るのがメンドウなだけです。
6. 使用画像は「完全読み込み済み」のものを使用ください。(Firefox要注意)


● 画像塗りの手法を応用しました。ステージ160x160、画像100x100の大きさとして。 2番、ステージ200x160としてテストしますが、最終的に画像は四角形になりますので変な意味で「面白い所」です。(2番参照)
ドラッグはそのままでは機能しませんので、グループでラップしてグループにドラッグ設定します。

1-2番、実際にはパターン化せず「画像塗り」を利用したほうが良い。「画像塗り」は簡単である。
パターン化の利点としてグラフイックなど重ねることが出来る...


//patternサイズをステージの大きさに広げる
var pattern=draw.pattern(160,160,function(add) {

	//一旦画像を広げて、表示の大きさに戻す
	add.image('画像URL').size(160,160).scale(100/160)

	//グラフイックなど重ねることが可能
	//add.circle(100).attr({'fill':'none','stroke':'#F00','stroke-width':2}).center(80,80)

})
//patternとrectのcenter()位置はあわせる
.center(80,80)//pattern

//レクト要素に、patternを挿入する、中央表示
var rect=draw.rect(100,100).radius(10).attr({'fill':pattern,'stroke':'#FFF','stroke-width':2}).center(80,80)//rect

add.imageにcenter()処理はずれ易いので注意。


	//これはずれやすいので控える
	add.image('画像URL').size(160,160).scale(100/160).center(80,80)//ダメ

● pattern化すれば、勝手にリピートしますが、位置が合わない場合がありますので、transformのtranslate()でパターン位置を調整します。3番参照。(これ以外の方法があるかは不明)

以前「画像塗り」では、リピート位置を合わせられなかったので pattern化は有効である。やっと難問が解決した。
思わぬタケノコの収穫だ。


//表示したいサイズでパターンを作る
var pattern3=draw.pattern(50,50,function(add) {
	//add-image
	add.image('/main/images/testImage108.jpg').size(50,50)
})

//移動/ステージ中央値
.attr('transform','translate(80,80)')
//rectに挿入
var rect3=group3.rect(100,100).radius(10).attr({'fill':pattern3,'stroke':'#FFF','stroke-width':1}).center(80,80)

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

ステージ中央でない場合は、共に値をあわせればよい

.attr('transform','translate(100,80)')
rect3=group3.rect(100,100)......center(100,80)

2番、ドラッグでレクトと画像が同サイズなのが確認できます。(中をみるためわざとグループ化していない)

1番、pattern画像 / 2番、pattern画像2 ステージ200x160 / 3番、pattern画像リピート


モット簡単な方法があるかも知れないが、今回はここまで。


サンプルJS


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

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

	//var image=draw.image('/main/images/testImage101.jpg').size(100,100)//.center(80,80).scale(100/160)

	//ドラッグ用
	var group1=draw.group()
	var group2=draw.group()

	//patternにcenter()処理
	var pattern1a=draw.pattern(160,160,function(add) {
		add.image('/main/images/testImage101.jpg').size(160,160).scale(100/160)
	})
	//patternとrectのcenter()位置はあわせる
	.center(60,60)//pattern

	var rect=group1.rect(100,100).attr({'fill':pattern1a,'stroke':'#000','stroke-width':1}).center(60,60)//rect
	.rotate(30)
	group1.draggable()//groupドラッグ

	//2中央はOK
	var pattern1b=draw.pattern(160,160,function(add) {
		add.image('/main/images/testImage102.jpg').size(160,160).scale(100/160)
	})
	//patternとrectのcenter()位置はあわせる
	.center(80,80)

	var rect2=group2.rect(100,100).radius(10).attr({'fill':pattern1b,'stroke':'#FFF','stroke-width':2}).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	group2.draggable()//groupドラッグ

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

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

	//TEXT
	var text=draw.text('pattern画像 drag NG').font({leading:0.8})

	//インスタンス化
	var add_image
	//2
	var pattern2=draw.pattern(200,160,function(add) {
		//インスタンスOK
		add_image=add.image('/main/images/testImage103.jpg')
		add_image.size(200,160).scale(100/160)
	})
	.center(100,80)//pattern

	//中をみるためわざとグループ化していない
	var rect2=draw.rect(100,100).radius(10).attr({'fill':pattern2,'stroke':'#FFF','stroke-width':1}).center(100,80)//rect
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

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

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

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

	//ドラッグ用
	var group3=draw.group()
	//3
	var pattern3=draw.pattern(50,50,function(add) {
		//add-image
		add.image('/main/images/testImage101.jpg').size(50,50)
	})

	//移動/ステージ中央値
	.attr('transform','translate(80,80)')
	//rectのdragは効かない
	var rect3=group3.rect(100,100).radius(10).attr({'fill':pattern3,'stroke':'#FFF','stroke-width':1}).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//グループdrag
	group3.draggable()


● 通常の「画像塗り」のサンプル例(参考)

画像塗り1番、通常の画像塗りで、上記、1-2番pattern使用より簡単である。

画像塗り2番、ステージにリピートしている画像を、原点00で塗り、グループ要素「g」を動かしているので、移動回転などがメンドウになる。これは上の3番の様にpatternを利用したほうが軽くきれいである。
実際は陰影がキレルが最近作った「#drop-shadow2」を利用したので一応は完成している。お勧めできない。


画像塗り1番、通常画像塗りの例、(patternは使用していません) / 画像塗り2番、縮小、(動かすのがメンドウ)


画像塗りサンプルJS(参考)


	//画像塗りの例1
	//対象エレメントID
	var draw=SVG('draw-image1').size(160,160)

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

	//グループ1
	var gazo_group1=draw.group()
	//画像1
	var gazo1=draw.image('/main/images/testImage101.jpg').size(160,160).scale(100/160).center(80,80)
	//rect1画像塗り
	var gazo_rect1=draw.rect(100,100).radius(10).attr({'fill':gazo1,'stroke':'#FFF','stroke-width':1}).center(80,80)
	//グループにadd
	gazo_group1.add(gazo_rect1)//グループ化
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.draggable()

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

	//画像塗りの例2
	//対象エレメントID
	var draw=SVG('draw-image2').size(160,160)

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

	//グループ2
	var gazo_group2=draw.group()
	//画像2/原点00
	var gazo2=draw.image('/main/images/testImage101.jpg').size(50,50)
	//rect1は移動できない/原点00で画像塗り
	var gazo_rect2=draw.rect(100,100).radius(10).attr({'fill':gazo2,'stroke':'#FFF','stroke-width':1})
	//グループにadd
	gazo_group2.add(gazo_rect2)//グループ化
	.attr({'filter':'url(#drop-shadow2)'})//別陰影
	.draggable()
	//グループを移動/簡単には行かない/動かすのがメンドウ
	gazo_group2.translate(30,30)


 

Gradientの回転とリピート


● Gradientの回転とリピート設定が可能ですが、
重要なことは、通常linearでライン描画、rotate()回転の際には、from()to()の設定は行いません。
但し、radialで円、楕円描画はfrom()to()設定が必要で、一旦、原点に描画してから中心に移動させます。

translate() の値は 0-1 値ですので、注意ください。

● リピートは attr() で「spreadMethod」属性を設定します。
そのまま:pad、リピート:repeat、鏡面でリピート:reflect、の3種類設定可。

● 同心円を描画するには少しコツがいります。


SVG.jsのメソッドで伸縮回転移動

Gradient設定の際は、SVG.jsのメソッド .scale() .rotate() .translate()を利用した方が簡単です。
但し、マニュアル、サンプル共に使用方法の説明は有りません(困るネ)。テストしたら機能しましたと言う事です。


1. SVG.jsのメソッド .scale() .rotate() .translate() 利用可能。現在その他の変形には対応していないようです。
将来的にはすこしは進化してほしいと思ってはいますが、.....

(transform変形では、rotateの順序次第で振る舞いが違う場合があります、skew(x,y)は当てになりません)
2. リピートは attr() で「spreadMethod」属性を設定します。(pad repeat reflect)
サンプルではキレイなためほとんどがreflect設定です。
3. scale() 縮小変更の場合は、repeat reflect のいずれかでなければ、リピートしません。
4. ドラッグはレクト要素などに直接設定できます。
5. ChromeでGradientの描画品質が悪い場合があります。将来直ると思います。
6. 問題があれば、自己解決ください。


一応、下記の書式で機能します。(詳細は各サンプル参照)


グラデインスタンス.scale(縮尺比率).rotate(角度値).translate(xyの位置比率)

例/scale縮小の場合はリピート設定をすること
gradient4.scale(0.25).rotate(30).translate(0.5,0.5)
scaleの縦横比率が違う場合は
scale(sx,sy)

//リピート
グラデインスタンス.attr('spreadMethod','repeat')//pad repeat reflect

例/reflect
gradient4.attr('spreadMethod','reflect')

gradientTransform属性として、生成されるのはmatrixなのですが.....


gradientTransform="matrix(0.25,0,0,0.25,0.5,0.5)"

zu

 

● 5-1番、radialで円形、回転は無意味です。


これがよろしいようです

//原点00描画
gradient5.from(0,0).to(0,0).radius(0.5)//00
//SVG.jsメソッド中心に移動
.scale(0.25).translate(0.5,0.5)//center
-----------------------------------

これではダメです、図左1の様になる
gradient5.from(0.5,0.5).to(0.5,0.5).radius(0.5)
.scale(0.25)
-----------------------------------

スケール1、で中央に設定は、図左2の様になる
gradient5.from(0.5,0.5).to(0.5,0.5).radius(0.5)
.scale(1)
-----------------------------------

scaleを考慮して0.5x4の位置に描画すればよいが計算がメンドウです

//原点中心
gradient5.from(2,2).to(2,2).radius(0.5)
//SVG.jsメソッド
.scale(0.25)

● 5-2番、radialで楕円形、回転は先に設定します。スケールの sx sy 値をかえれば楕円形に成ります。


//原点00描画/楕円回転はfrom.to設定
gradient5b.from(0,0).to(0,0).radius(0.5)//00
//楕円変形はメソッドが簡単/回転は先に
.rotate(30).scale(0.5,0.25).translate(0.5,0.5)//center

その他の設定方法

SVG.jsのメソッドを利用しないでtransform属性を直接attr()で設定する方法ですが、少々計算がメンドウになりますので参考程度に読み流してください。


● MatrixによるGradientの設定 (無意味な参考かも知れない)

Matrixによっても縮小回転移動の設定は可能ですが、
通常のSVG.jsのMatrixとは違いますので利用できません。(生成される値がGradient用ではなく通常SVG要素用のためダメ)


GradientのMatrix設定はすこぶるメンドウです。使用するとなればサンプル6番の様に成ると思いますが、上記のSVG.jsのメソッド scale() rotate() translate()を利用した方が利口です。
実際の計算記述は非効率ですが、下記の様にすれば良いようです。(理解するまで時間が掛かったぜ)

translate 0.5 で中央に移動していますが、グラデの描画次第で変化がない場合も有ります。


しかし、次に述べる「手書きtransform設定」より計算は楽かも知れません。


transform属性としてmatrixを羅列できるので
transform="matrix(......) matrix(......) matrix(......)"

//メンドウです
var rad=Math.PI*2/360*135
var scale_x=0.2
var scale_y=0.2
var translate_x=0.5
var translate_y=0.5
gradient6.attr('transform','matrix('+ scale_x +' 0 0 '+ scale_y +' 0 0) ' +'matrix('+ Math.cos(rad) +' '+ Math.sin(rad) +' -'+ Math.sin(rad) +' '+ Math.cos(rad) +' '+ translate_x +' '+ translate_y +')')//角度と移動

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

//SVG.jsのメソッド、簡単
gradient6.scale(0.2).rotate(135).translate(0.5,0.5)

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

単純なものならテキトウに手書きでも書けるが限度はあります

//Matrixイイカゲンな値を書く傾き0
gradient6b.attr('transform','matrix(0.1 0 0 0.1 0.5 0.5)')
//角度のみ訂正できる
.rotate(30)//SVG.jsメソッド

グラデ、matrixについては、下記の記事を参考にしました。
【参考】gihyo.jpの記事: 第3回 少し高度なSVG


● 手書きtransform設定

transformで変形を設定すれば良い訳ですから、細やかな設定が可能ではあるが反面数値の計算がscale値が1以外で大変面倒になります。
この方法で処理する方はいないでショウ。
詳細は、サンプル7-9番を参照ください。言っている意味がわかります。

単なる同心円なら簡単と思いきや...、大きな罠が待っています。


scale,translateなど羅列するだけですですが...

グラデインスタンス.attr('transform','scale(比率値),rotate(値),translate(x比率値,y比率値),skewX(値),...')

楕円形にして回転させると修正が大変です。やりたくない気持ちだ。(サンプル、5-2番)


//楕円で回転を与えると大変です
//計算値
var angle=45
var scl_x=0.5 //スケールは1以下のこと
var scl_y=0.25
var trl_x=0.5/scl_x
var trl_y=0.5/scl_y

//rotate楕円原点描画、中心に移動/回転を先に
gradient9.from(0,0).to(0,0).radius(0.5)//00
.attr('transform','rotate('+ angle +',0.5,0.5),scale('+ scl_x +','+ scl_y +'),translate('+ trl_x +','+ trl_y +')')

skewX処理できますが、少しずれるのでイイカゲンに修正した。


//skewXはズレマス
gradient9.from(0.5,0.5).to(0.5,0.5).radius(0.5)//center
//円、ほぼ中心に移動skewX処理、誤差あり
.attr('transform','scale(0.25),translate(1.25,1.5),skewX(30)')

SVG.jsメソッド設定と手書きMatrixサンプル

x y は全て 0-1 の比率で設定している。中央移動あわせも楕円もこちらが簡単です。

4番、linear reflect.repeat切替 / 5-1番、radial中央移動 原点切替/ 5-2番、楕円の回転


サンプルJS


	//SVG.jsメソッド
	//対象エレメントID
	var draw=SVG('graphic-1d').size(160,160)

	//TEXT
	var text=draw.text('SVG.jsメソッド reflect').font({leading:0.8})

	var gradient4=draw.gradient('linear',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#008B8B')
	})
	//rotate回転の場合は使用しない
	//.from(0,0).to(1,1)

	//translate0.5中心に移動
	gradient4.scale(0.25).rotate(30).translate(0.5,0.5)

	//repeat OK
	//.attr('spreadMethod','repeat')//pad repeat reflect
	//reflect OK
	.attr('spreadMethod','reflect')//pad repeat reflect

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

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

	//ボタン4
	var hit_btn4=draw.circle(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(140,10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	hit_btn4.click(function(e) {
		this.toggleClass('btn-hit')
		if(this.hasClass('btn-hit')) {
			//repeat
			gradient4.attr('spreadMethod','repeat')
		}else{
			//reflect
			gradient4.attr('spreadMethod','reflect')
		}
	})

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

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

	//TEXT
	var text=draw.text('SVG.jsメソッド').font({leading:0.8})

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

	//原点00描画
	gradient5.from(0,0).to(0,0).radius(0.5)
	//SVG.jsメソッド中心に移動
	.scale(0.25).translate(0.5,0.5)//center
	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect5=draw.rect(100,100).attr({'fill':gradient5}).center(80,80)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

	//ボタン5
	var hit_btn5=draw.circle(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(140,10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	hit_btn5.click(function(e) {
		this.toggleClass('btn-hit')
		if(this.hasClass('btn-hit')) {
			//00
			gradient5.translate(0,0)
		}else{
			//center
			gradient5.translate(0.5,0.5)
		}
	})

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

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

	//TEXT
	var text=draw.text('SVG.jsメソッド楕円回転').font({leading:0.8})

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

	//原点00描画/楕円回転はfrom.to設定
	gradient5b.from(0,0).to(0,0).radius(0.5)//00
	//楕円変形はメソッドが簡単/回転は先に
	.rotate(30).scale(0.5,0.25).translate(0.5,0.5)//center
	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect5b=draw.rect(100,100).attr({'fill':gradient5b}).center(80,80)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影


GradientのMatrixは、通常のSVG要素に対するSVG.Matrixクラスとは違いますので区別して下さい。

6-1番、Matrix / 6-2番、Matrixイイカゲン / 6-3番、Matrixイイカゲン2


サンプルJS


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

	//TEXT
	var text=draw.text('手書きMatrix メンドウ').font({leading:0.8})

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

	//メンドウです
	var rad=Math.PI*2/360*135
	var scale_x=0.2
	var scale_y=0.2
	var translate_x=0.5
	var translate_y=0.5
	gradient6.attr('transform','matrix('+ scale_x +' 0 0 '+ scale_y +' 0 0) ' +'matrix('+ Math.cos(rad) +' '+ Math.sin(rad) +' -'+ Math.sin(rad) +' '+ Math.cos(rad) +' '+ translate_x +' '+ translate_y +')')//角度と移動

	//reflect OK
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect6=draw.rect(100,100).radius(10).attr({'fill':gradient6,'stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

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

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

	//TEXT
	var text=draw.text('手書きMatrixイイカゲン').font({leading:0.8})

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

	//Matrixイイカゲンな値を書く傾き0
	gradient6b.attr('transform','matrix(0.1 0 0 0.1 0.5 0.5)')
	//角度のみ訂正できる
	.rotate(30)//SVG.jsメソッド
	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient
	var rect6b=draw.rect(100,100).radius(10).attr({'fill':gradient6b,'stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

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

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

	//TEXT
	var text=draw.text('手書きMatrixイイカゲン2').font({leading:0.8})

	var gradient6c=draw.gradient('radial',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#DB7093')
	})
	.from(0,0).to(0,0).radius(0.5)//00

	//Matrixイイカゲンな値を書く、radialは回転は与えない
	gradient6c.attr('transform','matrix(0.1 0 0 0.1 0.5 0.5)')
	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect6c=draw.rect(100,100).radius(10).attr({'fill':gradient6c,'stroke':'#FFF','stroke-width':2}).center(80,80)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影


手書きtransform設定

x y は全て 0-1 の比率で設定している。細やかな設定を行う場合、スケール変更のあわせ方が結構面倒だ。
処理によっては、ギブアップするぜ。SVG.jsメソッドを利用するのが簡単なことが理解できる。

7番、通常の繰り返し/ 8番、同心円に/ 9番、楕円形で回転


サンプルJS


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

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

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

	//rotateは1以下のscaleとあわせて記載することメンドイ
	//scale rotate OK/rotateはfrom.to無しのこと
	.attr('transform','scale(0.1),rotate(15)')
	//skewXのみはかかる/from.to無しのこと
	//.attr('transform','scale(0.1),skewX(30)')

	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect7=draw.rect(100,100).radius(10).attr({'fill':gradient7,'stroke':'#FFF','stroke-width':2}).center(80,80)//.move(30,30)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

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

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

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

	var gradient8=draw.gradient('radial',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#F00')
	})

	//from-to
	gradient8.from(0.5,0.5).to(0.5,0.5).radius(0.5)//center
	//中心に移動
	.attr('transform','scale(0.25),translate(1.5,1.5)')

	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect8=draw.rect(100,100).attr({'fill':gradient8}).center(80,80)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

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

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

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

	var gradient9=draw.gradient('radial',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#FF4500')
	})

	//楕円で回転を与えると大変です/円でも出来ます
	//計算値
	var angle=45
	var scl_x=0.5 //スケールは1以下のこと
	var scl_y=0.25
	var trl_x=0.5/scl_x
	var trl_y=0.5/scl_y
	//rotate楕円原点描画、中心に移動/回転を先に
	gradient9.from(0,0).to(0,0).radius(0.5)//00
	.attr('transform','rotate('+ angle +',0.5,0.5),scale('+ scl_x +','+ scl_y +'),translate('+ trl_x +','+ trl_y +')')

	//reflect
	.attr('spreadMethod','reflect')//pad repeat reflect

	//gradient-rect
	var rect8=draw.rect(100,100).attr({'fill':gradient9}).center(80,80)
	.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影


GradientとPatternの組み合わせ

細やかな繰り返しのGradientの場合、Patternとの組み合わせも1つの方法です。
沢山のサンプルを作り、方法を知ることが大切ですが、イヤハヤメンドウキワマリナイ。


1. 小さなGradientを作り、Pattern化して配置します。(パターンは作るのがメンドウで、私は嫌いです)
2. Patternはリピートします。
3. Patternをtransform移動させると、レクトでの配置がキレイになります。(必要ないなら設定しません、左上よりPatternが描画されます)
4. パターン処理での、ドラッグはレクト要素などで機能しませんので、グループでラップしました。


Patternをtransform移動させると、下記サンプルの様にレクトでの配置がキレイになります。


//移動/ステージ中央値
パターン.attr('transform','translate(80,80)')

組み合わせパターンのサイズ切替(10番参照)
組み合わせが複雑であれば、update()では対処が難しく複雑になる。よって2パターン用意し「レクトに上書き」して切り替えてみた。この方が単純で描画も早い。


別パターンを用意する

//切り替え用patternサイズ違い
var pattern10b=draw.pattern(10,10,function(add) {
	add.rect(10,10).attr({'fill':gradient10})
})

rect10に上書き

//パターン縮小
rect10.attr({'fill':pattern10b})

10番、組み合わせ サイズ切替 / 11番、組み合わせ / 12番、組み合わせ reflect.repeat切替


サンプルJS


	//SVG.jsメソッド
	//対象エレメントID
	var draw=SVG('graphic-1j').size(160,160)

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

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

	//SVG.jsメソッド中心に移動
	.scale(0.5).rotate(45).translate(0.5,0.5)//center
	//reflect OK
	.attr('spreadMethod','reflect')//pad repeat reflect

	//pattern敷き詰め、大きさかえるならサイズを変更すること
	var pattern10=draw.pattern(20,20,function(add) {
		add.rect(20,20).attr({'fill':gradient10})
	})
	//切り替え用patternサイズ違い
	var pattern10b=draw.pattern(10,10,function(add) {
		add.rect(10,10).attr({'fill':gradient10})
	})

	//移動/ステージ中央値
	.attr('transform','translate(80,80)')

	//グループ
	var group10=draw.group()
	//gradient-rect
	var rect10=group10.rect(100,100).radius(10).attr({'fill':pattern10,'stroke':'#FFF','stroke-width':2}).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	group10.draggable()

	//ボタン10
	var hit_btn10=draw.circle(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(140,10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	hit_btn10.click(function(e) {
		this.toggleClass('btn-hit')
		if(this.hasClass('btn-hit')) {
			//パターン縮小
			rect10.attr({'fill':pattern10b})
		}else{
			//戻す
			rect10.attr({'fill':pattern10})
		}
	})

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

	//SVG.jsメソッド
	//対象エレメントID
	var draw=SVG('graphic-1k').size(160,160)

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

	//11
	var gradient11=draw.gradient('linear',function(stop){
		stop.at(0,'#333')
		stop.at(1,'#FFA500')
	})
	.scale(1).rotate(45).translate(0.5,0.5)
	.attr('spreadMethod','repeat')

	var pattern11=draw.pattern(20,20,function(add) {
		add.rect(20,20).attr({'fill':gradient11})

	})
	//移動/ステージ中央値
	.attr('transform','translate(80,80)')

	//グループ
	var group11=draw.group()
	//gradient-rect
	var rect11=group11.rect(100,100).radius(10).attr({'fill':pattern11,'stroke':'#FFF','stroke-width':2}).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	group11.draggable()

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

	//SVG.jsメソッド
	//対象エレメントID
	var draw=SVG('graphic-1l').size(160,160)

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

	//12
	var gradient12=draw.gradient('radial',function(stop){
		stop.at(0,'#333')
		stop.at(1,'#FFA500')
	})
	.from(0.5,0.5).to(0.5,0.5).radius(1)
	.translate(0.5,0.5)
	.attr('spreadMethod','reflect')

	//25x25
	var pattern12=draw.pattern(25,25,function(add) {
		add.rect(25,25).attr({'fill':gradient12})
	})

	//移動/ステージ中央値
	.attr('transform','translate(80,80)')

	//グループ
	var group12=draw.group()
	//gradient-rect
	var rect12=group12.rect(100,100).radius(10).attr({'fill':pattern12,'stroke':'#FFF','stroke-width':2}).center(80,80)//.rotate(30)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	group12.draggable()

	//ボタン12
	var hit_btn12=draw.circle(10).attr({'fill':'#F00','stroke':'#FFF','stroke-width':2}).center(140,10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	hit_btn12.click(function(e) {
		this.toggleClass('btn-hit')
		if(this.hasClass('btn-hit')) {
			//0
			gradient12.translate(0,0)
		}else{
			//0.5
			gradient12.translate(0.5,0.5)
		}
	})


GradientとPatternのその他の処理例

組み合わせ、画像ぬりなどによる各種処理例です。詳細はJSを参照ください。13番は「トコヤ」サンで良く見かけます。
画像をPatternに取り込めば、「画像stroke」も可能です。(14番参照)


Gradient、Pattern、画像、のstroke処理1

13番、Gradient stroke / 14番、画像stroke / 15番、Gradient fill


サンプルJS


	//SVG.jsメソッド
	//対象エレメントID
	var draw=SVG('graphic-1m').size(160,160)

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

	var gradient13=draw.gradient('linear',function(stop){
		stop.at(0,'#F00')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#00F')
	})

	//展開方向/対角方向OK
	.from(0,0).to(1,1)
	.scale(0.1).translate(0.5,0.5)
	.attr('spreadMethod','reflect')

	//グループ
	var group13=draw.group()
	//gradient-rect
	var rect13=group13.rect(100,100).radius(10).attr({'fill':'#FFF','stroke':gradient13,'stroke-width':4}).center(80,80)//.rotate(30)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	group13.draggable()

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

	//SVG.jsメソッド
	//対象エレメントID
	var draw=SVG('graphic-1n').size(160,160)

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

	//14
	var pattern14=draw.pattern(160,160,function(add) {
		add.image('/main/images/grad_200.jpg').size(160,160).move(0,0).scale(120/160)
	})

	//グループ
	var group14=draw.group()
	//pattern-stroke
	var rect14=group14.rect(100,100).radius(10).attr({'fill':'#FFF','stroke':pattern14,'stroke-width':4}).center(80,80)//.rotate(30)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	group14.draggable()

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

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

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

	//gradient-patternをつくる
	var gradient15=draw.gradient('linear',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#FF69B4')
	})
	.from(0,0).to(1,1)
	gradient15.scale(0.1)//.translate(0.5,0.5)
	.attr('spreadMethod','reflect')

	//設定
	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 group15=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)
		//gradient-rect
		var rect=draw.rect(26,26).attr({'fill':gradient15,'stroke':'#FFF','stroke-width':2}).center(x,y).rotate(i*a)
		.attr({'filter':'url(#dropShadow2)'})//陰影
		group15.add(rect)

	}
	//グループ
	group15.draggable()


Gradient、Pattern、画像、の処理2

16番、pattern-clipマスク/ 17番、draw-image / 18番、gradient-path


サンプルJS


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

	//TEXT
	var text=draw.text('pattern-clipマスク').font({leading:0.8})

	//gradient-patternをつくる
	var gradient16=draw.gradient('linear',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#008B8B')
	})
	.from(0,0).to(1,1)
	gradient16.scale(0.05)//.translate(0.5,0.5)
	.attr('spreadMethod','reflect')
	//160x160
	var pattern16=draw.pattern(160,160,function(add) {
		add.rect(160,160).attr({'fill':gradient16})
	})

	//設定
	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 group16=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=draw.rect(30,30).attr({'fill':'#000'}).center(x,y).rotate(i*a)
		//mask材
		var maskrect=draw.rect(160,160).attr({'fill':pattern16})
		maskrect.clipWith(rect)
		//陰影処理のためグループにする
		group16.add(maskrect)

	}
	//グループ
	group16.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

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

	//対象エレメントID
	var draw=SVG('graphic-1q').size(160,160)
	//TEXT
	var text=draw.text('draw image').font({leading:0.8})

	//設定
	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 group17=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)
		//image
		var image=draw.image('/main/images/grad_200.jpg').size(160,160)
		//rect
		var rect=draw.rect(30,30).attr({'fill':image}).center(x,y).rotate(i*a)
		//陰影処理のためグループにする
		group17.add(rect)

	}
	//グループ
	group17.draggable()
	.attr({'filter':'url(#dropShadow2)'})//陰影

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

	//対象エレメントID
	var draw=SVG('graphic-1r').size(160,160)
	//TEXT
	var text=draw.text('gradient-path').font({leading:0.8})

	//gradientをつくる
	var gradient18=draw.gradient('linear',function(stop){
		stop.at(0,'#333')
		stop.at(.45,'#FFF')
		stop.at(.55,'#FFF')
		stop.at(1,'#DAA520')
	})
	.from(0,0).to(1,1)
	gradient18.scale(0.05)//.translate(0.5,0.5)
	.attr('spreadMethod','reflect')

	//グループ
	var group18=draw.group()
	var path=draw.path('M230 230A 45 45, 0, 1, 1, 275 275L 275 230 Z').center(80,80).scale(1.5)
	.attr({'fill':gradient18})
	.attr({'filter':'url(#dropShadow2)'})//陰影

	group18.add(path)
	.draggable()


サンプルJSの全表示

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

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

使用画像

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

使用画像サンプル

 


 

このページは下記ページの追加です。SVG.js GradientとPatternについて基本的な説明は下記ページ参照ください。
【参照】当方の記事: SVG.js グラデーションとパターン

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

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

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

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


 

最近の新聞記事より、「かぐや姫は宇宙人だったのか...」、「竹の子」に決まってるだろう。以上です。



[ この記事のURL ]


タグ:javascript , SVG

 

ブログ記事一覧

年別アーカイブ一覧



[1]