Google画像検索風のギャラリー

sample page : http://sample.mi2log.com/

Markup

```html:
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="g_img.css" type="text/css" />

<script src="jquery.min.js"></script>
<script src="g_img.js"></script>
</head>

<body>
<div id="loading">
	<div id="preload">
		<div class="barBody">
			<p class="bar"></p>
		</div>
		<p class="precount"></p>
	</div>
</div>

<div id="header">
	<span id="tittle">MY Tumblr</span>
</div>
<ol id="google_imgSrc">

<li class="img_a">
	<a href="…/abc.html">
		<img class="imgItem" src=".../abc.jpg" alt="TumblrItems"/>
	</a>
	<span class="title">pageTitle</span>
	<span class="caption">Captions</span>
	<span class="url">
		<a href="uri" target="_blank">URL</a>
	</span>
</li>

<!--Load more Items on Ajax-->

</ol>
</body>

</html>
```

g_img.js

```js:
/* jQuery.ggDiary 

 * Mitsuki Suzuki
 * MIT license
 */	
 
!function($j){
/*!
 * EventEmitter v4.2.0 - git.io/ee
 * Oliver Caldwell
 * MIT license
 * @preserve
 */		
$j.fn.imagesLoaded = function(callback){

  var elems = this.filter('img'),
      len   = elems.length,
      parcentage = 100 / len,
      blank = " ";
            
  elems.on('load.imgloaded',function(){
      if (--len <= 0 && this.src !== blank){ 
        elems.unbind('load.imgloaded');
        callback.call(elems,this);
        $j('#loading').fadeOut(1000,function(){
			$(this).remove();
		});
      }
  }).each(function(l){
	 var src = this.src;
        this.src = blank;
        this.src = src;
		$j(this).on('load',function(){
       	  	$j('#loading').find('.bar').append(' ')
       	  	.end().find('.precount').html($('.bar').text().length * parcentage +'%'); 
        });
  });
  return this;
  
};

$j.fn.ggDiary = function(){
	return this.each(function(){
		new $j.fn.ggDiary.init(this);
	});	
};

$j.fn.ggDiary.init = function(elem){
	
	var init_this = this;
		
	$j(elem).width( $j(window).width() )
	.find('img').imagesLoaded(function(){
	
		//resize window
		$j(window).on('resize',function(){
			$j('li').css({visibility:'hidden'});
			init_this.imgResizeStart();
		});
		
		//move on click
		$j(document).on('click','.img_a',function(){
			init_this.info_window_show($j(this));
			return false;
		});
		
		setTimeout(function(){
			init_this.imgResizeStart();
		},1000);
	});
};

$j.fn.ggDiary.init.prototype = {
	posisionMarkPos : function(elm){
				
		var selectElmWidth = elm.width(),
			selectElmPos = elm.offset(),
			margin = $('#google_imgSrc').css('marginLeft')
				
		,	markerPosM = selectElmPos.left + (selectElmWidth/2);
		$j('.posMarker').css({left:markerPosM - parseInt(margin)});
		
	},
	bottomIndex : function(thisPos,defindex){
				
			var nowindex = defindex
			,	maxlength = $j('.img_a').length;
			
				while( 1 ){
					if( nowindex == maxlength ){ nowindex = 1; break };
					var herePos = $j('.img_a').find('img').eq(nowindex).offset();
					
					nowindex++;
					
					if(thisPos.top < herePos.top ){ break };
				};			
		
		return nowindex;
	},		
	imgResizeStart : function(){
			
		$j('.img_a').width('').height('').find('img').width('').height(200);
		
		var subimgWrap = new Array(),
			imageWrap = $j('.img_a').find('img'),
			maxlength = imageWrap.length
						
		,	firstPos = imageWrap.eq(1).offset();
			lengthIndex = this.bottomIndex(firstPos,0)
				
		,	i = 0,max = 0;
			
			for(; i < maxlength; i = max ){
				
				max = i + lengthIndex;
				
				if( max >= maxlength ){
					max = maxlength;
				};
				subimgWrap = imageWrap.slice( i, max );
				this.imgResize( subimgWrap );
			
			};
			$j('#google_imgSrc').width($(window).width());
	},
	imgResize : function(targetElm){	
			
			var imgwidth = [],
				imgheight = targetElm.eq(0).height()
				
			,	targetElmLength = targetElm.length;
			
			targetElm.height(imgheight);
			
			//個々のimgの幅を格納	する	
			for( var i = 0; i < targetElmLength; i++ ){
			
				var width = $(targetElm).eq(i).width()
				, bodyWidth ,width ,imgheight ,widthReito;
				
				imgwidth.push(width);
				
			};
			
			//配列img要素の合計幅を求める
			for( var i = 0,allimgwidth = 0; i < targetElmLength; i++ ){
			
				allimgwidth = allimgwidth + imgwidth[i];
				
			};
			bodyWidth = $j(window).width();
			
			//個々img要素のサイズを指定する
			for( var i = 0; i < targetElmLength; i++ ){
			
				width = targetElm.eq(i).width(),
				widthReito = width/allimgwidth;
				
				targetElm.eq(i).height('').width((bodyWidth*widthReito)-10|0);
				targetElm.eq(i).parent().parent().height('')
				.width((bodyWidth*widthReito)-30|0).css({visibility:'visible'});
				
			};
			
			imgheight = targetElm.eq(0).height();
			targetElm.height(imgheight).width('');
			
	},
	info_window_show : function(that){
		
		var self = this;
		
		//すでに表示されていれば
		if($j(that).hasClass('view')){
			
			$j('.view').removeClass('view');
			$j('.infoWindow').stop().slideUp(500,function(){
				$(this).remove();
			});
	
			return false;
			
		//info-windowが存在しなければ表示する
		}else{
		
			var thisImg = that.find('img'),
				thisPos = thisImg.offset(),
				viewPos = thisImg.offset(),
				defindex = that.index('.img_a'),
				img_src = that.find('a').attr('href'),
				img_title = that.find('.title').text(),
				img_caption = that.find('.caption').html(),
				img_url = that.find('.url').html()
				
			,	proto_this = this
				
			,	infoWindowPos;
			
			//要素のクラスにviewがあるか評価する
			if($j('.img_a').hasClass('view')){
			
				viewPos = $j('.view').offset();
				$j('.view').removeClass('view');
			
			};
			that.addClass('view');
			
			//現在のwindowの位置を評価する
			if( viewPos.top !== thisPos.top-5 || $('.infoWindow').size() == 0 ){
				
				var element_infoWindow = '<div class="infoWindow" style="display:none">\
											<span class="posMarker">▲</span>\
											<a class="close" href="#">close window</a>\
											<div class="imgWrap">\
												<img class="display" src="'+img_src+'" />\
											</div><div class="img_info">\
												<h3>'+img_title+'</h3>\
												<div>'+img_caption+'</div>\
											</div>\
											<div class="imgurl">'+img_url+'</div></div>';
				
				$j('.infoWindow').slideUp(500,function(){
					$(this).remove();
				});
				
				//エレメントの折り返しでwindowの表示位置を確定する
				$j('.img_a').eq(proto_this.bottomIndex(thisPos,defindex)-2)
				.after(element_infoWindow).each(function(){
				
					$('.infoWindow').slideDown(500,function(){
					
						infoWindowPos = $('.infoWindow').offset();
						$j('body').animate({ scrollTop: infoWindowPos.top-300});
						
					});
					
					proto_this.posisionMarkPos(that);
					
				});
				
			}else{
	
				$j('.display').attr('src',img_src);
				$j('.img_info h3').empty().append(img_title);
				$j('.img_info div').empty().append($(img_caption));
				$j('.img_info .imgurl').empty().append($(img_url));
				
				proto_this.posisionMarkPos(that);
	
			};
			
			//resize window
			$j(window).on('resize',function(){
				
				var thisPos = $j('.view').find('img').offset();
					
				$j('.infoWindow').hide().insertAfter($j('.img_a')
				.eq(self.bottomIndex(thisPos,defindex)-2)).show();
				
				self.posisionMarkPos(that);
				
			});
			
			//close window
			$j(document).on('click','.close',function(){
			
				$j('.view').removeClass('view');
				$j('.infoWindow').stop().slideUp(500,function(){
					$j(this).remove();
				});
				
				return false;
				
			});
		};
	}
	
};

var tumblr_get_images='';

$j.ajax({
	cache: false,
	type: "get",
	dataType: "jsonp",
	url: 'http://api.tumblr.com/v2/blog/mitsuki0524.tumblr.com/'+
				'posts?api_key=zf5B2hRR0zy7PizccYfkoI0z08SlhkiMLHvBgrzfY8qICOvMTW&limit=40&offset=',
	timeout: 10000,
		success: function(Data){
			$.each(Data.response.posts,function(i,v){
				
				var m = this.photos[0].alt_sizes[0].url,
					o = this.photos[0].original_size.url,
					n = this["post_url"],
					p = this["date"];
					c = this["caption"]
				
				tumblr_get_images += '<li class="img_a effect--2 tumblr"><a href="'+o+'"><img class="imgItem" src="'+m+
						'" alt="Tumblr--Items"/></a><span class="title">'+p+
						'</span><span class="caption">'+c+'</span><span class="url"><a href='+n+
						' target="_blank">'+n+'</a></span></li>';
			
			});
			$j('#google_imgSrc').empty().append(tumblr_get_images).ggDiary();
		},			
		error:function(){
			var error = '<div class="error"><h2>FAILED TO LOAD.</h2>'+
						'<p>Sorry,can&#039t get a JSON items.</p>'+
						'<p>Tumblr is temporarily unavailable. Some time pass and access this topic.</p></div>';
			$j(error).appendTo('#google_imgSrc');
		}
});


}(jQuery);
```

