LINK-GOTO-BACK(元のページに戻る)


SVG.js Carousel表示デモ。DEMO-041


解説の記事ページで収容出来ないデモなどを表示しています。解説などは少なめですので、コードをみて直感的に理解ください。このページではjquery-1.9.1を使用しています。
2016/07/06 新規


DEMO SVG.js Carousel表示

 

ご注意、Chrome.Firefox.IE11等、モダンブラウザでご覧ください(Chrome推奨)。
但し、Mac、Android系の動作は不明です。


Chrome.Firefox.IE11にて確認済み。ブラウザにより多少描画差が有る場合もあります。問題のある場合は自己解決ください。
現時点で、SVG.jsに関する資料サンプルなどは配布元の資料を除き、NET上では「ほぼ皆無」です。
SVG.jsのdropshadowは、エラーで使用出来ないので、当方自作の dropshadow-custom.js (カスタムdropshadow)を使用します。

 

レクトの3D風Carouselとシンボル構成の3D風Carousel

SVG.jsで作る3D風Carouselの原型です。シンボル構成の場合は色々な要素を重ねて表示が可能です。
作り方はもっと方法があるかも知れませんが.....


レクトの3D風Carousel


画像無しのレクト形式の3D風Carouselに成ります。処理方法が複雑で調整に手間取りました。IMAGEでも同じ形式で処理可能です。(但し画像塗りでない場合)

下記ステージでマウスを左右に動かすと、回転速度、回転方向が変わります。薄いダミー図形は100x100の大きさで中央に表示。



 

サンプルJS


//svg-carousel.js
//svg.js用

(function($){

  $(function(){

    function init(){

	//レクトcarousel
	//-----------------------------------

	//対象エレメントID
	var draw=SVG('svg-carousel').size(640,300)

	//TEXT
	var carouseltext=draw.text('svg-carousel').font({leading:0.8})

	//案内用
	var rect=draw.rect(100,100).attr({'fill':'none','stroke':'#CCC','stroke-width':1}).center(320,150)

	//マウスのmoveリスナー設置
	var sum_canvas=document.getElementById("svg-carousel")
	sum_canvas.onmousemove=sum_mouseMoveHandler
	var timeerId=null
	var set_angle=0
	var speed_v=0//初期速度係数0-1

	//マウスHandler未完成
	function sum_mouseMoveHandler(e) {

		//中のインスタンスに反応するので未完成
  		var rect=e.target.getBoundingClientRect()
  		//マウス座標の更新
		sum_mouseX=e.clientX-rect.left
		sum_mouseY=e.clientY-rect.top
		//carouseltext.text(' X ' + sum_mouseX + ' Y ' + sum_mouseY)
		//速度係数 0から+-2
		speed_v=(sum_mouseX-320)/160
		carouseltext.text(' V ' + speed_v)

	}

	//条件
	var spikes,a,center_x,center_y,radius_x,radius_y,angle_v
	spikes=8,a=360/spikes,center_x=320,center_y=150,radius_x=200,radius_y=50,angle_v=0 //12時方向
	var posArr=[]//オブジェクト保存容器
	var elmArr=[]

	//GROUP
	var group=draw.group()

	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 rect=group.rect(100,100).attr({'fill':color})

		rect.attr({'filter':'url(#dropShadow2)'})//陰影
		//インスタンス保存
		elmArr[i]=rect

	}

	//回転処理速度
	setInterval(setpostion,20)//10-20

	function setpostion(){

		//回転を変化
		angle_v +=speed_v
		posArr=[]

		for (i=0; i < spikes; i++){

			//3D風配置/matrix位置補正
			var x=(center_x+radius_x*Math.cos(((i*a+angle_v)-90)*Math.PI/180))
			var y=(center_y+radius_y*Math.sin(((i*a+angle_v)-90)*Math.PI/180))

			//スケール補正とpostion係数保存
			//*0.75すれば最大100%
			var scale_v=y/center_y*0.75

			//matrix位置決め
			var matrix=new SVG.Matrix()
			.scale(scale_v,scale_v,x,y)//.rotate(0,x,y)
			var matrix_v=matrix.toString()
			//centerと伸縮
			elmArr[i].center(x,y).attr('transform',matrix_v)

			//id.postion保存
			posArr.push({'id':i, 'postion':scale_v});

		}

		//postion配列をソート/postion昇順にsort
		posArr.sort(function(a,b) {
			var x=a.postion;
			var y=b.postion;
			return x > y ? 1 : -1}
		)
		//重ね変更
		for (var i=0; i < posArr.length; i++){
			//エレメントを取り出す
			var rect=elmArr[posArr[i].id]
			//エレメントの重ね順補正
			rect.front()
		}

	}


    }

    //start
    init()

  });

})(jQuery);


