POPSブログ

jQuery レスポンシブ・Transitもどき3 コントロール付き

410

  Category:  jquery2017/03/05 pops 

クロスフェードおよびスライドなどの各種エフェクト組み合わせのTransitもどきに、Pager コントロール等をつけました。画像の大きさは常に同じで、マスクの伸縮により表示範囲を変える特殊なものです。原則高さの無い画像専用です。

 

responsive

 

jQuery レスポンシブ・Transitもどき処理のテスト3

色々なエフェクト処理を内包したものです。CSS3処理では有りませんので、Transitもどき処理とでも呼ぶことにします。
Transitもどき処理は「前ページ」「前々ページ」にその原型と、説明などをしています。
ここでは、高さを一定にして表示する「アレンジ」です。スマートフォンなどで見易いかも知れません。

 

DEMO1 (背景黒 Pager コントロール)

通常のHTML5ページでみてみます。ブラウザ幅を変更して確認ください。

● 通常デモページ (http://pops-web.com/main/baserhtml/test007.html) : 通常ページでの表示デモ

● スマートフォン等の表示 : 確認ツールで見た場合の表示

 

DEMO2 (角丸陰影 Pager コントロール)

通常のHTML5ページでみてみます。ブラウザ幅を変更して確認ください。

● 通常デモページ (http://pops-web.com/main/baserhtml/test007b.html) : 通常ページでの表示デモ

● スマートフォン等の表示 : 確認ツールで見た場合の表示

 

表示の特徴

高さが常に同じですから、スマートフォンで画像が縮小されない特徴があります。画像の高さは200px位が良いと思います。
スマートフォンを横にした場合に操作性が良いのではないでしょうか...
異常に縮小される事が有りませんので、場合によっては使い道があるかも知れません。


[図] PC、スマートフォンとの表示の違い

zuzu

 

1. 高さを一定にしてスマートフォンなどで見易い様にします。(見易いかも知れません)
2. 横はウィンドウ幅でマスクされデバイスにより異なります。画像「表示範囲」をかえているだけですが...
3. 画像中央が常に表示範囲の中心になるようにセットされます。(ペースを移動)
4. 以前の処理では、ブラウザ外側に空白が出る場合が多いが、今回はレスポンシブに見えるが、実際は普通の処理で有ることです。マスクで表示範囲は変えているが、基本的に構造の大きさは変わっていない。

 

構造と簡単な説明

エフェクト専用のimg要素を最上層に配置して、何らかのエフェクト処理します。animate()を利用すれば多用な変化をさせることが可能です。このJSでは、約15種のエフェクトを実現しています。
ここでは、Pagerとコントロールボタンをつけた仕様にしています。

構成上の説明などは、「前ページ」を参照ください。


zu

 

1. 原則、外側divにmax-width:880pxを設定します。(media screenでの設定も同じ)
今回の構造に限り、一応念のための処理です。
2. ボーダー、陰影処理でも、修正する事により左右の切れが無くなり、適正に配置されます。
(仮想マージンを20前後設定して画像を小さくします)
3. Pager、はボタン式、サムネール式より選べます。大きさはCSSで調整します。
4. コントロールは画像の内側に配置になります。(マスクにappndしています)
5. スマートフォンでは画像枚数は少ないほうが良い。


● 対応ブラウザと検証

html5.js、css3-mediaqueries.jsを読み込んでいますので、仕方なく「IE」をも検証しました。
当方としては別段IEに対応する気は毛頭有りませんし、特にIE 9 8 7はもはや対応すべきではなく「排除」すべきです。


1. 一応、モダンブラウザおよび、IE 11 10 9 8 7まで表示可能です。(IEは問題ありすぎ...)
(IE11はモダンブラウザに属するが、CSS3、Canvas対応などでは他より劣るので余り対応したくない)
2. 検証はブラウザ付属ので「ペロッパーツール」および「確認ツール」で行いました。(一部、iphone6で確認)
3. デモページで使用のjQueryは jquery-1.11.3.min.js です。


構造の相違

div要素、#transitMaskが追加され、伴ってマスク層に成ります。コントロールは#transitMaskにappendされます。
#transitBaseは中心補正のためにx方向に移動して使用されます。


<div id="transitMask">
 <div id="transitBase">
  <img />
  <img />
  .
  .
 </div>
</div>

HTML CSS JS

下記にHTML CSS JSを提示します。CSS JSの名前は自由です。単純なimgのみの構成にしました。
このようなものは「A-link」をつけて使用される場合が多いようです。(A-linkは簡単に付加できます)

HTML

画像URLは当方のデモでのものです。実際にはユーザー設置条件にあわせます。
最後のimg要素は画像処理用の「エフェクト層」に成ります。自動生成しませんので、手書きで書いてください。

DEMO2の場合の例、背景用のラップなし。


<div id="transitMask">
 <div id="transitBase">
  <img class="image-parts" src="/main/images/tokyo01.jpg" />
  <img class="image-parts" src="/main/images/tokyo02.jpg" />
  <img class="image-parts" src="/main/images/tokyo03.jpg" />
  <img class="image-parts" src="/main/images/tokyo04.jpg" />
  <img class="image-parts" src="/main/images/tokyo05.jpg" />
  <img id="top-imageitem" class="image-parts" src="/main/images/tokyo01.jpg" />
 </div>
</div> 

A-linkを付ける場合は、下記の様に書く。最後のエフェクト層はそのままです。
CSSの変更などは不要です。


<div id="transitMask">
 <div id="transitBase">
  <a href="#"><img class="image-parts" src="/main/images/tokyo01.jpg" /></a>
  .
  .

  <img id="top-imageitem" class="image-parts" src="/main/images/tokyo01.jpg" />
 </div>
</div>

背景などを着色する場合はラップします。構造設計、CSSは自由です。


<div id="transitBox">
<div id="transitMask">
 <div id="transitBase">
	画像略す
 </div>
</div>
</div>

DEMO1の場合の例、背景用のラップあり。


<div id="transitBox">
<br />
<div id="transitMask">
 <div id="transitBase">
  <img class="image-parts" src="/main/images/tokyo01.jpg" />
  <img class="image-parts" src="/main/images/tokyo02.jpg" />
  <img class="image-parts" src="/main/images/tokyo03.jpg" />
  <img class="image-parts" src="/main/images/tokyo04.jpg" />
  <img class="image-parts" src="/main/images/tokyo05.jpg" />
  <img id="top-imageitem" class="image-parts" src="/main/images/tokyo01.jpg" />
 </div>
</div>
</div>

HTML5でのテスト表示結果

今回はレスポンシブに見えるが、実際は普通の処理で有ることです。モダンブラウザおよび IE7-11 まで表示結果はOKでした。
max-widthを利用しなくとも処理できる。


DEMEの説明

simple-transit4.js

コントロール、Pagerなどを設定出来るようにしました。詳細はJS先頭部分を参照ください。
アレンジなどはCSSで行いますが使用者の自由です。


通常、リサイズ修正をした場合にブラウザ外側に空白が出る場合が多いが、デモでの構造では空白はでない。
改造などでの不具合を考慮して念のため、以下の様にする。

今回のものに限り、max-width方式を設定しなくとも、JSでの補正だけでレスポンシブに成ります。



max-width設定の場合、空白がでる場合もある

#transitMask{
position:relative;
max-width:960px;
height:200px;
margin:0 auto;
padding:0;
background-color:#000000;
overflow:hidden;
}

空白除去のため必要です
#wrappr{
overflow:hidden;
}