```css:
body{
	margin: 0;
	background: #3498db;
	font-family: sans-serif;
}

#header {
	margin-bottom: 17px;
	text-align: center;
	background: #2980b9;
}

#tittle {
	color: #eee;
	font-size: 80px;
	font-weight: 900;
	letter-spacing: 4px;
} 


#google_imgSrc {
	margin: 0 auto;
	list-style-type: none;
	padding: 0;
	overflow: hidden;
	position: relative;
}

.img_a {
	float: left;
	margin: 0 0 20px 17px;
	overflow: hidden;
	max-height: 300px;
	visibility: hidden;
	position: relative;
	cursor: pointer;
	border: 5px solid #fff;
		}.img_a > a > img {
		display: block;
		border:0;
		}.img_a>span{
		display: none;
		}

.infoWindow {
	background: #2980b9;
	margin: 10px 0 20px 0;
	position: relative;
	padding: 20px;
	clear: both;
	zoom: 100%;

	}.infoWindow .posMarker {
		display: block;
		top: -23px;
		font-size: 18px;
		color: #fff;
		position: absolute;
	}.infoWindow .imgWrap {
		float: left;
		width: 40%;
		padding-right: 40px;
		margin-bottom: 20px;
		margin-left: 20px;
		border-right: solid 2px #fff;
		position: relative
		}.infoWindow .imgWrap .display {
			display: block;
			border: #fafafa 10px solid;
			width: 100%;
			position: relative;
	}.infoWindow .img_info {
		float: left;
		font-size: 15px;
		color: #333;
		width: 40%;
		border-radius: 5px;
		padding-left: 10px;
	}.infoWindow h3 {
		font-size: 27px;
		color: #eee;
		margin-top: 0;
		margin-bottom: 10px;
	}.infoWindow .imgurl {
		clear: both;
		margin-top: 20px;
		text-align: right;
		}.infoWindow .imgurl a {
			color: #111;
			text-decoration: none;
			font-size: 15px;
			font-weight: 900;
	}.infoWindow::after {
		content: "";
		zoom: 100%;
		clear: both;
		display: block;
	}.infoWindow .close {
		font-size: 12px;
		color: #567;
		text-decoration: none;
		font-weight: 900;
		background: #fff;
		padding: 5px;
		right: 20px;
		position: absolute;
		}.infoWindow .close:hover {
			color: #5f6f7f;
			background: #89a;
}
	

//未整理

#loading{
transition: 1s linear;
background: #111;
width:100%;
height:100%;
z-index: 10;
position: fixed;
}.barBody{
margin: auto;
overflow: hidden;
}.bar {
transition: 0.5s;
letter-spacing: -4px;
color: #c0392b;
height: 13px;
line-height: 1;
width: 0px;
background: #fff;
}.precount {
text-align: center;
color: #fff;
}#preload {
position: relative;
top: 50%;
margin: auto;
}

```