サンプルJSの簡単な説明

3D風Carouselにするため、角度を変更して外周配置位置を変更しています。レクトなどの書き換えは行っていません。その都度重なり順を変更して、3D風に見せかけています。

SVGでこのような処理をすることは余り無いと思います。(無意味に勢いで作っているだけです)


1. 角度変更はタイマーで10ミリ秒に1回処理。(10-50ミリ秒位が適正のようだ)
2. ステージにマウスが入ると、回転速度方向が変わるようにしていますが、処理は削除できる。
(中の図形にも反応するので、本来は別形式でつくるのが良いと思います。簡単なのでとりあえず。)
3. 画像表示も出来るが、塗りの場合は別処理になる。(別途サンプル参照)
4. CSS Matrix処理と似通っているが、SVGはクセがあり少し面倒である。
5. 処理が悪いと、陰影が途中で切れます。回転軸を図形の中心にする事が重要です。
(注意、このページは、jQuery1.9のため、dropshadow-custom.jsで陰影処理)
6. レクトのみで利用することは考えられませんので、原理の説明用です。このままで画像に切り替えて応用可能です。
7. USE、シンボル等でレクトの中を上手く構成出来れば応用可能ですが、これも大変な作業と思います。
(下記、シンボル構成の3D風Carousel参照)

 

グループ構造の中に構成する場合

グループ構造の中に構成すれば、全体の移動などレイアウトが楽になります。他の処理はまったく同じになります。


グループに構成しない場合
//レクト生成
var rect=draw.rect(100,100).attr({'fill':color})

---------------------------------------------------
グループに構成する場合

//GROUP
var group=draw.group()

//レクト生成
var rect=group.rect(100,100).attr({'fill':color})

グループ移動が出来る
group.x(値).y(値)

図形中心位置の移動

角度を加える都度に外周位置を計算してそこに図形を移動させます。matrixで処理した場合陰影の切れが無く正常に成ります。

.scale(scale_v,x,y)でも良いはずであるが、不安定なため.scale(scale_v,scale_v,x,y)にしている。


//matrix位置決め
var matrix=new SVG.Matrix()
.scale(scale_v,scale_v,x,y)//.rotate(0,x,y)
var matrix_v=matrix.toString()
//centerと伸縮
elmArr[i].center(x,y).attr('transform',matrix_v)

重なり順の修正

3D風Carouselにするため、重なり順の修正を行っています、Y位置の順序またはスケールの順序を並び替えして、下記の様に処理しています。外周は常時変わるのでY位置で並び替えれば擬似3Dになる。


//postion配列をソート/postion昇順にsort
posArr.sort(function(a,b) {
	var x=a.postion;
	var y=b.postion;
	return x > y ? 1 : -1}
)
//重ね変更
for (var i=0; i < posArr.length; i++){
	//エレメントを取り出す
	var rect=elmArr[posArr[i].id]
	//エレメントの重ね順補正
	rect.front()
}

画像に入れ替えた場合のサンプル

画像に入れ替えた場合は下記ページにサンプルが有ります。処理方法はまったく同じです。

【参照】当方の記事: 画像の3D風Carousel

 

 

シンボル構成の3D風Carousel

symbol()を利用すれば多くの要素を重ねて描画できますから、レクトのみで利用することも可能となります。
但し、center()が機能しない為少々工夫が必要です。下記、サンプルでは画像を表示しているだけです。



 

サンプルJS


//svg-carousel-sbl.js
//svg.js用symbol構成