● @media screen設定の場合

デモはこちらを設定しました。


@media screen設定の場合、空白が出ない

#transitMask{
position:relative;
width:960px;
height:200px;
margin:0 auto;
padding:0;
background-color:#000000;
overflow:hidden;
}

/* 上書き */
@media screen and (max-width:959px){
	#transitMask{
		width:100%;
	}
}

@media screen設定のため
下記の空白除去は原則不要です
#wrappr{
overflow:hidden;
}

サンプルCSS (DEMO1,DEMO2)

CSS、(DEMO1)


/* 重要 */
#Page{
/*overflow:hidden;*/
}

#header,#main{
width:100%;
height:auto;
margin:0 auto;
text-align:center;
background-color:#eee;
}

/* 機能します */
#transitBox{
position:relative;
width:100%;
height:auto;
background-color:#000;
}

/* 構造 */
#transitMask{
position:relative;
width:960px;
height:200px;
margin:0 auto;
padding:0;
background-color:#000000;
overflow:hidden;
}

#transitBase{
position:relative;
width:960px;
height:200px;
margin:0 auto;
padding:0;
}

/* 上書き */
@media screen and (max-width:959px){
	#transitMask{
		width:100%;
	}
}

/* image */
#transitBase img{
position:absolute;
top:0;left:0;
width:960px;
height:100%;
margin:0;
padding:0;
}

