POPSブログ

SVG.js アニメーション(2)

383

  Category:  javascript2016/03/07 pops 

SVG.js アニメーションについて調べてみますが、PATHアニメーション、SMIL形式のアニメーション、パスに沿ってアニメーション、画像のFadeとCrossFade はページ容量の都合で分離して掲載します。一部当方独自の方法をも取りますが、一応正常に可動します。

 

SVG.js アニメーションのテスト2

 

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

 

SVG.js アニメーション2


前ページの続きになります。アニメーションの書式などは「SVG.js アニメーション(1)」を参照ください。


PATHアニメーション

PATHアニメーションの stroke-dasharray、stroke-dashoffset、の値はパスの長さに関わらず 1000 に成ります。

1番、circle PATHアニメ / 2番、rect PATHアニメ / 3番、text PATHアニメ


サンプルJS


	//Pathアニメーション
	//対象エレメントID
	var draw=SVG('graphics-9a').size(160,160)

	//半径50/SVG.jsのパス書式ではなく、標準の書式d=''でなければ動作しない
	var str='M 50 50 m 0 -50 a 50 50 0 1 1 -1 0 h 1'
	//注意テキストでないので、buildは使用しない
	var circle_p=draw.path(str).attr({'fill':'rgba(0,0,0,0)','stroke':'#000','stroke-width':2,'stroke-dasharray':1000,'stroke-dashoffset':1000})
	.move(30,30)

	//ボタン
	var anime_btn10=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(140,140)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')

	//svg.path.jsでパスは描けるがanimateではないのでafterなどは無効になる
	//circle_p.drawAnimated()

	//CLICK-ACTION
	anime_btn10.click(function() {
		circle_p.animate(2000).attr({'stroke-dashoffset':0}).after(function(){
			this.animate(1000).attr({'fill':'#FF1493'}).after(function(){
				this.attr({'filter':'url(#dropShadow2)'})
			})
		})
	})

	var txt=draw.text('1 Pathアニメーション1回限り').font({leading:0.8})

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

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

	//100x100/SVG.jsのパス書式ではなく、標準の書式d=''でなければ動作しない
	var str='M 0 0 L 0 0 100 0 L 100 0 100 100 L 100 100 0 100 L 0 100 0 0 Z'
	//注意テキストでないので、buildは使用しない
	var rect_p=draw.path(str).attr({'fill':'rgba(0,0,0,0)','stroke':'#000','stroke-width':2,'stroke-dasharray':1000,'stroke-dashoffset':1000})
	.move(30,30)

	//ボタン
	var anime_btn11=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(140,140)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	anime_btn11.click(function() {
		rect_p.animate(2000).attr({'stroke-dashoffset':0}).after(function(){
			this.animate(1000).attr({'fill':'#00CED1'}).after(function(){
				this.attr({'filter':'url(#dropShadow2)'})
			})
		})
	})

	var txt=draw.text('2 Pathアニメーション1回限り').font({leading:0.8})

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

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

	//注意テキストのためbuildを使用
	//文字描画/stroke-dashoffsetを動かす
	var mv_outlinetext=draw.text('POPS').attr({'fill':'#FFFFFF','stroke':'#000','stroke-width':2,'stroke-dasharray':1000,'stroke-dashoffset':1000}).move(80,60)
	mv_outlinetext.font({
		family:'Arial'
		,size:50
		,'font-weight':'bold'
		,anchor:'middle'
		,leading:1
	})
	mv_outlinetext.build(true)

	mv_outlinetext.build(false)
	//ボタン
	var anime_btn12=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(140,140)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	anime_btn12.click(function() {
		mv_outlinetext.animate(2000).attr({'stroke-dashoffset':0}).after(function(){
			this.animate(1000).attr({'fill':'#FFD700'}).after(function(){
				this.attr({'filter':'url(#dropShadow2)'})
			})
		})
	})

	var txt=draw.text('3 Pathアニメーション1回限り').font({leading:0.8})


TEXT-PATHアニメーション

TEXT-PATHアニメーション大型1

文字が大きいと、パス描画後も処理が継続していますので、終了まで時間が掛かります。(原則、早くは出来ません)