(function($){

  $(function(){

    function init(){

	//symbol構成レクトcarousel
	//-----------------------------------

	//画像URL
	var imgUrls=['testImage101.jpg','testImage102.jpg','testImage103.jpg','testImage104.jpg','testImage105.jpg','testImage106.jpg','testImage107.jpg','testImage108.jpg']

	//対象エレメントID
	var draw=SVG('svg-carousel-symbol').size(640,300)

	//TEXT
	var carouseltext=draw.text('svg-carousel').font({leading:0.8})

	//案内用
	var rect=draw.rect(100,100).attr({'fill':'none','stroke':'#CCC','stroke-width':1}).center(320,150)

	//マウスのmoveリスナー設置
	var sum_canvas=document.getElementById("svg-carousel-symbol")
	sum_canvas.onmousemove=sum_mouseMoveHandler
	var timeerId=null
	var set_angle=0
	var speed_v=0//初期速度係数0-1

	//マウスHandler未完成
	function sum_mouseMoveHandler(e) {

		//中のインスタンスに反応するので未完成
  		var rect=e.target.getBoundingClientRect()
  		//マウス座標の更新
		sum_mouseX=e.clientX-rect.left
		sum_mouseY=e.clientY-rect.top
		//carouseltext.text(' X ' + sum_mouseX + ' Y ' + sum_mouseY)
		//速度係数 0から+-2
		speed_v=(sum_mouseX-320)/160
		carouseltext.text(' V ' + speed_v)

	}

	//条件
	var spikes,a,center_x,center_y,radius_x,radius_y,angle_v
	spikes=8,a=360/spikes,center_x=320,center_y=150,radius_x=200,radius_y=50,angle_v=0 //12時方向
	var posArr=[]//オブジェクト保存容器
	var elmArr=[]

	var symbol_w,symbol_h
	symbol_w=120,symbol_h=120
	var symbols=[]

	//GROUP
	var group=draw.group()

	//シンボル作成
	for (i=0; i < spikes; i++){

		symbols[i]=draw.symbol()

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

		//シンボルレクト生成
		//symbols[i].rect(symbol_w,symbol_h).attr({'fill':'none'})//仮想ベース描画しなくともOK
		symbols[i].rect(100,100).radius(10).attr({'fill':color}).x(10).y(10)
		.attr({'filter':'url(#dropShadow2)'})//陰影
		symbols[i].rect(80,80).attr({'fill':'#FFF'}).x(20).y(20)
		//symbols[i].rect(50,50).attr({'fill':'#CCC'}).x(35).y(35)
		//画像表示
		symbols[i].image('/main/images/'+imgUrls[i]).size(50,50).x(35).y(35)

	}

	//配置
	for (i=0; i < spikes; i++){

		//レクト生成
		var rect=group.use(symbols[i])
		//インスタンス保存
		elmArr[i]=rect

	}

	//回転処理速度
	setInterval(setpostion,20)//10-20

	function setpostion(){

		//回転を変化
		angle_v +=speed_v
		posArr=[]

		for (i=0; i < spikes; i++){

			//仮想3D風配置位置
			var x=(center_x+radius_x*Math.cos(((i*a+angle_v)-90)*Math.PI/180))
			var y=(center_y+radius_y*Math.sin(((i*a+angle_v)-90)*Math.PI/180))
			//実際配置シンボル位置
			var x2=x-symbol_w/2
			var y2=y-symbol_h/2

			//スケール補正とpostion係数保存
			//*0.75すれば最大100%
			var scale_v=y/center_y*0.75

			//matrix位置決め
			var matrix=new SVG.Matrix()
			.scale(scale_v,scale_v,x,y)//.rotate(0,x,y)
			var matrix_v=matrix.toString()
			//moveと伸縮/シンボルにcenterは機能しない
			elmArr[i].move(x2,y2).attr('transform',matrix_v)

			//id.postion保存
			posArr.push({'id':i, 'postion':scale_v});

		}

		//postion配列をソート/postion昇順にsort
		posArr.sort(function(a,b) {
			var x=a.postion;
			var y=b.postion;
			return x > y ? 1 : -1}
		)
		//重ね変更
		for (var i=0; i < posArr.length; i++){
			//エレメントを取り出す
			var rect=elmArr[posArr[i].id]
			//エレメントの重ね順補正
			rect.front()
		}

	}


    }

    //start
    init()

  });

})(jQuery);