/*span構成コントロール*/
#transitMask #base-prev{
display:block;
position:absolute;
top:0;left:0;
width:20px;
height:100%;
margin:0;
padding:0;
background:url('/main/baserhtml/images/arrow_left_a3.png') no-repeat center center;
cursor:pointer;
z-index:100;
}
#transitMask #base-next{
display:block;
position:absolute;
top:0;right:0;
width:20px;
height:100%;
margin:0;
padding:0;
background:url('/main/baserhtml/images/arrow_right_a3.png') no-repeat center center;
cursor:pointer;
z-index:101;
}

/* btn */
#btnBox{
width:100%;
height:auto;
margin:10px auto;
text-align:center;
z-index:1000;
}
#btnBox span{
width:100%;
height:auto;
margin:5px;
font-size:16px;
color:#888888;
cursor:pointer;
}
#btnBox span.active{
color:#ff0000;
}

#btnBox span img{
width:40px;
height:18px;
opacity:0.5;
filter:alpha(opacity=50);
-ms-filter:"alpha(opacity=50)";
}
#btnBox span img.active{
opacity:1.0;
filter:none;
}

CSS、(DEMO2)


/* 重要 */
#Page{
/*overflow:hidden;*/
}

#header,#main{
width:100%;
height:auto;
margin:0 auto;
text-align:center;
background-color:#eee;
}

/* 機能します */
#transitBox{
position:relative;
width:100%;
height:auto;
background-color:#000000;
}

/* 構造 */
#transitMask{
position:relative;
width:960px;
height:200px;
margin:0 auto;
padding:0;
background-color:#000000;
box-shadow:0px 0px 14px rgba(0,0,0,0.7);
border-radius:10px;
overflow:hidden;
}

#transitBase{
position:relative;
width:960px;
height:200px;
margin:0 auto;
padding:0;
}

/* 上書き */
@media screen and (max-width:959px){
	#transitMask{
		width:100%;
	}
}

/* image */
#transitBase img{
position:absolute;
top:0;left:0;
width:960px;
height:100%;
margin:0;
padding:0;
}

/*span構成コントロール*/
#transitMask #base-prev{
display:block;
position:absolute;
top:0;left:0;
width:20px;
height:100%;
margin:0;
padding:0;
background:url('/main/baserhtml/images/arrow_left_a3.png') no-repeat center center;
cursor:pointer;
z-index:100;
}
#transitMask #base-next{
display:block;
position:absolute;
top:0;right:0;
width:20px;
height:100%;
margin:0;
padding:0;
background:url('/main/baserhtml/images/arrow_right_a3.png') no-repeat center center;
cursor:pointer;
z-index:101;
}