描画後の時間が冗長ですので少し調整します。stroke-dasharray の値が小さいと、描画が切れます。文字の大きさ長さにより差が有りますのでアニメーションを確認しながら調整します。調整によっては意図しない描画になる場合があります。

 



通常は下記のように書くと描画後の時間が冗長
outlinetext.animate(3000).attr({'stroke-dashoffset':0}).after...

少し描画を変えて
outlinetext.animate(3000,'=').attr({'stroke-dashoffset':0,'stroke-dasharray':500}).after...

サンプルJS


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

	//文字描画フォント指定
	var outlinetext=draw.text('POPS-WEB')
	.font({
		family:'GauFontMilkChoco'
		,size:65
		,anchor:'left'
		,leading:1
	})
	.addClass('GauFontMilkChoco')//有効
	//再実行のため
	outlinetext.hide()

	//ボタン
	var test_btn11=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(620,10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	test_btn11.click(function(){

		//再実行のため
		this.hide()
		outlinetext.attr({'filter':'none'})
		//実行
		show_outlinetext()
	})

	function show_outlinetext(){

		//再実行のため
		outlinetext.show()

		//実行
		outlinetext.attr({'fill':'#FFF','stroke':'#DC143C','stroke-width':2,'stroke-dasharray':1000,'stroke-dashoffset':1000}).move(70,25)
		outlinetext.build(true)

		outlinetext.build(false)
		//animate
		outlinetext.animate(3000,'=').attr({'stroke-dashoffset':0,'stroke-dasharray':500}).after(function(){
			this.animate(1000).attr({'fill':'#DB7093','stroke':'#FFFFFF','stroke-width':2}).after(function(){
				//陰影
				this.attr({'filter':'url(#dropShadow2)'})
				//新しいブラウザ向けランダムカラー
				var color='#'+Math.random().toString(16).slice(-6)
				this.animate(1000).attr({'fill':color}).after(function(){
					//ボタン表示
					test_btn11.show()
				})
			})
		})
	}

	var txt=draw.text('4 Pathアニメーション、3秒、「再実行」出来ます。').font({leading:0.8})


カーニングTEXT

カーニングTEXTの場合、Firefoxがtspanを個別に認識出来ない様で処理できません。JSが停止してしまいます。
サンプル3の様にカーニング設定の書式を変えて間隔を調整できますので、この方法ならFirefoxでもOKです。但し、個別に色をつけることは出来ません。(虹色ならパターンで可能かも知れません...)

zudaze

 


サンプル2、tspan個別にdx設定
tspan(tx).attr({'dx':-10})

サンプル3、TEXTに複数のdxを設定
text.attr({dx:'-10,-10,-10,-10,-10,......'})

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

//firefox判定
var ua=window.navigator.userAgent
var firefox=false
if (ua.indexOf("Firefox") > -1) {firefox=true}

tspanがある場合

色々な方法を試しましたが、日ごろの行いが悪いせいか「現在未解決」です。誰か考えてください。
firefox判定し動作しないようにしています。

TEXT-PATHアニメーション大型2 (Firefox NG 実行出来ません)


tspanで個別に色指定している場合、親であるtextの色を変えても、tspanの色は変化しません。

サンプルJS


	//TEXTカーニング大型2
	//エレメントID
	var draw=SVG('svgtext-fliter-2a').size(640,100)

	var mess_txt=draw.text('5 Pathアニメーション、3秒、「再実行」出来ます。').font({leading:0.8})

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

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

	//カーニングと着色
	var spikes=main_strings.length
	kerning_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':'#FFF','stroke':color,'stroke-width':2})
		}
	})

	//再実行のため
	kerning_text.hide()

	//ボタン
	var test_btn12=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(620,10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	test_btn12.click(function(){

		//再実行のため
		this.hide()
		kerning_text.attr({'filter':'none'})
		//実行
		if(firefox){mess_txt.text('firefoxは実行出来ません')}
		if(!firefox){show_ktext()}

	})

	//Firefox実行出来ない
	function show_ktext(){

		//実行
		kerning_text.move(50,15)
		kerning_text.show()
		kerning_text.attr({'fill':'#FFF','stroke':'#000','stroke-width':2,'stroke-dasharray':1000,'stroke-dashoffset':1000}).move(50,15)
		kerning_text.build(true)

		kerning_text.build(false)
		//animate
		kerning_text.animate(3000,'=').attr({'fill':'#FFF','stroke':'#000','stroke-dashoffset':0,'stroke-dasharray':500}).after(function(){
			//陰影
			this.attr({'filter':'url(#dropShadow2)'})
			//ボタン表示
			test_btn12.show()
		})
	}


tspanがない場合

TEXT-PATHアニメーション大型3 (Firefox OK)、tspan無しのため個別に着色は出来ません


サンプルJS


	//TEXTカーニング大型3
	//エレメントID
	var draw=SVG('svgtext-fliter-2b').size(640,100)

	//ストリング2
	var main_strings2="Merry Christmas 2017.dazo"

	//文字描画フォント指定
	var kerning_text2=draw.text(main_strings2)
	.font({
		family:'Times New Roman'
		,size:65
		,anchor:'left'
		,leading:1
	})

	//カーニング
	var dxstrs=[]
	for (var i=0; i<main_strings.length;i++){
		dxstrs.push(-10)
	}
	kerning_text2.attr({'dx':dxstrs.toString()})

	//再実行のため
	kerning_text2.hide()

	//ボタン
	var test_btn13=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(620,10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	test_btn13.click(function(){

		//再実行のため
		this.hide()
		kerning_text2.attr({'filter':'none'})
		//実行
		show_ktext2()
	})

	//Firefox OK
	function show_ktext2(){

		//再実行のため
		kerning_text2.show()

		//実行
		kerning_text2.attr({'fill':'#FFF','stroke':'#DC143C','stroke-width':2,'stroke-dasharray':1000,'stroke-dashoffset':1000}).move(70,15)
		kerning_text2.build(true)

		kerning_text2.build(false)
		//animate
		kerning_text2.animate(3000,'=').attr({'stroke-dashoffset':0,'stroke-dasharray':500}).after(function(){
			this.animate(1000).attr({'fill':'#DB7093','stroke':'#FFFFFF','stroke-width':2}).after(function(){
				//陰影
				this.attr({'filter':'url(#dropShadow2)'})
				//新しいブラウザ向けランダムカラー
				var color2='#'+Math.random().toString(16).slice(-6)
				this.animate(1000).attr({'fill':color2}).after(function(){
					//ボタン表示
					test_btn13.show()
				})
			})
		})
	}

	var txt=draw.text('6 Pathアニメーション、3秒、「再実行」出来ます。').font({leading:0.8})


 

SMIL形式のアニメーション

SMIL形式のアニメーションとは、下記の様な「animateMotion」形式のもので、簡単に作ることが出来ます。

【参照】: 「10分でわかるSVG 応用編」サンプル

下記は、上記サイトのサンプルをそのまま掲載したものです。(「IE」では非対応)

HTML、(sample.atmarkit.jpより引用)


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="100">
<path d="M 30,40 c 0,80 240,-80 240,0 s -240,-80 -240,0" fill="none" stroke="#ccc" /></path>
<path d="M -10,-10 L 10,0 -10,10 Z"><animateMotion rotate="auto" dur="6s" repeatCount="indefinite" path="M 30,40 c 0,-80 240,80 240,0 s -240,80 -240,0" /></path>
</svg>

● SMIL形式のアニメーションはSVG.jsでは対応していませんが、svg()メソッドで取り込むことが可能です。
SMIL形式の場合、色々と問題があり全てのブラウザが対応している訳ではなく「IE」ではアニメーションが実行されません。
また、現在Chromeで「非推奨」になっており、将来的には対応されなくなるようです。


svg()で「svg」を取り込み表示する。場合によってはグループを作りその中でsvg()を実行しなければならない事もあり、保障されたものでは無いので工夫が要ります。


svg('<g>SMIL形式のアニメーション部分</g>')

svg()は便利です、他にも使い道はあるでしょう。(特にパクリに便利だ)

 

● svg()で取り込みの、パスに沿ってアニメーション、形状のアニメーション。3つとも「IE」ではアニメーションが実行されません


サンプルJS


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

	//svg
	draw.svg('<g><rect width="160" height="160" fill="#f06"></rect></g>')
	//line
	var path=draw.path('M 10,80 c 0,-80 140,80 140,0 s -140,80 -140,0').attr({'fill':'none','stroke':'#FFF','stroke-width':1})

	//svg書き出しの場合可動する
	var group=draw.group()
	var path=group.path('M -10,-10 L 10,0 -10,10 Z')
	var animateMotion=group.element('animateMotion')

	animateMotion.attr({'rotate':'auto','dur':'6s','repeatCount':'indefinite','path':'M 10,80 c 0,-80 140,80 140,0 s -140,80 -140,0'})

	var txt=draw.text('1パスに沿ってアニメーション').font({leading:0.8})

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

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

	//そのままでは移動できないのでに収容する/画像塗りは難しい
	var group=draw.group()
	group.svg('<g><path fill="#000"><animate attributeType="XML" attributeName="d" dur="6s" repeatCount="indefinite" values="M 0,0 L 40,0 80,0 40,80; M 0,80 L 40,0 80,80 40,80; M 0,0 L 40,0 80,0 40,80" /></path></g>')
	group.move(40,40)

	var txt=draw.text('2 形状のアニメーション').font({leading:0.8})

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

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

	var group=draw.group()
	var path=group.path('M -10,-10 L 10,0 -10,10 Z')
	var animateMotion=group.element('animateMotion')
	animateMotion.attr({'rotate':'auto','dur':'6s','repeatCount':'indefinite','path':'M 10,80 c 0,-80 140,80 140,0 s -140,80 -140,0'})

	var txt=draw.text('3、1番を別方式で取り込む').font({leading:0.8})


将来的にSMILは消滅する様ですから、JavaScript処理を考えて見ます。


パスに沿ってアニメーション(JavaScript処理)

SMIL形式では無く、JavaScript処理したもので、つまりはこのようにした方が良いと言う事です。(「IE」OK)
下記例は、当然得意の「パクリ」でSVG.jsで動くようにした。原理詳細は下記サイトを参照ください。

【参考】liginc.co.jpの記事: SVGのpathを使ったモーションパスアニメーションの実装方法

【参考】jsdo.itの記事: svgのパスに沿ってdomを動かす


getTotalLength()でpathの長さを取得して処理する方法だそうです。SMIL形式では無いから「IE11」でもOKです。

JavaScriptで処理するにIDが必要であるが、パスなどを書き込んだ直後に、SVG.jsで自動生成されるので、attr()で取得できる。これを利用すれば良いと言う訳です。


マニュアルを良く見たら、getTotalLength() getPointAtLength() に相当するSVG.jsメソッドが在ったのでそれで処理する。(2016/03/11修正します)
2、3番パス違いでまったく同じです。一緒にコードを書いているので変数名をかえているが...


pathの長さを取得
pathの長さ=SVG.jsのパスインスタンス.length()

n地点のポイント値を取得して移動させる、x y 値が簡単に取得できる
var point=SVG.jsのインスタンス.pointAt(カウント)

ボールがSVG.jsインスタンスならば、下記で動く
SVG.jsのインスタンス.attr({'transform':"translate("+ point.x + ","+ point.y + ")"})

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

1番、下記の2変数を有効にすれば、折り返さない

//アニメーション関数
function moveCircle(){

	//終点についたら反転させる判定
	if( parseInt(counter,10) === 1 ){

		//counter=0
		//state=true

	}
}

パスの始点を通過する場合にChromeで一瞬ボールが中央に来るような場合はパスの描画形式を変えてみると解決する。
(円の描画パスは色々書き方がある)、Chrome以外は正常のようです。
ボールの運動がずれる場合は cx() cy() 設定を確認ください。



サンプルJS


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

	//ガイドライン
	var guide_path=draw.path('M 20,80 A 60,60 0 1,1 140,80 A 60,60 0 1,1 20,80 z')
	.attr({'fill':'none','stroke':'#F00','stroke-width':1})
	//BALL
	var ball=draw.circle(10).attr({'fill':'#FF0000','stroke':'#000','stroke-width':1}).cx(0).cy(0)

	//動かす値を取得
	var counter=0
	//再生方向反転用フラグ
	var state=true
	//pathの長さを取得
	var leng=guide_path.length()

	//アニメーション関数
	function moveCircle(){

		//終点についたら反転させる判定
		if( parseInt(counter,10) === 1 ){
		state=false
		//counter=0
		} else if(parseInt(counter,10) < 0 ){
		state=true
		}
		//state=true

		//アニメーション用のcounter
		if(state){
		counter +=0.003
		} else {
		counter -=0.003
		}

		var point=guide_path.pointAt(counter*leng)
		//要素のtranslateを変更
		ball.attr({'transform':"translate("+ point.x + ","+ point.y + ")"})

		//再帰
		window.requestAnimationFrame(moveCircle)
	}

	var timer=window.requestAnimationFrame(moveCircle)

	var txt=draw.text('1 requestAnimationFrame方式').font({size:10,leading:0.8})

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

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

	var mv_speed=1000/120

	//ガイドライン
	var guide_path=draw.path('M 20,80 A 60,60 0 1,1 140,80 A 60,60 0 1,1 20,80 z')
	.attr({'fill':'none','stroke':'#F00','stroke-width':1})
	//BALL
	var ball1=draw.circle(10).attr({'fill':'#F00','stroke':'#000','stroke-width':1}).cx(0).cy(0)

	//パスの長さ
	var pathLength=guide_path.length()
	var nowPos=0
	setTimeout(function(){anime()},mv_speed)

	//アニメ
	function anime(){
		if(nowPos > pathLength){
			nowPos=0
		}
		var point=guide_path.pointAt(nowPos)
		//SVGはtranslate
		ball1.attr({'transform':"translate("+ point.x + ","+ point.y + ")"})
		nowPos++
		setTimeout(function(){anime()},mv_speed)
	}

	var txt=draw.text('2 setTimeout方式').font({size:10,leading:0.8})

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

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

	var mv_speed2=1000/120

	//ガイドライン
	var guide_path2=draw.path('M 10,80 c 0,-80 140,80 140,0 s -140,80 -140,0')
	.attr({'fill':'none','stroke':'#CCC','stroke-width':1})
	//BALL2
	var ball2=draw.circle(10).attr({'fill':'#0FF','stroke':'#000','stroke-width':1}).cx(0).cy(0)

	//パスの長さ
	var pathLength2=guide_path2.length()
	var nowPos2=0
	setTimeout(function(){anime2()},mv_speed2)

	//アニメ
	function anime2(){
		if(nowPos2 > pathLength2){
			nowPos2=0
		}
		var point=guide_path2.pointAt(nowPos2)
		//SVGはtranslate
		ball2.attr({'transform':"translate("+ point.x + ","+ point.y + ")"})
		nowPos2++
		setTimeout(function(){anime2()},mv_speed2)
	}

	var txt=draw.text('3 setTimeout方式 パス違い').font({size:10,leading:0.8})


 

画像のFadeとCrossFade

load()を使用すると「画像の切り替え」が簡単に実行できますが、loaded()は使い勝手が悪いので、原則使用しませんので使い道は誰か考えてください。


● 通常の画像表示は、下記の通りですが加工処理は出来ません。読み込み次第に表示します。

画像を加工処理する場合、画像の大きさ設定が重要であり、且つ「完全読み込み済み」画像でなければ処理出来ないことが多数です。特にFirefoxでは厳密ですから注意ください。


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

● load()は現在表示している画像を取り替えるメソッドです。原則、同じドメインでサイズは同一が原則です。
new Image()オブジェクトで処理され、ロード完了画像が取得できます。読み込みエラーで在れば処理されません。


マニュアル書式
image.load('/path/to/another/image.jpg')

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

表示している画像
var image=draw.image('/main/images/testImage108.jpg').size(100,100)
必要な所で画像を取り替える
image=draw.image('/main/images/testImage108.jpg')

● loaded()は期待に反してお粗末ですから、技量が無ければ使いこなせないと思います。
width、height、ratio (width/height)、url、の取得が可能ですが、関数の中は別世界なので、通常の画像処理等が難しい面があります。
また、draw.image()を実行してからの処理で、関数の中は画像loadedを待たず実行しますのでスコブル使い難く、何のための関数かわからない。私は使用しません。


マニュアル書式
var image=draw.image('/path/to/image.jpg').loaded(function(loader){
  this.size(loader.width,loader.height)
})

----------------------------------------------
var image=draw.image('/path/to/image.jpg').loaded(function(loader){
  this.size(loader.width,loader.height)
  if(loader.width > 0){
    //ロード完了後処理できる

  }
})

当方使用しませんので、説明詳細は控えます。必要な方は自己解決ください。


● loaded()による、FadeとCrossFade

1-3番、load()と fill-opacity処理の組み合わせです。スコブル便利に思います。


サンプルJS


	//画像FADE
	//対象エレメントID
	var draw=SVG('graphics-12a').size(160,160)

	//image 100x100
	var image=draw.image('/main/images/testImage108.jpg').size(160,160).center(80,80).scale(100/160)
	//rect画像塗り
	var fade_rect=draw.rect(100,100).attr({'fill':image}).radius(10).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影

	//ボタン
	var fade_btn1=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(140,140)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	fade_btn1.click(function() {
		fade_rect.animate(1000).attr({'fill-opacity':0}).after(function(){
			this.animate(1000).attr({'fill-opacity':1})
		})
	})

	var txt=draw.text('1 画像FADE TEST').font({leading:0.8})

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

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

	var backt=draw.rect(100,100).attr({'fill':'#000'}).radius(10).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//image 100x100
	var image=draw.image('/main/images/testImage108.jpg').size(160,160).center(80,80).scale(100/160)
	//rect画像塗り
	var fade_rect2=draw.rect(100,100).attr({'fill':image}).radius(10).center(80,80)

	//ボタン
	var fade_btn2=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(140,140)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	//CLICK-ACTION
	fade_btn2.click(function() {
		fade_rect2.animate(1000).attr({'fill-opacity':0}).after(function(){
			this.animate(1000).attr({'fill-opacity':1})
		})
	})

	var txt=draw.text('2 画像FADE TEST2').font({leading:0.8})

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

	//画像CROSSFADE

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

	var imageno=0
	var image_urls=['/main/images/testImage108.jpg','/main/images/testImage107.jpg','/main/images/testImage106.jpg','/main/images/testImage105.jpg']

	var back=draw.rect(100,100).attr({'fill':'#000'}).radius(10).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//image 100x100
	var top_image=draw.image(image_urls[imageno]).size(160,160).center(80,80).scale(100/160)
	var btm_image=draw.image(image_urls[imageno]).size(160,160).center(80,80).scale(100/160)

	//下層画像セット
	var btm_rect=draw.rect(100,100).attr({'fill':btm_image}).radius(10).center(80,80)
	//上層画像セット
	var top_rect=draw.rect(100,100).attr({'fill':top_image}).radius(10).center(80,80)
	//top_rect.attr({'fill-opacity':0})

	//画像の塗り位置を再セットしなくともよいメリットがある
	//loadImage
	function loadImage(no){

		//画像ロード
		top_image.load(image_urls[no])
		//直ぐ画像ロード完了前提
		crossFade(no)
	}

	//CROSSFADE
	function crossFade(no){

		//上層に画像セット透明度0
		top_rect.attr({'fill-opacity':0})
		//FADE
		top_rect.animate(1000).attr({'fill-opacity':1}).after(function(){

			//下層画像セット
			btm_image.load(image_urls[no]).attr({'fill-opacity':1})
			//Firefoxちらつき防止対策
			setTimeout(function() {
				//上層消す
				this.attr({'fill-opacity':0})
			},200)
		})
	}

	//ボタン
	var fade_btn3=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(100,145)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	fade_btn3.click(function(){
		loadImage(1)
	})
	var fade_btn4=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(120,145)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	fade_btn4.click(function(){
		loadImage(2)
	})
	var fade_btn5=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(140,145)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	fade_btn5.click(function(){
		loadImage(3)
	})

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


4番、fill-opacity処理 / 5番、画像をopacity()処理 / 6番はloaded()参考です


サンプルJS


	//画像CROSSFADE
	//対象エレメントID
	var draw=SVG('graphics-12d').size(160,160)

	//coment
	var coment=draw.text('4 画像CROSSFADE2').font({leading:0.8}).move(10,0)

	var loadimgUrl,img_no=0,hit_btn=[],gl_no
	,image_urls2=['/main/images/testImage108.jpg','/main/images/testImage107.jpg','/main/images/testImage106.jpg','/main/images/testImage105.jpg']

	var back2=draw.rect(100,100).attr({'fill':'#000'}).radius(10).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//image 100x100
	var top_image2=draw.image(image_urls2[img_no]).size(160,160).center(80,80).scale(100/160)
	var btm_image2=draw.image(image_urls2[img_no]).size(160,160).center(80,80).scale(100/160)

	//下層btm_box画像セット
	var btm_box=draw.rect(100,100).attr({'fill':btm_image2}).radius(10).center(80,80)
	//上層top_box画像セット
	var top_box=draw.rect(100,100).attr({'fill':top_image2}).radius(10).center(80,80)
	.attr({'fill-opacity':0})

	//CROSSFADE
	function crossFade2(no){

		//画像番号
		img_no=no
		//TEXT
		coment.text('' + (img_no+1) + '番目の画像を表示')

		//ボタン色変更
		for (i=0; i < image_urls2.length; i++){
			hit_btn[i].attr({'fill':'#888888'})
			hit_btn[img_no].attr({'fill':'#FF0000'})
		}

		//上層に画像セット透明度0
		top_image2.load(image_urls2[no])
		top_box.attr({'fill-opacity':0})
		//FADE
		top_box.animate(1000).attr({'fill-opacity':1}).after(function(){

			//下層画像セット
			btm_image2.load(image_urls2[no])
			btm_box.attr({'fill-opacity':1})
			btm_image.load(image_urls[no]).attr({'fill-opacity':1})
			//Firefoxちらつき防止対策
			setTimeout(function() {
				//上層消す
				this.attr({'fill-opacity':0})
			},200)
		})
	}

	//画像Loader
	function load_image(no){
		//var no=no

		//画像Loader
		var imageLoader=new Image()
		imageLoader.onload=function(){
			//OKロード完了
			crossFade2(no)
		}
		imageLoader.onerror=function(){
			//NG
			coment.text('LoadingError')
		}
		//URL-SET
		imageLoader.src=image_urls2[no]

	}

	//ボタン/受け渡し番号で設定
	for (i=0; i < image_urls2.length; i++){
		hit_btn[i]=draw.circle(10).attr({'fill':'#888888','stroke':'#FFF','stroke-width':2}).center(i*20+50,145)
		.attr({'no':i})//受け渡し番号no
		//.data('no',i)//dataで受け渡し番号no登録も可能
		.attr({'filter':'url(#dropShadow2)'})//陰影
		.style('cursor','pointer')
		hit_btn[i].click(function(){
			//こうしないと番号がわたらない
			var no=this.attr('no')
			//var no=this.data('no')//dataで受け渡し番号no読み取りも可能
			load_image(no)
		})
	}

	//最初を赤色に
	hit_btn[img_no].attr({'fill':'#FF0000'})

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

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

	//BACK
	var back=draw.rect(100,100).attr({'fill':'#000'}).radius(10).center(80,80)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	//画像
	var image_x=draw.image('/main/images/testImage108.jpg').size(160,160).center(80,80).scale(100/160)
	//表示RECTBOX
	var rectbox=draw.rect(100,100).attr({'fill':image_x}).radius(10).center(80,80)

	//ボタン
	var fade_btn12=draw.circle(10).attr({'fill':'#FF0000','stroke':'#FFF','stroke-width':2}).center(140,140)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	.style('cursor','pointer')
	fade_btn12.click(function(){

		//画像ロード、一旦透明度0で画像をFADE
		image_x.load('/main/images/testImage107.jpg').opacity(0)
		image_x.animate(1000).attr({'opacity':1})

	})

	var txt=draw.text('5 画像FADE opacity()処理').font({leading:0.8})


 

サンプルJSの全表示

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

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

使用画像

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

使用画像サンプル

 


 

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

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

【参照】当方の記事: SVG.js アニメーション(1)


「苦悶式」です。以上。

 


[ この記事のURL ]


タグ:SVG , javascript

 

ブログ記事一覧

年別アーカイブ一覧



[1]