サンプルJSの簡単な説明

原理的には上記のレクト3D風Carouselをシンボル構成にして一部修正しただけです。「陰影」が切れたりcenter()が機能しないため少々工夫しています。

SVG自体がまだなじみの薄いものですから、SVGでこのような処理をすることは余り無いと思います。


1. 「陰影」切れを防ぐため仮想的に中のレクトの描画範囲を広げています。
2. スケール変更など前の配置位置計算値をそのまま利用、center()が機能しない為にmove()で移動して修正
3. サンプルでは画像を表示しているだけで、加工を行っていませんので画像先読みは省略しています。
4. もう少し複雑に構成することも可能と思います。
5. グループの中に多要素を収容する方法もあるが、返って面倒のようです。シンボル構成が簡単のようだ。


[修正の説明図]

zu

 

シンボルの構成

「陰影」切れを防ぐため、シンボルの要素は.x().y()または.move()で移動させます。
一番下の、仮想ベースを着色描画すると全体の配置状況を確認できます。ここでは4方向10ピクセル大きくしています。


//シンボル作成
for (i=0; i < spikes; i++){

	symbols[i]=draw.symbol()

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

	//シンボルレクト生成
	//symbols[i].rect(symbol_w,symbol_h).attr({'fill':'none'})//仮想ベース描画しなくともOK
	symbols[i].rect(100,100).radius(10).attr({'fill':color}).x(10).y(10)
	.attr({'filter':'url(#dropShadow2)'})//陰影
	symbols[i].rect(80,80).attr({'fill':'#FFF'}).x(20).y(20)
	//symbols[i].rect(50,50).attr({'fill':'#CCC'}).x(35).y(35)
	//画像表示
	symbols[i].image('/main/images/'+imgUrls[i]).size(50,50).x(35).y(35)

}

外周図形の配置

center()が機能しないためmove()で計算値を修正配置します。このほうが計算がやり易い。
スケール計算の都合で、x y 計算はそのまま行い、x2 y2 で修正値を算出して、移動配置させています。重ね順の修正は同じです。


for (i=0; i < spikes; i++){

	//仮想3D風配置位置
	var x=(center_x+radius_x*Math.cos(((i*a+angle_v)-90)*Math.PI/180))
	var y=(center_y+radius_y*Math.sin(((i*a+angle_v)-90)*Math.PI/180))
	//実際配置シンボル位置
	var x2=x-symbol_w/2
	var y2=y-symbol_h/2

	//スケール補正とpostion係数保存
	//*0.75すれば最大100%
	var scale_v=y/center_y*0.75

	//matrix位置決め
	var matrix=new SVG.Matrix()
	.scale(scale_v,scale_v,x,y)//.rotate(0,x,y)
	var matrix_v=matrix.toString()
	//moveと伸縮/シンボルにcenterは機能しない
	elmArr[i].move(x2,y2).attr('transform',matrix_v)

	//id.postion保存
	posArr.push({'id':i, 'postion':scale_v});

}

外周要素のZ軸回転


elmArr[i].move(x2,y2).attr('transform',matrix_v).rotate(30)

 

 

サンプルJSの全表示

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

● サンプルJSの全表示 svg-carousel.js

● サンプルJSの全表示 svg-carousel-sbl.js

 

JSの構造

下記の様に、サンプルではjQueryの構造の中にありますが、どのような形でもページのHTMLが構築されてからJSを実行出来るなら結構と思います。
処理条件などにより遅延など必要なら下記の様にする


(function($){

  $(function(){

    function init(){

	//

    }
    setTimeout(function() {
      //start
      init()
    },1000);

  });

})(jQuery);

CSS


.carousel-elm {
width:640px;
height:300px;
border:1px #000000 solid;
overflow:hidden;
}

使用画像

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

使用画像サンプル

 

 

詳細説明などは、記事ページなどを参照ください。

 

以上。

 

LINK-GOTO-BACK(元のページに戻る)