/* btn */
#btnBox{
width:100%;
height:auto;
margin:10px auto;
text-align:center;
z-index:1000;
}
#btnBox span{
width:100%;
height:auto;
margin:5px;
font-size:16px;
color:#888888;
cursor:pointer;
}
#btnBox span.active{
color:#ff0000;
}

#btnBox span.active{
color:#ff0000;
}

#btnBox span img{
width:40px;/*40x18*/
height:18px;
border:#fff 1px solid;
}
#btnBox span img.active{
border:#f00 1px solid;
}

/*
#btnBox span img{
width:40px;
height:18px;
opacity:0.5;
filter:alpha(opacity=50);
-ms-filter:"alpha(opacity=50)";
}
#btnBox span img.active{
opacity:1.0;
filter:none;
}
*/

サンプルJS

JS、(DEMO1、DEMO2、違いなし)


//simple-transit4.js
//簡易構造画像エフェクト/拡大修正/画像の大きさ不変
//Pagerコントロール付き

(function($){

  $(function(){

    function init(){

	//画像の大きさ
	var image_w=960;
	var image_h=200;
	//左右マージン合計値
	var margin=20;

	//時間
	var cycle_time=6000;
	var fade_time=800;

	//コントロールBTNの使用
	var ctrlbtn_use=true;
	//BTNグループの使用true、不使用false
	var hitbtn_use=true;
	//サムネール使用true、ボタンはfalse
	var thumb_use=true;
	//サムネールの大きさはCSSで設定

	//オブジェクト
	//var box_elm_wrap=$('#transitBox')
	var mask_elm=$('#transitMask');//マスク
	var box_elm=$('#transitBase');//ベース
	var img_elm=$('#transitBase img');
	var top_item=$('#top-imageitem');//ID

	//変数
	var image_max=img_elm.length-1;
	var timerID=null;
	var image_no=0;
	var keep_no=0;
	var image_urls=[];
	var partselm=[];
	var item_w;
	var all_w;

	//エフェクト追加変数
	var cross_url="";
	var keep_url="";
	var window_width=0;
	var animeflag=false;
	//BTNオブジェクト
	var hit_btns=[];

	//Effectデータ
	var once=false;
	var move_type="in";
	var mvtypes=['in','out'];

	//ポジションと大きさのデータ
	//scale-xy,scale-y,scale-x,slid-up,slide-dn,slid-left,slide-right,scale-righ,scale-left,scale1.5,scale,scale,scale2,scale0.5,fade,fade,fade
	var w_array=[0,1,0,1,1,1,1,0,0,              1.5,     1.5,    1.5,      2,     0.5,     1,1,1];
	var h_array=[0,0,1,1,1,1,1,0,0,              1.5,     1.5,    1.5,      2,     0.5,     1,1,1];
	var posx_array=[0.5,0,0.5,0,0,1,-1,0,1,     -0.25,   -0.25,   -0.25,   -0.5,   0.25,    0,0,0];
	var posy_array=[0.5,0.5,0,1,-1,0,0,0,1,     -0.25,    0,      -0.5,    -0.5,   0.25,    0,0,0];

	//現在の画像の大きさ
	var width_v=image_w;
	var height_v=image_h;

	//一旦全てを消す/URL取得
	box_elm.find("img").each(function(i){
		$(this).css({'z-index':i,'display':'none'});
		partselm[i]=img_elm.eq(i);//オブジェクト保存
		image_urls[i]=$(this).attr('src');
	});

	//display早めにした
	partselm[0].css({'display':'block'});
	top_item.css({'display':'block'});

	//コントロールBTN/span構成
	if(ctrlbtn_use){

		//append #transitMask
		mask_elm.append('<span id="base-prev"></span>');
		mask_elm.append('<span id="base-next"></span>');

		//オブジェクト
		var next_elm=$('#base-next');
		var prev_elm=$('#base-prev');

		//click-action
		next_elm.click(function(){
			//アニメ中はキャンセル
			if(animeflag){return false}
			//タイマーclear
			clearTimeout(timerID);
			next_set();
			return false
		});
		prev_elm.click(function(){
			//アニメ中はキャンセル
			if(animeflag){return false}
			//タイマーclear
			clearTimeout(timerID);
			prev_set();
			return false
		});

	}
	//BTNグループaction-set
	if(hitbtn_use){

		//後ろにappendする
		mask_elm.after('<div id="btnBox"></div>');
		var mark="&#9679;";
		//make-btn
		var btnhtml="";
		for (var i=0; i < image_max; i++) {

			//ID名を付ける
			var name="hitbtn"+i;
			if(thumb_use){
				thumb='<img class="thumb" src="'+ image_urls[i] +'" />';
				btnhtml += '<span id="' + name +'">' + thumb + '</span>';
			}else{
				btnhtml += '<span id="' + name +'">' + mark + '</span>';
			}

		}
		//append #btnBox
 		$('#btnBox').append(btnhtml);
		btnhtml="";

		//action
		$('#btnBox').find('span').each(function(i){
			$(this).click(function(){hitno_set(i);});
		});
		//オブジェクト保存
		for (var i=0; i < image_max; i++) {
			hit_btns[i]=$('#hitbtn'+i);
		}

	}
	//最初をactiveに
	if(hitbtn_use){
		if(thumb_use){
			hit_btns[0].children("img").addClass('active');
		}else{
			hit_btns[0].addClass('active');
		}
	}

	//初期化、寸法きめ
	resizeFunc();

	//スタート遅延
	set_timer();

	//IN OUT エフェクト処理
	function effectImage(){

		animeflag=true;
		//IN OUT取得
		var move_type=mvtypes[Math.floor(Math.random()*mvtypes.length)];
		//最初はIN
		if(!once){
			once=true;
			move_type="in";
		}
		//in強制設定
		//move_type="in";

		if(hitbtn_use){
			if(thumb_use){
				hit_btns[keep_no].children("img").removeClass('active');
			}else{
				hit_btns[keep_no].removeClass('active');
			}
		}

		//位置データのランダム設定
		var chg_no=Math.floor(Math.random()*w_array.length);

		//現在の大きさから計算
		var pos_x=posx_array[chg_no]*width_v;
		var pos_y=posy_array[chg_no]*height_v;
		var w_v=w_array[chg_no]*width_v;
		var h_v=h_array[chg_no]*height_v;

		//IN
		if(move_type=='in'){

			//事前処理
			cross_url=image_urls[image_no];
			//cross_url画像切り替え
			top_item.attr({'src':cross_url}).css({'left':pos_x,'top':pos_y,'width':w_v,'height':h_v,'opacity':0});
			top_item.css({'display':'block'});//上層
			//IN エフェクト
			top_item.animate({'left':0,'top':0,'width':width_v,'height':height_v,'opacity':1},fade_time,function(){

				//階層処理
				partselm[image_no].css({'display':'block'});
				top_item.css({'display':'none'});
				partselm[keep_no].css({'display':'none'});
				//処理番号URL保存
				keep_no=image_no;
				keep_url=cross_url;
				animeflag=false;

			if(hitbtn_use){
				if(thumb_use){
					hit_btns[image_no].children("img").addClass('active');
				}else{
					hit_btns[image_no].addClass('active');
				}
			}

				set_timer();

			});
		};
		//OUT
		if(move_type=='out'){

			//事前処理
			cross_url=image_urls[image_no];
			//keep_url画像切り替え
			top_item.attr({'src':keep_url}).css({'left':0,'top':0,'width':width_v,'height':height_v,'opacity':1});
			//上層表示
			top_item.css({'display':'block'});

			//下層表示
			partselm[image_no].css({'display':'block'});
			partselm[keep_no].css({'display':'none'});

			//OUT エフェクト
			top_item.animate({'left':pos_x,'top':pos_y,'width':w_v,'height':h_v,'opacity':0},fade_time,function(){

				//上層処理
				top_item.css({'display':'none'});

				//処理番号URL保存
				keep_no=image_no;
				keep_url=cross_url;
				animeflag=false;

			if(hitbtn_use){
				if(thumb_use){
					hit_btns[image_no].children("img").addClass('active');
				}else{
					hit_btns[image_no].addClass('active');
				}
			}

				set_timer();

			});
		};


	}

	//次ぎの開く要素を計算
	function next_set() {

		//タイマーclear
		clearTimeout(timerID);
		//次ぎの番号
		image_no +=1;
		if (image_no > (image_max-1)) {image_no=0;}
		effectImage();

	}

	//戻る要素を計算
	function prev_set() {

		//タイマーclear
		clearTimeout(timerID);
		//戻る番号
		image_no -=1;
		if (image_no < 0) {image_no=image_max-1;}
		effectImage();

	}
	//指定番号で計算
	function hitno_set(no) {

		//表示番号ならキャンセル
		if(no==keep_no){return false}
		//アニメ中はキャンセル
		if(animeflag){return false}
		//タイマーclear
		clearTimeout(timerID);
		//番号
		image_no=no;
		effectImage();
		return false

	}

	//タイマーSET
	function set_timer() {

		//一旦切ってからセット
		clearTimeout(timerID);
		timerID=setTimeout(next_set,cycle_time);

	}

	//ラップの大きさを修正
	//window-resize
	$(window).resize(resizeFunc);

	//スライドのためBOXの大きさ設定
	function resizeFunc(){

		window_width=$(window).width();
		//全体の横幅
		all_w=image_w+margin;

		//画像修正/全体の横幅判定
		if(window_width<all_w){

			all_w=window_width;
			var w=window_width-margin;//マスクマージン修正

			//現在の大きさ
			width_v=image_w;
			height_v=image_h;
			var pos_base=(image_w-w)/2*-1;//補正値

			//マスク横幅変更
			mask_elm.css({'width':w,'height':image_h});
			//ベース中央移動補正
			box_elm.css({'left':pos_base,'width':w,'height':image_h});

		}else{

			//現在の大きさ
			width_v=image_w;
			height_v=image_h;

			//マスク横幅変更
			mask_elm.css({'width':image_w,'height':image_h});
			//ベース中央移動補正
			box_elm.css({'left':0,'width':image_w,'height':image_h});

		}

	}

    }//init end

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

    //遅延
    setTimeout(function() {
      init();
    },10);

  });

})(jQuery);


Pager コントロール 陰影処理

Pager コントロール 陰影処理などは通常の「Transitもどき」とほぼ同じですから「前ページ」を参照ください。


 

JS最後の遅延処理

主にIE系ですが、画像を読み込んでからでなければ、上手く動作しない場合など1秒位遅延させると良い場合があります。その対策で付けていますが、今回は必要ではありませんでした。


//遅延/IE7
setTimeout(function() {
 init();
},10);

 

使用画像

原則、使用者が用意します。(960x200サイズ) : サンプルでの使用画像


透過PNG画像、下に来る画像の色合いによっては認識しづらい場合が有ります。下は自作品で、品質は良くない。
別画像の必要なかたは自作するか、ネット上でプラグイン付属画像をパクッテください。

透過画像 透過画像 透過画像 透過画像 透過画像 透過画像 透過画像 20x20透過画像
---


前ページ掲載のTransitもどき、Pager コントロールなしのJSです。

【参照】当方の記事: jQuery レスポンシブ・Transitもどきコントロール付き



 

モット効率的な方法もあるかも知れませんが、まだ判りません。誰か考えてください。
簡単ですが、以上です。

 


[ この記事のURL ]


タグ:jquery , Effect , css3 , html5

 

ブログ記事一覧

年別アーカイブ一覧



[1]