<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codrops &#187; image gallery</title>
	<atom:link href="http://tympanus.net/codrops/tag/image-gallery/feed/" rel="self" type="application/rss+xml" />
	<link>http://tympanus.net/codrops</link>
	<description>Useful resources and inspiration for creative minds</description>
	<lastBuildDate>Sun, 19 May 2013 17:43:37 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>3D Image Gallery Room</title>
		<link>http://tympanus.net/codrops/2013/01/15/3d-image-gallery-room/</link>
		<comments>http://tympanus.net/codrops/2013/01/15/3d-image-gallery-room/#comments</comments>
		<pubDate>Tue, 15 Jan 2013 13:48:52 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[image gallery]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=13564</guid>
		<description><![CDATA[An experimental image gallery with a realistic touch: the images are displayed in a 3D room with walls.]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/3DGalleryRoom/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom.jpg" alt="3D Gallery Room" width="580" height="315" class="alignnone size-full wp-image-13595" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/3DGalleryRoom/">View demo</a> <a class="download" href="http://tympanus.net/Development/3DGalleryRoom/3DGalleryRoom.zip">Download source</a></p>
<p>Today we want to share another 3D experiment with you: a gallery room in 3D. The idea is to create a realistic environment for an image exposition using CSS 3D transforms. Images are &#8220;hanged&#8221; along a wall which will have an end. Once the end of the wall is reached, a rotation will happen and we&#8217;ll be turned to the next wall whith more images. To give a real sensation of being in a room, we only have four walls and corners. Each image will have a little description tag with a small-sized font and when clicking on it, a larger version will appear from below.</p>
<p><strong>Please note that this is highly experimental and probably very buggy.</strong></p>
<p>We recommend to view the demos in Google Chrome, they perform best there.</p>
<p>We use the following initial structure for adding figures and their captions:</p>
<pre class="brush:html">
&lt;div id="gr-gallery" class="gr-gallery"&gt;

	&lt;div class="gr-main"&gt;

		&lt;figure&gt;
			&lt;div&gt;&lt;img src="images/11.jpg" alt="img01" /&gt;&lt;/div&gt;
			&lt;figcaption&gt;
				&lt;h2&gt;&lt;span&gt;Penn. Station, Madison Square Garden and Empire State Building&lt;/span&gt;&lt;/h2&gt;
				&lt;div&gt;&lt;p&gt;New York City, 2009, by &lt;a href="http://www.flickr.com/photos/thomasclaveirole"&gt;Thomas Claveirole&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
			&lt;/figcaption&gt;
		&lt;/figure&gt;

		&lt;figure&gt;
			&lt;!-- --&gt;
		&lt;/figure&gt;

		&lt;!-- --&gt;
	&lt;/div&gt;
	
&lt;/div&gt;
</pre>
<p>We will first transform it into the following structure that will contain a &#8220;room&#8221; with a main &#8220;wall&#8221;:</p>
<pre class="brush:html">
&lt;div id="gr-gallery" class="gr-gallery"&gt;

	&lt;div class="gr-main" style="display: none;"&gt;
		&lt;!-- --&gt;
	&lt;/div&gt;

	&lt;div class="gr-room"&gt;
		&lt;div class="gr-wall-main"&gt;
			&lt;div class="gr-floor" style="width: 3382px;"&gt;&lt;/div&gt;
			&lt;figure&gt;&lt;/figure&gt;
			&lt;figure&gt;&lt;/figure&gt;
			&lt;!-- --&gt;
		&lt;/div&gt;
	&lt;/div&gt;

	&lt;nav&gt;
		&lt;span class="gr-prev"&gt;prev&lt;/span&gt;
		&lt;span class="gr-next"&gt;next&lt;/span&gt;
	&lt;/nav&gt;

	&lt;div class="gr-caption"&gt;
		&lt;span class="gr-caption-close"&gt;x&lt;/span&gt;
	&lt;/div&gt;
	
&lt;/div&gt;&lt;!-- /gr-gallery --&gt;
</pre>
<p>The main wall will get a width so that a certain amount of images fits inside. The default number of images per wall are the total number divided by four since we have four walls to spread them on. We can also set the number of items per wall by initializing the layout array, as see in the demos:</p>
<pre class="brush:js">
Gallery.init( {
	layout : [3,2,3,2]
} );
</pre>
<p>Now, when we reach the end of a wall and rotate to see the next one, we&#8217;ll add another wall dynamically and set the right transforms so that it&#8217;s in the right angle towards the main wall. </p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<p>Let&#8217;s take a look at some screenshots. The gallery starts by looking at the first image which will be centered in the viewport. With a very large screen, we will be able to see the neighboring images as well, depending on the wall size of course:</p>
<p><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_01.jpg" alt="3DGalleryRoom_01" width="580" height="525" class="alignnone size-full wp-image-13588" /></p>
<p>When clicking on the little description, a larger version will slide in from the bottom of the screen:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_02.jpg" alt="3DGalleryRoom_02" width="580" height="525" class="alignnone size-full wp-image-13589" /></p>
<p>When clicking on a navigation arrow (we click to go to the right) we will move to the next or previous picture. When the end of the wall is reached, we&#8217;ll give a turn:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_03.jpg" alt="3DGalleryRoom_03" width="580" height="525" class="alignnone size-full wp-image-13590" /></p>
<p>The next image is placed into another wall a positioned accordingly:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_04.jpg" alt="3DGalleryRoom_04" width="580" height="525" class="alignnone size-full wp-image-13591" /></p>
<p>When we turn fully, the walls will be reset and we&#8217;ll again have only the main wall:<br />
<img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2013/01/3DGalleryRoom_05.jpg" alt="3DGalleryRoom_05" width="580" height="524" class="alignnone size-full wp-image-13592" /></p>
<p>The biggest problem for these kind of extreme experiments is the different handling of 3D transforms in the browsers and of course the performance. When playing with extreme widths and perspective, there can be glitches in viewing because an element might be rotated &#8220;right into your face&#8221; :) The larger the element is in width, the higher the perspective value needs to be (at least for Firefox).</p>
<p>Sadly, the performance suffers when adding something like a box shadow, so we have stripped the demos down to their bare style and not added too much fanciness. It does look a bit ugly, but we simply wanted to show the 3D effect and the smoothness is more important for us in this experiment. </p>
<p><em>Anyway, we hope you enjoyed this little experiment and find it inspiring!</em></p>
<p><a class="demo" href="http://tympanus.net/Development/3DGalleryRoom/">View demo</a> <a class="download" href="http://tympanus.net/Development/3DGalleryRoom/3DGalleryRoom.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2013/01/15/3d-image-gallery-room/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Gamma Gallery: A Responsive Image Gallery Experiment</title>
		<link>http://tympanus.net/codrops/2012/11/06/gamma-gallery-a-responsive-image-gallery-experiment/</link>
		<comments>http://tympanus.net/codrops/2012/11/06/gamma-gallery-a-responsive-image-gallery-experiment/#comments</comments>
		<pubDate>Tue, 06 Nov 2012 17:19:13 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Playground]]></category>
		<category><![CDATA[fluid]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[image gallery]]></category>
		<category><![CDATA[masonry]]></category>
		<category><![CDATA[responsive]]></category>
		<category><![CDATA[slideshow]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=11836</guid>
		<description><![CDATA[Gamma Gallery is an experimental responsive image gallery that attempts to provide an adjustable responsive images approach taking its grid layout and the full slideshow view into account. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Development/GammaGallery/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2012/11/GammaGallery.jpg" alt="Gamma Gallery: A Responsive Image Gallery Experiment" title="Gamma Gallery: A Responsive Image Gallery Experiment" width="580" height="315" class="alignnone size-full wp-image-11847" /></a></p>
<p><a class="demo" href="http://tympanus.net/Development/GammaGallery/">View demo</a> <a class="download" href="http://tympanus.net/Development/GammaGallery/GammaGallery.zip">Download source</a></p>
<p>Creating a truly responsive image gallery can be a very tricky and difficult thing. There are so many factors to consider like the layout and the features, and so many choices to make when it comes to delivering a good viewing experience for every device. Gamma Gallery is an attempt to create an image gallery that uses a similar responsive images approach to the <a href="http://www.w3.org/community/respimg/wiki/Picture_Element_Proposal">proposed picture element</a>. Focused on providing suitable image sizes for both, the fluid grid thumbnails and the full image view, the selection of images also depends on container dimensions and not solely on the window size. In some cases it might even be reasonable to load larger thumbnails for a smaller device if we, for example want to show less columns in a grid. So, smaller windows don&#8217;t necessarily mean smaller thumbnails.</p>
<p>Gamma Gallery uses David David DeSandro&#8217;s <a href="http://masonry.desandro.com/">Masonry</a> in a fluid mode where column numbers are defined depending on the grid container sizes. </p>
<p>Inspired by <a href="https://github.com/scottjehl/picturefill">Picturefill</a> from Scott Jehl, the responsive images approach that mimics the picture element, we&#8217;ve come up with the following HTML structure for defining different image sizes:</p>
<pre class="brush:html">
&lt;div class="gamma-container gamma-loading" id="gamma-container"&gt;

	&lt;ul class="gamma-gallery"&gt;
		&lt;li&gt;
			&lt;div data-alt="img01" data-description="&lt;h3&gt;Assemblage&lt;/h3&gt;" data-max-width="1800" data-max-height="2400"&gt;
				&lt;div data-src="images/xxxlarge/1.jpg" data-min-width="1300"&gt;&lt;/div&gt;
				&lt;div data-src="images/xxlarge/1.jpg" data-min-width="1000"&gt;&lt;/div&gt;
				&lt;div data-src="images/xlarge/1.jpg" data-min-width="700"&gt;&lt;/div&gt;
				&lt;div data-src="images/large/1.jpg" data-min-width="300"&gt;&lt;/div&gt;
				&lt;div data-src="images/medium/1.jpg" data-min-width="200"&gt;&lt;/div&gt;
				&lt;div data-src="images/small/1.jpg" data-min-width="140"&gt;&lt;/div&gt;
				&lt;div data-src="images/xsmall/1.jpg"&gt;&lt;/div&gt;
				&lt;noscript&gt;
					&lt;img src="images/xsmall/1.jpg" alt="img01"/&gt;
				&lt;/noscript&gt;
			&lt;/div&gt;
		&lt;/li&gt;
		&lt;li&gt; &lt;!-- ... --&gt; &lt;/li&gt;
		&lt;!-- ... --&gt;
	&lt;/ul&gt;

	&lt;div class="gamma-overlay"&gt;&lt;/div&gt;

&lt;/div&gt;
</pre>
<p>Depending in which viewing mode we are, thumbnail grid view or full image view, the choice of the fitting image will depend on either the list item&#8217;s size or the whole viewport size. Let&#8217;s call that the &#8220;container size&#8221;. An &#8220;xsmall&#8221; image will be chosen if the container size is less than 140 pixels. A &#8220;small&#8221; image is picked if the container is wider than 140 pixels (data-min-width=&#8221;140&#8243;). A &#8220;medium&#8221; image is chosen if the container is wider than 200 pixels and so on. </p>
<p>Because we have a &#8220;fluid&#8221; image approach where we define the max-width of the image to be 100%, we will fit the image in its container if the image is bigger than the container. For that, our images will have the sizes that are defined in their consecutive (upper) step. For example, the &#8220;large&#8221; sized image will have a width of 700 pixels. This will ensure that the image shown is always equal or larger than its container, never smaller. In order to maintain the layout of the grid and never show a pixelated image (i.e. by stretching it), this approach seemed the most reasonable one. </p>
<p>The data-max-width and data-max-height attributes defines the largest image dimension which will restrict it to that size and not stretch it fully in the slideshow view. The slideshow view will take all the window size into account and allow the image to fill up all the possible space. The attributes ensure that the image doesn&#8217;t get resized beyond its largest dimension and become pixelated on huge screens. </p>
<p>Some things we are using in Gamma:</p>
<ul>
<li><a href="http://masonry.desandro.com/">jQuery Masonry</a> by David DeSandro for the grid layout</li>
<li><a href="http://www.w3.org/TR/page-visibility/">PageVisibility API</a> for pausing the slideshow when the page is not being displayed (e.g. when changing the tab). Also read <a href="http://www.html5rocks.com/en/tutorials/pagevisibility/intro/">Using the PageVisibility API</a> by Joe Marini on HTML5 Rocks</li>
<li><a href="https://github.com/websanova/js-url">url()</a>: a simple, lightweight url parser for JavaScript</li>
<li><a href="https://github.com/balupton/history.js">History.js</a> for HTML5 History/State APIs (pushState, replaceState, onPopState) support</li>
<li><a href="http://jquerypp.com/">jQuery++</a> for some useful DOM helpers and special events</li>
<li>And of course, <a href="http://modernizr.com/">Modernizr</a></li>
</ul>
<p><strong>There are many things to improve here, it is a very experimental implementation that tries to tackle the responsiveness of a special scenario, an image gallery.</strong></p>
<p>In the demo we don&#8217;t really take care of the vertical images which should of course have a set of reasonable dimensions that take the height of common screen sizes into account. </p>
<p>Here are the settings in the Gamma gallery script:</p>
<pre class="brush:js">
// default value for masonry column count
columns : 4,
// transition properties for the images in ms (transition to/from singleview)
speed : 300,
easing : 'ease',
// if set to true the overlay's opacity will animate (transition to/from singleview)
overlayAnimated : true,
// if true, the navigate next function is called when the image (singleview) is clicked
nextOnClickImage : true,
// circular navigation
circular : true,
// transition settings for the image in the single view.
// These include:
// - adjusting its position and size when the window is resized
// - fading out the image when navigating
svImageTransitionSpeedFade : 300,
svImageTransitionEasingFade : 'ease-in-out',
svImageTransitionSpeedResize : 300,
svImageTransitionEasingResize : 'ease-in-out',
svMarginsVH : {
	vertical : 140,
	horizontal : 120
},
// allow keybord and swipe navigation
keyboard : true,
swipe : true,
// slideshow interval (ms)
interval : 4000,
// if History API is not supported this value will turn false
historyapi : true
</pre>
<p>And here is an example of how we can initialize the gallery:</p>
<pre class="brush:js">
&lt;script type="text/javascript"&gt;
	
	$(function() {

		var GammaSettings = {
				// order is important!
				viewport : [ {
					width : 1200,
					columns : 5
				}, {
					width : 900,
					columns : 4
				}, {
					width : 500,
					columns : 3
				}, { 
					width : 320,
					columns : 2
				}, { 
					width : 0,
					columns : 2
				} ]
		};

		Gamma.init( GammaSettings );

	});

&lt;/script&gt;
</pre>
<p>The viewport width is the width that we will take into account for choosing the right sized image but also for defining how many columns in our grid layout we want to show. For example, between 320 and 500 pixel we would like to show 2 columns. </p>
<p>The images used in the demo are by <a href="http://www.idleformat.com/">Idleformat</a>.</p>
<p>The thumbnail hover style is inspired by the one seen on <a href="http://studionudge.com/">Nudge</a>.</p>
<p>Feedback, suggestions and comment are very welcome, there is lot&#8217;s things to improve and make better. Thank you!</p>
<div class="ct-github-link"><a href="https://github.com/codrops/GammaGallery">Find this project on Github</a></div>
<p><a class="demo" href="http://tympanus.net/Development/GammaGallery/">View demo</a> <a class="download" href="http://tympanus.net/Development/GammaGallery/GammaGallery.zip">Download source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2012/11/06/gamma-gallery-a-responsive-image-gallery-experiment/feed/</wfw:commentRss>
		<slash:comments>103</slash:comments>
		</item>
		<item>
		<title>Sweet Thumbnails Preview Gallery</title>
		<link>http://tympanus.net/codrops/2011/01/19/sweet-thumbnails-gallery/</link>
		<comments>http://tympanus.net/codrops/2011/01/19/sweet-thumbnails-gallery/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 17:12:57 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[image gallery]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[sliding]]></category>
		<category><![CDATA[thumbnails]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=3719</guid>
		<description><![CDATA[View demoDownload source In this tutorial we will create an image gallery with jQuery that shows a preview of each image as a little thumbnail. The idea is to hover over the slider dots and make the regarding thumbnail slide into the previewer. When clicking a slider dot, the full image will slide in from [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Tutorials/SweetThumbnails/" target="_blank"><img class="aligncenter size-full wp-image-3731" title="SweetThumbnailsPreviewGallery" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2011/01/SweetThumbnailsPreviewGallery.jpg" alt="" width="580" height="315" /></a></p>
<p><a class="demo" href="http://tympanus.net/Tutorials/SweetThumbnails/" target="_blank">View demo</a><a class="download" href="http://tympanus.net/Tutorials/SweetThumbnails/SweetThumbnails.zip">Download source</a></p>
<p>In this tutorial we will create an image gallery with jQuery that shows a preview of each image as a little thumbnail. The idea is to hover over the slider dots and make the regarding thumbnail slide into the previewer. When clicking a slider dot, the full image will slide in from the right or left side, depending on the currently viewed image.</p>
<p><strong>Update:</strong> If you are interested in integrating the thumbnails preview slider you might want to check out the new post on how to use only the preview part:<br />
<a href="http://tympanus.net/codrops/2011/01/27/thumbnails-preview-slider/">Thumbnails Preview Slider with jQuery</a></p>
<p>The beautiful images are by talented <strong>geishaboy500</strong> and can be found here on his <a href="http://www.flickr.com/photos/geishaboy500/" target="_blank">Flickr Photostream</a>.</p>
<p>So, let&#8217;s roll!</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<h3>The Markup</h3>
<p>The HTML structure is going to consist of a main container which will have the image wrapper for the big image, the navigation items and the dot list with the thumbnail preview:</p>
<pre class="brush:xml">&lt;div id="ps_container" class="ps_container"&gt;
	&lt;div class="ps_image_wrapper"&gt;
		&lt;!-- First initial image --&gt;
		&lt;img src="images/1.jpg" alt="" /&gt;
	&lt;/div&gt;
	&lt;!-- Navigation items --&gt;
	&lt;div class="ps_next"&gt;&lt;/div&gt;
	&lt;div class="ps_prev"&gt;&lt;/div&gt;
	&lt;!-- Dot list with thumbnail preview --&gt;
	&lt;ul class="ps_nav"&gt;
		&lt;li class="selected"&gt;
			&lt;a href="images/1.jpg" rel="images/thumbs/1.jpg"&gt;Image 1&lt;/a&gt;
		&lt;/li&gt;
		&lt;li&gt;
			&lt;a href="images/2.jpg" rel="images/thumbs/2.jpg"&gt;Image 2&lt;/a&gt;
		&lt;/li&gt;
		...
		&lt;li class="ps_preview"&gt;
			&lt;div class="ps_preview_wrapper"&gt;
				&lt;!-- Thumbnail comes here --&gt;
			&lt;/div&gt;
			&lt;!-- Little triangle --&gt;
			&lt;span&gt;&lt;/span&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;
</pre>
<p>The thumbnail preview element will be a list item in the dot list. It&#8217;s going to have a special class since we want to treat this element differently. Each dot list item will contain a link element which will hold the information on the thumbnail image and the big image. Using JavaScript, we will extract that path information from the attributes and create the image elements dynamically.</p>
<p>Let&#8217;s take a look at the style.</p>
<h3>The CSS</h3>
<p>First, we will style the main container. Since our images have a maximum width of 680 pixel and a maximum height of 450 pixel, we will define the following values for the container (leaving some space for the dot list):</p>
<pre class="brush:css">.ps_container{
	display:none;
	width:680px;
	height:500px;
	margin:20px auto 0px auto;
	position:relative;
}
</pre>
<p>Now we will style the wrapper for the full images. Here we really set the exact maximum dimensions and say that the overflow is hidden. We do that because we want to be able to put two images inside of this wrapper but cut off the overflow. In our JS function we will animate the images so that the current one gets revealed.<br />
We will center the wrapper by setting the left and right margins to &#8220;auto&#8221;:</p>
<pre class="brush:css">.ps_image_wrapper{
	width:680px;
	height:450px;
	overflow:hidden;
	position:relative;
	margin:0 auto;
	-moz-box-shadow:0px 0px 5px #999;
	-webkit-box-shadow:0px 0px 5px #999;
	box-shadow:0px 0px 5px #999;
}
</pre>
<p>The image(s) inside of the wrapper should be of position absolute since we want to animate the left value to slide in the current image and slide out the previous one:</p>
<pre class="brush:css">.ps_image_wrapper img{
	position:absolute;
	left:0px;
	top:0px;
}
</pre>
<p>The navigation elements will have the following style:</p>
<pre class="brush:css">.ps_prev,
.ps_next{
	width:30px;
	height:59px;
	position:absolute;
	top:50%;
	margin-top:-40px;
	cursor:pointer;
	opacity:0.5;
}
.ps_prev{
	background:transparent url(../images/prev.png) no-repeat top center;
	left:-50px;
}
.ps_next{
	background:transparent url(../images/next.png) no-repeat top center;
	right:-50px;
}
.ps_prev:hover,
.ps_next:hover{
	opacity:0.9;
}
</pre>
<p>The dot list with the class &#8220;ps_nav&#8221; will be placed under the full image and centered by auto margins:</p>
<pre class="brush:css">ul.ps_nav{
	list-style:none;
	margin:0;
	padding:0;
	width:170px;
	margin:20px auto;
	position:relative;
}
</pre>
<p>The dot list elements will float:</p>
<pre class="brush:css">ul.ps_nav li{
	float:left;
}
</pre>
<p>And the inner link elements will get the dot background image, which is a sprites image:</p>
<pre class="brush:css">ul.ps_nav li a{
	display:block;
	text-indent:-9000px;
	width:11px;
	height:11px;
	outline:none;
	padding:0px 3px;
	background:transparent url(../images/dot.png) no-repeat top center;
}
</pre>
<p>On hover we will change the background position to show the other half:</p>
<pre class="brush:css">ul.ps_nav li a:hover,ul.ps_nav li.selected a{
	background-position:50% -11px;
}
</pre>
<p>Our special list element, the one that will have the thumbnail preview, will be of absolute positioning. The top has a negative value, since we want to pull this element up, beyond the list. The left value will be dynamically calculated. -34.5 pixel is the left value for the preview element when we want to show it over the first dot:</p>
<pre class="brush:css">ul.ps_nav li.ps_preview{
	display:none;
	width:85px;
	height:91px;
	top:-95px;
	left:-34.5px; /*This we will calculate dynamically*/
	position:absolute;
}
</pre>
<p>The span will be the little triangle:</p>
<pre class="brush:css">ul.ps_nav li.ps_preview span{
	background:transparent url(../images/triangle.png) no-repeat top center;
	width:15px;
	height:6px;
	position:absolute;
	top:85px;
	left:35px;
}
</pre>
<p>The preview wrapper will function the same way like the full image wrapper. We will hide the overflow:</p>
<pre class="brush:css">.ps_preview_wrapper{
	width:75px;
	height:75px;
	border:5px solid #fff;
	overflow:hidden;
	position:relative;
	-moz-box-shadow:0px 0px 5px #999;
	-webkit-box-shadow:0px 0px 5px #999;
	box-shadow:0px 0px 5px #999;
}
</pre>
<p>And ultimately, we want the thumbnails to be of absolute positioning since we want to animate the left value for the sliding effect:</p>
<pre class="brush:css">.ps_preview_wrapper img{
	position:absolute;
	top:0px;
	left:0px;
}
</pre>
<p>And that&#8217;s all the style. Let add the jQuery spice!</p>
<h3>The JavaScript</h3>
<p>The idea of this gallery is to show little thumbnails when hovering over a dot that represents and image.</p>
<p>When moving the cursor over the dots, we want to create a sliding animation that moves the next currently hovered thumbnail image into place. This will create a great effect, giving the illusion that we have an invisible bar of thumbnail images above the dots and our preview element makes them visible.</p>
<p>We also want the clicked image to show up by &#8220;pushing&#8221; the current one away, either from the left or from the right side.</p>
<p>Both effects we will achieve by placing the images or thumbs next to each other and animating their left value accordingly.</p>
<p>So, let&#8217;s begin by caching some elements:</p>
<pre class="brush:js">var $ps_container		= $('#ps_container'),
	$ps_image_wrapper 	= $ps_container.find('.ps_image_wrapper'),
	$ps_next			= $ps_container.find('.ps_next'),
	$ps_prev			= $ps_container.find('.ps_prev'),
	$ps_nav				= $ps_container.find('.ps_nav'),
	$tooltip			= $ps_container.find('.ps_preview'),
	$ps_preview_wrapper = $tooltip.find('.ps_preview_wrapper'),
	$links				= $ps_nav.children('li').not($tooltip),
	total_images		= $links.length,
	currentHovered		= -1,
	current				= 0,
	$loader				= $('#loader');
</pre>
<p>(The loader element was not mentioned in the HTML structure since we placed it outside of the container. We want to show a loading element until all the images are loaded. In the download file you will be able to see the preload function for the images.)</p>
<p>Now we need to check if the browser is a real one or, for whatever insane reason, a crappy one like, let&#8217;s say, IE:</p>
<pre class="brush:js">var ie 				= false;
if ($.browser.msie) {
	ie = true; // oh no sweet Jesus
}
if(!ie) // there is a God
	$tooltip.css({
		opacity	: 0
	}).show();
</pre>
<p>Basically, we want to give the preview element or tooltip the opacity 0 and animate it to 1 when we hover over it. Since in IE it does not help to simply add an opacity filter (elements inside are still shown) we want to use the show/hide instead of animating the opacity. So, we add display:none to the style of the class but take it out if we don&#8217;t use IE.</p>
<p>After preloading the images, we will show the container:</p>
<pre class="brush:js">/*first preload images (thumbs and large images)*/
var loaded	= 0;
$links.each(function(i){
	var $link 	= $(this);
	$link.find('a').preload({
		onComplete	: function(){
			++loaded;
			if(loaded == total_images){
				//all images preloaded,
				//show ps_container and initialize events
				$loader.hide();
				$ps_container.show();
				//when mouse enters the the dots,
				//show the tooltip,
				//when mouse leaves hide the tooltip,
				//clicking on one will display the respective image
				$links.bind('mouseenter',showTooltip)
					  .bind('mouseleave',hideTooltip)
					  .bind('click',showImage);
				//navigate through the images
				$ps_next.bind('click',nextImage);
				$ps_prev.bind('click',prevImage);
			}
		}
	});
});
</pre>
<p>The function <strong>showTooltip()</strong> will show the thumbnails preview and animate it to the right place. It will also slide the thumbnails inside, either to the right or to the left, depending where we are &#8220;coming from&#8221;:</p>
<pre class="brush:js">function showTooltip(){
	var $link			= $(this),
		idx				= $link.index(),
		linkOuterWidth	= $link.outerWidth(),
		//this holds the left value for the next position
		//of the tooltip
		left			= parseFloat(idx * linkOuterWidth) - $tooltip.width()/2 + linkOuterWidth/2,
		//the thumb image source
		$thumb			= $link.find('a').attr('rel'),
		imageLeft;

	//if we are not hovering the current one
	if(currentHovered != idx){
		//check if we will animate left-&gt;right or right-&gt;left
		if(currentHovered != -1){
			if(currentHovered &lt; idx){
				imageLeft	= 75;
			}
			else{
				imageLeft	= -75;
			}
		}
		currentHovered = idx;

		//the next thumb image to be shown in the tooltip
		var $newImage = $('<img alt="" />').css('left','0px')
								   .attr('src',$thumb);

		//if theres more than 1 image
		//(if we would move the mouse too fast it would probably happen)
		//then remove the oldest one (:last)
		if($ps_preview_wrapper.children().length &gt; 1)
			$ps_preview_wrapper.children(':last').remove();

		//prepend the new image
		$ps_preview_wrapper.prepend($newImage);

		var $tooltip_imgs		= $ps_preview_wrapper.children(),
			tooltip_imgs_count	= $tooltip_imgs.length;

		//if theres 2 images on the tooltip
		//animate the current one out, and the new one in
		if(tooltip_imgs_count &gt; 1){
			$tooltip_imgs.eq(tooltip_imgs_count-1)
						 .stop()
						 .animate({
							left:-imageLeft+'px'
						  },150,function(){
								//remove the old one
								$(this).remove();
						  });
			$tooltip_imgs.eq(0)
						 .css('left',imageLeft + 'px')
						 .stop()
						 .animate({
							left:'0px'
						  },150);
		}
	}
	//if we are not using a "browser", we just show the tooltip,
	//otherwise we fade it in
	//
	if(ie)
		$tooltip.css('left',left + 'px').show();
	else
	$tooltip.stop()
			.animate({
				left		: left + 'px',
				opacity		: 1
			},150);
}
</pre>
<p style="text-align: center;"><img class="nofancy size-full wp-image-3729  aligncenter" title="thumbnails" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2011/01/thumbnails.jpg" alt="" width="478" height="236" /></p>
<p>The function <strong>hideTooltip()</strong> simply fades out the thumbnails preview (or hides it if IE):</p>
<pre class="brush:js">function hideTooltip(){
	//hide / fade out the tooltip
	if(ie)
		$tooltip.hide();
	else
	$tooltip.stop()
			.animate({
				opacity		: 0
			},150);
}
</pre>
<p>The following function will show an image in full size and animate the wrapper around to the right size. The new image will &#8220;slide into place&#8221;:</p>
<pre class="brush:js">function showImage(e){
	var $link				= $(this),
		idx					= $link.index(),
		$image				= $link.find('a').attr('href'),
		$currentImage 		= $ps_image_wrapper.find('img'),
		currentImageWidth	= $currentImage.width();

	//if we click the current one return
	if(current == idx) return false;

	//add class selected to the current page / dot
	$links.eq(current).removeClass('selected');
	$link.addClass('selected');

	//the new image element
	var $newImage = $('<img alt="" />').css('left',currentImageWidth + 'px')
							   .attr('src',$image);

	//if the wrapper has more than one image, remove oldest
	if($ps_image_wrapper.children().length &gt; 1)
		$ps_image_wrapper.children(':last').remove();

	//prepend the new image
	$ps_image_wrapper.prepend($newImage);

	//the new image width
	//this will be the new width of the ps_image_wrapper
	var newImageWidth	= $newImage.width();

	//check animation direction
	if(current &gt; idx){
		$newImage.css('left',-newImageWidth + 'px');
		currentImageWidth = -newImageWidth;
	}
	current = idx;
	//animate the new width of the ps_image_wrapper
	//(same like new image width)
	$ps_image_wrapper.stop().animate({
		width	: newImageWidth + 'px'
	},350);
	//animate the new image in
	$newImage.stop().animate({
		left	: '0px'
	},350);
	//animate the old image out
	$currentImage.stop().animate({
		left	: -currentImageWidth + 'px'
	},350);

	e.preventDefault();
}
</pre>
<p>The navigation functions will simply trigger a click event on the dots (which we already took care of in the beginning):</p>
<pre class="brush:js">function nextImage(){
	if(current &lt; total_images){ 		$links.eq(current+1).trigger('click'); 	} } function prevImage(){ 	if(current &gt; 0){
		$links.eq(current-1).trigger('click');
	}
}
</pre>
<p>And that&#8217;s all! We hope you enjoyed the sweet thumbnails tutorial and find it useful!</p>
<p><a class="demo" href="http://tympanus.net/Tutorials/SweetThumbnails/" target="_blank">View demo</a><a class="download" href="http://tympanus.net/Tutorials/SweetThumbnails/SweetThumbnails.zip">Download source</a></p>
<div class="googlead"><!-- wp_ad_camp_1 --></div>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2011/01/19/sweet-thumbnails-gallery/feed/</wfw:commentRss>
		<slash:comments>128</slash:comments>
		</item>
		<item>
		<title>Bubbleriffic Image Gallery with jQuery</title>
		<link>http://tympanus.net/codrops/2010/12/10/bubbleriffic-image-gallery/</link>
		<comments>http://tympanus.net/codrops/2010/12/10/bubbleriffic-image-gallery/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 23:11:43 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[bubble]]></category>
		<category><![CDATA[circle]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[image gallery]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=3154</guid>
		<description><![CDATA[View demoDownload source In this tutorial we will create a bubbly image gallery that shows your images in a unique way. The idea is to show the thumbnails of albums in a rounded fashion allowing the user to scroll them automatically by moving the mouse. Clicking on a thumbnail will zoom in a big circle [...]]]></description>
				<content:encoded><![CDATA[<p><a target="_blank" href="http://tympanus.net/Tutorials/BubblerifficImageGallery/"><img src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2010/12/bubbleriffic.jpg" alt="" title="bubbleriffic" width="580" height="315" class="aligncenter size-full wp-image-3169" /></a><br />
<a class="demo" href="http://tympanus.net/Tutorials/BubblerifficImageGallery/" target="_blank">View demo</a><a class="download" href="http://tympanus.net/Tutorials/BubblerifficImageGallery/BubblerifficImageGallery.zip">Download source</a></p>
<p>In this tutorial we will create a bubbly image gallery that shows your images in a unique way. The idea is to show the thumbnails of albums in a rounded fashion allowing the user to scroll them automatically by moving the mouse. Clicking on a thumbnail will zoom in a big circle and the full image which will be automatically resized to fit into the screen. Navigating through the images will slide the current image to the side and make the new one appear in a zoom like fashion.</p>
<p>We will be using Manos Malihu&#8217;s brilliant thumbnail scroller which you can find here: <a href="http://manos.malihu.gr/jquery-thumbnail-scroller" target="_blank">Manos Malihu&#8217;s thumbnail scroller</a></p>
<p>The beautiful images are by talented geishaboy500 and you can find more amazing photographs on his flickr photostream:<br />
<a target="_blank" href="http://www.flickr.com/photos/geishaboy500/">Photos by geishaboy500</a></p>
<p>Ok, let&#8217;s get started!</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<h3>The Markup</h3>
<p>Let&#8217;s start by creating our HTML structure. We will have quite a few elements, so we will begin with the top menu that appears when we view the full image:</p>
<pre class="brush:xml">
&lt;div class="top_menu" id="top_menu"&gt;
	&lt;span id="description" class="description"&gt;&lt;/span&gt;
	&lt;a id="back" href="#" class="back"&gt;&lt;span&gt;&lt;/span&gt;back&lt;/a&gt;
	&lt;div class="info"&gt;
		&lt;span class="album_info"&gt;Album 1&lt;/span&gt;
		&lt;span class="image_info"&gt; / Shot 1&lt;/span&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>We need an option to go back to the thumbnails view, a description area and an information area that shows us which image we are currently viewing. So, this element is just going to show up when we click on a thumbnail. The empty span will be used to add a little back arrow.</p>
<p>We also need a loader element:</p>
<pre class="brush:xml">
&lt;div id="loader" class="loader"&gt;&lt;/div&gt;
</pre>
<p>Now, let&#8217;s take a look at the heading element where we will put our main h1 element for the gallery title:</p>
<pre class="brush:xml">
&lt;div class="header" id="header" style="top:-90px;"&gt;&lt;!--top 30 px to show--&gt;
	&lt;h1&gt;Bubbleriffic&lt;span&gt;jQuery Image Gallery&lt;/span&gt;&lt;/h1&gt;
&lt;/div&gt;
</pre>
<p>We want to slide this element in from the top when we load the page, so we initially set the top value to -90 pixels. In the JavaScript we will then animate it to 30 pixels. You can also add this style to the stylesheet instead of having an inline style.</p>
<p>The next element will be the thumbnails wrapper that will have all the thumbnail albums. Since we will use Manos&#8217; thumbnail scroller, we will base our markup on that structure. There will be three scrolling containers for the three albums which will have the class &#8220;tshf_container&#8221;:</p>
<pre class="brush:xml">
&lt;div id="thumbnails_wrapper" class="thumbnails_wrapper" style="top:-255px;"&gt;
	&lt;!-- top:110px to show--&gt;
	
	&lt;div id="tshf_container1"  class="tshf_container"&gt;
		&lt;div class="thumbScroller"&gt;
			&lt;div class="container"&gt;
			
				&lt;div class="content"&gt;
					&lt;div&gt;
						&lt;a href="#"&gt;
							&lt;img src="images/albums/album1/thumbs/1.jpg" alt="Description" class="thumb" /&gt;		
						&lt;/a&gt;
						&lt;span&gt;&lt;/span&gt;
					&lt;/div&gt;
				&lt;/div&gt;
				
				&lt;div class="content"&gt;
					...
				&lt;/div&gt;
				
			&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	
	&lt;div id="tshf_container2"  class="tshf_container"&gt;
		...
	&lt;/div&gt;

	&lt;div id="tshf_container3"  class="tshf_container"&gt;
		...
	&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>The empty span inside of the div that holds the image will be used for overlaying an image with a hole in it, making the thumbnails appear like little bubbles.</p>
<p>Now we will add the yellow bubble that will be used to create the bubble like tunnel effect when we want to view a full image:</p>
<pre class="brush:xml">
&lt;div class="bubble"&gt;
	&lt;img id="bubble" src="images/bubble.png" alt=""/&gt;
&lt;/div&gt;
</pre>
<p>The preview container for the full image view with the navigation will have the following structure:</p>
<pre class="brush:xml">
&lt;div id="preview" class="preview"&gt;
	&lt;a id="prev_image" href="#" class="prev_image"&gt;&lt;/a&gt;
	&lt;a id="next_image" href="#" class="next_image"&gt;&lt;/a&gt;
&lt;/div&gt;
</pre>
<p>The footer can be used to add some information:</p>
<pre class="brush:xml">
&lt;div class="footer"&gt;
	&lt;!-- Add something here --&gt;
&lt;/div&gt;
</pre>
<p>Let&#8217;s take a look at the style!</p>
<h3>The CSS</h3>
<p>First, we will reset the style and define some general properties for links, lists and the body:</p>
<pre class="brush:css">
*{
	margin:0;
	padding:0;
}
a{
	text-decoration:none;
	outline:none;
}
ul{
	list-style:none;
}
body{
	background:#222 url(../bg.jpg) repeat top left;
	font-family:"Trebuchet MS", "Myriad Pro", Helvetica, sans-serif;
	font-size:13px;
	color: #fff;
	text-transform:uppercase;
	text-shadow:0px 0px 1px #fff;
	letter-spacing:1px;
	overflow:hidden;
}
</pre>
<p>The top menu that appears when we view a full image will have the following style:</p>
<pre class="brush:css">
.top_menu{
	height:30px;
	line-height:30px;
	position:absolute;
	top:-30px;
	left:0;
	width:100%;
	overflow:hidden;
	background:#010101;
	border-bottom:1px solid #000;
	z-index:100;
	-moz-box-shadow:0px 0px 4px #010101;
	-webkit-box-shadow:0px 0px 4px #010101;
	box-shadow:0px 0px 4px #010101;
}
</pre>
<p>(If you know that your text will only occupy one line in a specific element, then you can set that element&#8217;s line-height to its height in order to center the containing text vertically.)<br />
We set the top to -30 pixels in order to hide the element. </p>
<p>The back link will have the following style:</p>
<pre class="brush:css">
.top_menu .back{
	position:absolute;
	top:0px;
	left:10px;
	height:30px;
	line-height:30px;
	cursor:pointer;
	color:#aaa;
}
</pre>
<p>We will add a little arrow icon for the back link that actually has the same background image like the navigation element. We use double of the width though, so that we can repeat the image twice:</p>
<pre class="brush:css">
.top_menu .back span{
	width:14px;
	height:30px;
	display:block;
	float:left;
	background:#000 url(../images/prev.png) repeat-x center left;
	margin-right:5px;
	opacity:0.5;
}
.top_menu .back:hover{
	color:#fff;
}
.top_menu .back:hover span{
	opacity:0.9;
}
</pre>
<p>The description will appear centered:</p>
<pre class="brush:css">
.top_menu span.description{
	font-style:italic;
	position:absolute;
	width:100%;
	text-align:center;
	top:0px;
	left:0px;
	height:30px;
	line-height:30px;
}
</pre>
<p>And the info will float right:</p>
<pre class="brush:css">
.top_menu .info{
	float:right;
	margin-right:10px;
}
</pre>
<p>Let&#8217;s style the main header now. We will position it absolutely since we want it to animate from the top and we will give it a yellow background color and some nice box shadow:</p>
<pre class="brush:css">
.header{
	height:80px;
	position:absolute;
	top:30px;
	left:0px;
	width:100%;
	overflow:hidden;
	z-index:90;
	background-color:#ffd800;
	-moz-box-shadow:0px 0px 10px #010101;
	-webkit-box-shadow:0px 0px 10px #010101;
	box-shadow:0px 0px 10px #010101;
}
h1{
	font-size:60px;
	padding-left:20px;
	color:#010101;
	line-height:80px;
	text-shadow:1px 1px 1px #000;
}
h1 span{
	font-size:16px;
	float:right;
	margin-right:20px;
}
</pre>
<p>Before we style the thumbnails wrapper, let&#8217;s first take a look at all the other elements&#8217; style. </p>
<p>The full image will be positioned absolutely, but we will set its final position in the JavaScript:</p>
<pre class="brush:css">
.preview img{
	position:absolute;
	left:0;
	top:0;
	-moz-box-shadow:1px 1px 5px #111;
	-webkit-box-shadow:1px 1px 5px #111;
	box-shadow:21px 1px 5px #111;
	-webkit-box-reflect:
		below 5px
		-webkit-gradient(
		linear,
		left top,
		left bottom,
		from(transparent),
		color-stop(0.8, transparent),
		to(rgb(255, 216, 0))
		);
}
</pre>
<p>We will add some nice reflection for webkit browsers and some decent box shadow.</p>
<p>The footer will have almost the same style like the top menu, except the positioning and some other details, like the border:</p>
<pre class="brush:css">

.footer{
	z-index:100;
	height:30px;
	line-height:30px;
	text-align:center;
	font-size:10px;
	background:#010101;
	border-top:1px solid #000;
	position:absolute;
	bottom:0px;
	left:0px;
	width:100%;
	-moz-box-shadow:0px 0px 4px #010101;
	-webkit-box-shadow:0px 0px 4px #010101;
	box-shadow:0px 0px 4px #010101;
}
.footer a{
	color:#999;
	text-decoration:none;
	margin:40px;
}
</pre>
<p>The loading element will be placed in the middle of the page and we will make it round by setting the border radius to half of its width/height:</p>
<pre class="brush:css">
.loader{
	display:none;
	width:200px;
	height:200px;
	background: #000 url(../images/ajax-loader.gif) no-repeat center center;
	position:fixed;
	top:50%;
	left:50%;
	margin:-100px 0px 0px -100px;
	opacity: 0.7;
	z-index:9999;
	-moz-border-radius:100px;
	-webkit-border-radius:100px;
	border-radius:100px;
}
</pre>
<p>The navigation elements will have the following common style:</p>
<pre class="brush:css">
a.next_image,
a.prev_image{
	width:50px;
	height:50px;
	position:fixed;
	top:50%;
	margin-top:-25px;
	cursor:pointer;
	opacity:0.7;
	z-index:999999;
	-moz-box-shadow:0px 0px 3px #000;
	-webkit-box-shadow:0px 0px 3px #000;
	box-shadow:0px 0px 3px #000;
	-moz-border-radius:25px;
	-webkit-border-radius:25px;
	border-radius:25px;
}
a.next_image:hover,
a.prev_image:hover
{
	opacity:0.9;
}
</pre>
<p>And the separate styles will be</p>
<pre class="brush:css">
a.next_image{
	background:#000 url(../images/next.png) no-repeat center center;
	right:-50px;
}
a.prev_image{
	background:#000 url(../images/prev.png) no-repeat center center;
	left:-50px;
}
</pre>
<p>Initially, they will both be hidden, that&#8217;s why we will set their left/right positioning to the negative value of their widths.</p>
<p>Now, we will style the thumbnails wrapper:</p>
<pre class="brush:css">
.thumbnails_wrapper{
	position:absolute;
	top:-255px;
	left:0px;
	width:100%;
	-moz-box-shadow:0px 3px 5px #000;
	-webkit-box-shadow:0px 3px 5px #000;
	box-shadow:0px 3px 5px #000;
}
</pre>
<p>The bubble image will be positioned in the center of the page and have a width and height of 0. We will animate it then in the JavaScript:</p>
<pre class="brush:css">
.bubble img{
	position:fixed;
	top:50%;
	left:50%;
	width:0px;
	height:0px;
}
</pre>
<p>Now, we will adapt the style of Manos&#8217; thumbnail scroller:</p>
<pre class="brush:css">
.tshf_container{
	height:85px;
	position:relative;
	width:100%;
	background:#ffd800;
}
.tshf_container .thumbScroller{
	position:relative;
	width:100%;
	overflow:hidden;
}
.tshf_container .thumbScroller,
.tshf_container .thumbScroller .container,
.tshf_container .thumbScroller .content{
	height:85px;
}
.tshf_container .thumbScroller .container{
	position:relative;
	left:0;
}
.tshf_container .thumbScroller .content{
	float:left;
}
.tshf_container .thumbScroller .content div{
	height:100%;
	position:relative;
}
.tshf_container .thumbScroller img{
	border:none;
}
.tshf_container .thumbScroller .content div a{
	display:block;
	height:85px;
	width:85px;
}
.tshf_container .thumbScroller .content div a img{
	width:85px;
}
.tshf_container .thumbScroller .content div a:hover{
	border-color:#fff;
}
</pre>
<p>We will use the extra span to add our bubble overlay:</p>
<pre class="brush:css">
.tshf_container .thumbScroller .content span{
	cursor:pointer;
	position:absolute;
	width:85px;
	height:85px;
	top:0px;
	left:0px;
	background:transparent url(../images/thumb_overlay.png) no-repeat top left;
}
.tshf_container .thumbScroller .content div:hover span{
	background:transparent url(../images/thumb_overlay_hover.png) no-repeat top left;
}
</pre>
<p>And that&#8217;s all the style. Now, let&#8217;s add the magic!</p>
<h3>The JavaScript</h3>
<p>First, we will include the following scripts:</p>
<pre class="brush:xml">
&lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="js/jquery.easing.1.3.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="js/jquery.thumbnailScroller.js"&gt;&lt;/script&gt;
</pre>
<p>We will start by caching some important elements and defining some indexes:</p>
<pre class="brush:js">
var $thumbnails_wrapper 	= $('#thumbnails_wrapper'),
	$thumbs					= $thumbnails_wrapper.find('.tshf_container').find('.content'),
	$top_menu				= $('#top_menu'),
	$header					= $('#header'),
	$bubble                 = $('#bubble'),
	$loader					= $('#loader'),
	$preview				= $('#preview'),
	$thumb_images			= $thumbnails_wrapper.find('img'),
	total_thumbs			= $thumb_images.length,
	$next_img				= $('#next_image'),
	$prev_img				= $('#prev_image'),
	$back					= $('#back'),
	$description			= $('#description'),
	//current album and current photo
	//(indexes of the tshf_container and content elements)					
	currentAlbum			= -1,
	currentPhoto			= -1;
</pre>
<p>Then, we will show the loading element (until all thumbnails are loaded) and call the function that opens the albums:</p>
<pre class="brush:js">
$loader.show();

//shows the main menu and thumbs menu
openPhotoAlbums();
</pre>
<p>And this is how that function looks like:</p>
<pre class="brush:js">
function openPhotoAlbums(){
	//preload all the thumb images
	var cnt_loaded = 0;
	$thumb_images.each(function(){
		var $thumb 		= $(this);
		var image_src 	= $thumb.attr('src');
		$('&lt;img/&gt;').load(function(){
			++cnt_loaded;
			if(cnt_loaded == total_thumbs){
				$loader.hide();
				createThumbnailScroller();
				//show the main menu and thumbs menu
				$header.stop()
					   .animate({'top':'30px'},700,'easeOutBack');
				$thumbnails_wrapper.stop()
								   .animate({'top':'110px'},700,'easeOutBack');
			}
		}).attr('src',image_src);
	});
}
</pre>
<p>The function &#8220;createThumbnailScroller()&#8221; will make the thumbnails be scrollable after Manos&#8217; script, but we will get to that later.</p>
<p>Next, we will define what happens when we click on a thumbnail. </p>
<pre class="brush:js">
$thumbs.bind('click',function(e){
	//show loading image
	$loader.show();
	var $thumb	= $(this),
		//source of the corresponding large image
		img_src = $thumb.find('img.thumb')
						.attr('src')
						.replace('/thumbs','');
	
	//track the current album / photo
	currentPhoto= $thumb.index(),
	currentAlbum= $thumb.closest('.tshf_container')
						.index();
	//displays the current album and current photo
	updateInfo(currentAlbum,currentPhoto);
	//preload the large image
	$('&lt;img/&gt;').load(function(){
		var $this = $(this);
		//record the size that the large image 
		//should have when it is shown
		saveFinalPositions($this);
		//margin_circle is the diameter for the 
		//bubble image
		var w_w				= $(window).width(),
			w_h				= $(window).height(),
			margin_circle	= w_w + w_w/3;
		if(w_h&gt;w_w)
			margin_circle	= w_h + w_h/3;
		
		//the image will be positioned on the center,
		//with width and height of 0px
		$this.css({
			'width'		: '0px',
			'height'	: '0px',
			'marginTop'	: w_h/2 +'px',
			'marginLeft': w_w/2 +'px'
		});
		$preview.append($this);
		
		//hide the header
		$header.stop().animate({'top':'-90px'},400, function(){
			$loader.hide();
			//show the top menu with the back button,
			//and current album/picture info
			$top_menu.stop()
					 .animate({'top':'0px'},400,'easeOutBack');
			//animate the bubble image
			$bubble.stop().animate({
				'width'		:	margin_circle + 'px',
				'height'	:	margin_circle + 'px',
				'marginTop'	:	-margin_circle/2+'px',
				'marginLeft':	-margin_circle/2+'px'
			},700,function(){
				//solve resize problem
				$('BODY').css('background','#FFD800');
			});
			//after 200ms animate the large image
			//and show the navigation buttons
			setTimeout(function(){
				var final_w	= $this.data('width'),
					final_h	= $this.data('height');
				$this.stop().animate({
						'width'		: final_w + 'px',
						'height'	: final_h + 'px',
						'marginTop'	: w_h/2 - final_h/2 + 'px',
						'marginLeft': w_w/2 - final_w/2 + 'px'
				},700,showNav);
				//show the description
				$description.html($thumb.find('img.thumb').attr('alt'));
			},200);
			
		});
		//hide the thumbs
		$thumbnails_wrapper.stop()
						   .animate({
							   'top' : w_h+'px'
						   },400,function(){
								//solve resize problem
								$(this).hide();
						   });
		
	}).attr('src',img_src);
});
</pre>
<p>When we click on the &#8220;next&#8221; element of the navigation, we want the following to happen:</p>
<pre class="brush:js">
$next_img.bind('click',function(){
	//increment the currentPhoto
	++currentPhoto;
	//current album:
	var $album		= $thumbnails_wrapper.find('.tshf_container')
										 .eq(currentAlbum),
		//the next element / thumb to show
		$next		= $album.find('.content').eq(currentPhoto),
		$current 	= $preview.find('img');
	if($next.length == 0 || $current.is(':animated')){
		--currentPhoto;
		return false;
	}
	else{
		$loader.show();
		updateInfo(currentAlbum,currentPhoto);
		//preload the large image
		var img_src = $next.find('img.thumb')
						   .attr('src')
						   .replace('/thumbs',''),
			w_w		= $(window).width(),
			w_h		= $(window).height();				   
	
		$('&lt;img/&gt;').load(function(){
			var $this = $(this);
			//record the size that the large image 
			//should have when it is shown
			saveFinalPositions($this);
			$loader.hide();
			$current.stop()
					.animate({'marginLeft':'-'+($current.width()+20)+'px'},500,function(){
						//the current image gets removed
						$(this).remove();	
					});
			//the new image will be positioned on the center,
			//with width and height of 0px
			$this.css({
				'width'		: '0px',
				'height'	: '0px',
				'marginTop'	: w_h/2 +'px',
				'marginLeft': w_w/2 +'px'
			});
			$preview.prepend($this);
			var final_w	= $this.data('width'),
				final_h	= $this.data('height');
			$this.stop().animate({
					'width'		: final_w + 'px',
					'height'	: final_h + 'px',
					'marginTop'	: w_h/2 - final_h/2 + 'px',
					'marginLeft': w_w/2 - final_w/2 + 'px'
			},700);
			//show the description
			$description.html($next.find('img.thumb').attr('alt'));
		}).attr('src',img_src);	
	}
});
</pre>
<p>And now we define what happens when we click to view the previous image:</p>
<pre class="brush:js">
$prev_img.bind('click',function(){
	--currentPhoto;
	//current album:
	var $album		= $thumbnails_wrapper.find('.tshf_container')
										 .eq(currentAlbum),
		$prev		= $album.find('.content').eq(currentPhoto),
		$current 	= $preview.find('img');
	if($prev.length == 0 || $current.is(':animated') || currentPhoto &lt; 0){
		++currentPhoto;
		return false;
	}
	else{
		$loader.show();
		updateInfo(currentAlbum,currentPhoto);
		//preload the large image
		var img_src = $prev.find('img.thumb')
						   .attr('src')
						   .replace('/thumbs',''),
			w_w				= $(window).width(),
			w_h				= $(window).height();				   
	
		$('&lt;img/&gt;').load(function(){
			var $this = $(this);
			//record the size that the large image 
			//should have when it is shown
			saveFinalPositions($this);
			
			$loader.hide();
			$current.stop()
					.animate({'marginLeft':(w_w+20)+'px'},500,function(){
						//the current image gets removed
						$(this).remove();
					});
			//the new image will be positioned on the center,
			//with width and height of 0px
			$this.css({
				'width'		: '0px',
				'height'	: '0px',
				'marginTop'	: w_h/2 +'px',
				'marginLeft': w_w/2 +'px'
			});
			$preview.append($this);
			var final_w	= $this.data('width'),
				final_h	= $this.data('height');
			$this.stop().animate({
					'width'		: final_w + 'px',
					'height'	: final_h + 'px',
					'marginTop'	: w_h/2 - final_h/2 + 'px',
					'marginLeft': w_w/2 - final_w/2 + 'px'
			},700);
			//show the description
			$description.html($prev.find('img.thumb').attr('alt'));							
		}).attr('src',img_src);	
	}
});
</pre>
<p>When we resize the window, we need to recalculate the position and size of the image:</p>
<pre class="brush:js">
$(window).resize(function(){
	var $current = $preview.find('img'),
		w_w		 = $(window).width(),
		w_h		 = $(window).height();		
	if($current.length &gt; 0){
		saveFinalPositions($current);
		var final_w	= $current.data('width'),
			final_h	= $current.data('height');
		$current.css({
			'width'		: final_w + 'px',
			'height'	: final_h + 'px',
			'marginTop'	: w_h/2 - final_h/2 + 'px',
			'marginLeft': w_w/2 - final_w/2 + 'px'
		});
	}
});
</pre>
<p>When we click on the back link, we want to close the preview of the image:</p>
<pre class="brush:js">
$back.bind('click',closePreview)
</pre>
<p>The functions for showing and hiding the navigation:</p>
<pre class="brush:js">
//shows the navigation buttons
function showNav(){
	$next_img.stop().animate({
		'right'	: '10px'
	},300);
	$prev_img.stop().animate({
		'left'	: '10px'
	},300);
}

//hides the navigation buttons
function hideNav(){
	$next_img.stop().animate({
		'right'	: '-50px'
	},300);
	$prev_img.stop().animate({
		'left'	: '-50px'
	},300);
}
</pre>
<p>The following function will update the album/image info:</p>
<pre class="brush:js">
//updates the current album and current photo info
function updateInfo(album,photo){
	$top_menu.find('.album_info')
			 .html('Album ' + (album+1))
			 .end()
			 .find('.image_info')
			 .html(' / Shot ' + (photo+1))
}
</pre>
<p>The next function calculates the final width and height of the full image that will be shown based on the window size:</p>
<pre class="brush:js">
function saveFinalPositions($image){
	var theImage 	= new Image();
	theImage.src 	= $image.attr("src");
	var imgwidth 	= theImage.width;
	var imgheight 	= theImage.height;
	
	//140 is 2*60 of next/previous buttons plus 20 of extra margin
	var containerwidth 	= $(window).width() - 140;
	//150 is 30 of header + 30 of footer + extra 90 
	var containerheight = $(window).height() - 150;
	
	if(imgwidth	&gt; containerwidth){
		var newwidth = containerwidth;
		var ratio = imgwidth / containerwidth;
		var newheight = imgheight / ratio;
		if(newheight &gt; containerheight){
			var newnewheight = containerheight;
			var newratio = newheight/containerheight;
			var newnewwidth =newwidth/newratio;
			theImage.width = newnewwidth;
			theImage.height= newnewheight;	
		}
		else{
			theImage.width = newwidth;
			theImage.height= newheight;	
		}
	}
	else if(imgheight &gt; containerheight){
		var newheight = containerheight;
		var ratio = imgheight / containerheight;
		var newwidth = imgwidth / ratio;
		if(newwidth &gt; containerwidth){
			var newnewwidth = containerwidth;
			var newratio = newwidth/containerwidth;
			var newnewheight =newheight/newratio;
			theImage.height = newnewheight;
			theImage.width= newnewwidth;	
		}
		else{
			theImage.width = newwidth;
			theImage.height= newheight;	
		}
	}
	$image.data({'width':theImage.width,'height':theImage.height});		
}
</pre>
<p>When we hit the back link we want the current image to zoom out again with the big yellow bubble. Then we will show the thumbnails again:</p>
<pre class="brush:js">
function closePreview(){
	var $current = $preview.find('img'),
		w_w		 = $(window).width(),
		w_h		 = $(window).height(),
		margin_circle	= w_w + w_w/3;
		
	if(w_h&gt;w_w)
		margin_circle	= w_h + w_h/3;
	
	if($current.is(':animated'))
		return false;
	//hide the navigation
	hideNav();
	//hide the topmenu
	$top_menu.stop()
			 .animate({'top':'-30px'},400,'easeOutBack');
	//hide the image
	$current.stop().animate({
		'width'		: '0px',
		'height'	: '0px',
		'marginTop'	: w_h/2 +'px',
		'marginLeft': w_w/2 +'px'
	},700,function(){
		$(this).remove();
	});
	//animate the bubble image
	//first set the positions correctly - 
	//it could have changed on a window resize
	setTimeout(function(){
		$bubble.css({
			'width'		 :	margin_circle + 'px',
			'height'	 :	margin_circle + 'px',
			'margin-top' :	-margin_circle/2+'px',
			'margin-left':	-margin_circle/2+'px'
		});
		$('BODY').css('background','url("bg.jpg") repeat scroll left top #222222');
		$bubble.animate({
			'width'		:	'0px',
			'height'	:	'0px',
			'marginTop'	:	'0px',
			'marginLeft':	'0px'
		},500);
	},200);
	setTimeout(function(){
		$header.stop()
			   .animate({'top':'30px'},700,'easeOutBack');
		$thumbnails_wrapper.stop()
						   .show()	
						   .animate({'top':'110px'},700,'easeOutBack');
	},600);
}
</pre>
<p>And finally, we define the function that will make the thumbnail albums scrollable by applying Manos&#8217; thumbnail scroller:</p>
<pre class="brush:js">
function createThumbnailScroller(){
	/*
	ThumbnailScroller function parameters:
	1) id of the container (div id)
	2) thumbnail scroller type. Values: "horizontal", "vertical"
	3) first and last thumbnail margin (for better cursor interaction)
	4) scroll easing amount (0 for no easing)
	5) scroll easing type
	6) thumbnails default opacity
	7) thumbnails mouseover fade speed (in milliseconds)
	*/
 ThumbnailScroller("tshf_container1","horizontal",10,800,"easeOutCirc",0.5,300);
 ThumbnailScroller("tshf_container2","horizontal",10,800,"easeOutCirc",0.5,300);
 ThumbnailScroller("tshf_container3","horizontal",10,800,"easeOutCirc",0.5,300);
}
</pre>
<p>And that&#8217;s it! We hope you liked the tutorial and found it useful!</p>
<p><a class="demo" href="http://tympanus.net/Tutorials/BubblerifficImageGallery/" target="_blank">View demo</a><a class="download" href="http://tympanus.net/Tutorials/BubblerifficImageGallery/BubblerifficImageGallery.zip">Download source</a></p>
<div class="googlead"><!-- wp_ad_camp_1 --></div>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2010/12/10/bubbleriffic-image-gallery/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>Polaroid Photobar Gallery with jQuery</title>
		<link>http://tympanus.net/codrops/2010/09/28/polaroid-photobar-gallery/</link>
		<comments>http://tympanus.net/codrops/2010/09/28/polaroid-photobar-gallery/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 11:54:55 +0000</pubDate>
		<dc:creator>Mary Lou</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[image gallery]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[rotation]]></category>
		<category><![CDATA[sliding]]></category>
		<category><![CDATA[thumbnails]]></category>

		<guid isPermaLink="false">http://tympanus.net/codrops/?p=2774</guid>
		<description><![CDATA[View demoDownload source In this tutorial we are going to create an image gallery with a Polaroid look. We will have albums that will expand to sets of slightly rotated thumbnails that pop out on hover. The full image will slide in from the bottom once a thumbnail is clicked. In the full image view [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://tympanus.net/Tutorials/PolaroidPhotobarGallery/" target="_blank"><img class="aligncenter size-full wp-image-2786" title="polaroidphotobar" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/uploads/2010/09/polaroidphotobar.jpg" alt="" width="580" height="315" /></a></p>
<p><a class="demo" href="http://tympanus.net/Tutorials/PolaroidPhotobarGallery/" target="_blank">View demo</a><a class="download" href="http://tympanus.net/Tutorials/PolaroidPhotobarGallery/PolaroidPhotobarGallery.zip">Download source</a></p>
<p>In this tutorial we are going to create an image gallery with a Polaroid look. We will have albums that will expand to sets of slightly rotated thumbnails that pop out on hover. The full image will slide in from the bottom once a thumbnail is clicked. In the full image view the user can navigate through the pictures or simply choose another thumbnail to be displayed.</p>
<p>For this gallery we will be using the <a href="http://plugins.jquery.com/project/2d-transform" target="_blank">2D Transform plugin</a> to animate rotations.</p>
<p>The beautiful photos used in the demo are by talented <a href="http://www.flickr.com/photos/tetsumo/" target="_blank">Tetsumo</a>. Visit his blog <a href="http://www.yluux.com/" target="_blank">here</a>.</p>
<p>Let&#8217;s get started!</p>
<div class="ct-ad-article-wrapper ct-ad-article-wrapper-in"><div class="ct-ad-article"><img class="ct-ad-img" src="http://codropspz.tympanus.netdna-cdn.com/codrops/wp-content/themes/codropstheme02/images/advertisement.jpg" /><div id="bsap_1279993" class="bsarocks bsap_af25dfd2f1908889af7a1aa5f4dcbd9e"></div><div style="clear:both;"></div></div></div>
<h3>The Markup</h3>
<p>We are going to include all our HTML in a div with the class &#8220;pp_gallery&#8221;. It will consist of the loading div, the navigation that will appear when the full image is viewed and the main thumbnails container.</p>
<p>Inside of the thumbnails container which will have the class &#8220;pp_thumbContainer&#8221;, we will have several divs for the albums and a div for going back to the album view. Each album will contain the thumbnails with a description wrapped in a div with the class &#8220;content&#8221;. We will also include a div element for the description of the album itself.</p>
<pre class="brush:xml">&lt;div id="pp_gallery" class="pp_gallery"&gt;
	&lt;div id="pp_loading" class="pp_loading"&gt;&lt;/div&gt;
	&lt;div id="pp_next" class="pp_next"&gt;&lt;/div&gt;
	&lt;div id="pp_prev" class="pp_prev"&gt;&lt;/div&gt;
	&lt;div id="pp_thumbContainer"&gt;
		&lt;div class="album"&gt;
			&lt;div class="content"&gt;
				&lt;img src="images/album1/thumbs/1.jpg" alt="images/album1/1.jpg" /&gt;
				&lt;span&gt;The Sixties by Tetsumo&lt;/span&gt;
			&lt;/div&gt;
			&lt;div class="content"&gt;
				&lt;img src="images/album1/thumbs/2.jpg" alt="images/album1/2.jpg" /&gt;
				&lt;span&gt;The Sixties by Tetsumo&lt;/span&gt;
			&lt;/div&gt;
			...
			&lt;div class="descr"&gt;
				The Sixties
			&lt;/div&gt;
		&lt;/div&gt;
		&lt;div class="album" style="bottom:-90px;"&gt;
			...
		&lt;/div&gt;
		...
		&lt;div class="pp_back"&gt;Albums&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;</pre>
<p>The HTML structure of the dynamically created full image preview will be the following:</p>
<pre class="brush:xml">&lt;div id="pp_preview" class="pp_preview"&gt;
	&lt;img src="images/album1/1.jpg" /&gt;
	&lt;div class="pp_descr"&gt;&lt;span&gt;Description&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;</pre>
<p>Now, let&#8217;s take a look at the style.</p>
<h3>The CSS</h3>
<p>We will start with a reset and some general styles for the body:</p>
<pre class="brush:css">*{
	margin:0;
	padding:0;
}
body{
	background:#000 url(../bg.jpg) repeat center center;
	font-family:"Myriad Pro", "Trebuchet MS", Helvetica, sans-serif;
	font-size:12px;
	color: #fff;
	overflow:hidden;
}</pre>
<p>A structured background fits very nicely, so we choose to add a wood texture. You can find this and more textures on <a href="http://webtreats.mysitemyway.com/greyscale-natural-grunge-textures/" target="_blank">Webtreats</a>.</p>
<p>Next, we will style the loading div and the navigation for stepping through the pictures when we are in the preview mode:</p>
<pre class="brush:css">.pp_loading{
	display:none;
	position:fixed;
	top:50%;
	left:50%;
	margin:-35px 0px 0px -35px;
	background:#fff url(../icons/loader.gif) no-repeat center center;
	width:70px;
	height:70px;
	z-index:999;
	opacity:0.7;
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
	border-radius:10px;
}
.pp_next, .pp_prev{
	cursor:pointer;
	top:50%;
	margin-top:-16px;
	width:32px;
	height:32px;
	position:fixed;
	text-align:center;
	border:1px solid #111;
	color:#fff;
	-moz-box-shadow:0px 0px 3px #000;
	-webkit-box-shadow:0px 0px 3px #000;
	box-shadow:0px 0px 3px #000;
}
.pp_next{
	right:-40px;
	background:#222 url(../icons/next.png) no-repeat center center;
}
.pp_prev{
	left:-40px;
	background:#222 url(../icons/prev.png) no-repeat center center;
}</pre>
<p>The loading div is set to the center of the page by using the 50% negative margin trick. When the position is fixed, we can set the top and left to 50% and add a top and left margin to the negative value of half of the element&#8217;s width, or height, respectively.</p>
<p>The same we do for the navigation items, just that here will only center the elements vertically.</p>
<p>The thumbnails container will be positioned at the bottom of the page:</p>
<pre class="brush:css">#pp_thumbContainer{
	position:fixed;
	bottom:0px;
	left:0px;
	height:65px;
	width:100%;
}</pre>
<p>The albums are hidden initially. When we load the page, they will slide in from the bottom, so we will set the initial bottom value to -90 pixels:</p>
<pre class="brush:css">#pp_thumbContainer .album{
	position:absolute;
	width:200px;
	height:65px;
	bottom:-90px;
}</pre>
<p>The left value for the positioning of the albums will be calculated dynamically on page load. We will spread all the albums evenly throughout the width of the page.</p>
<p>The description of the album and the back element will share some styles:</p>
<pre class="brush:css">.album .descr,
.pp_back{
	position:absolute;
	bottom:0px;
	left:-16px;
	background:#222;
	text-align:center;
	border:1px solid #111;
	padding:5px;
	cursor:pointer;
	width:169px;
	color:#fff;
	cursor:pointer;
	text-shadow:0px 0px 1px #fff;
	-moz-box-shadow:1px 1px 4px #000;
	-webkit-box-shadow:1px 1px 4px #000;
	box-shadow:1px 1px 4px #000;
}</pre>
<p>&#8230;but not all. We will overwrite and add the values that are specific to the .pp_back class:</p>
<pre class="brush:css">.pp_back{
	text-transform:uppercase;
	bottom:120px;
	left:-100px;
	width:80px;
}</pre>
<p>The wrapper for the image and the image title will have the following style:</p>
<pre class="brush:css">#pp_thumbContainer .content{
	position:absolute;
	top:0px;
	height:155px;
	cursor:pointer;
}</pre>
<p>These wrappers will also be spread into position dynamically in our JavaScript. We set the top value to 0, so that all the thumbnails align to the top of the thumbnails container. We don&#8217;t want vertical thumbnails to stick out.</p>
<p>The thumbnail will have a white border and a box shadow:</p>
<pre class="brush:css">#pp_thumbContainer img{
	border:5px solid #fff;
	-moz-box-shadow:1px 1px 7px #000;
	-webkit-box-shadow:1px 1px 7px #000;
	box-shadow:1px 1px 7px #000;
}</pre>
<p>The description for each image is invisible. We will only use it to fill the description element for the full view.</p>
<pre class="brush:css">#pp_thumbContainer .content span{
	display:none;
}</pre>
<p>The wrapper for the full image will be positioned outside of the page by setting the top value to 150%. Once the image is loaded, we will slide it in from the bottom. We are setting the left value to 50% since we want to center the picture. Since we don&#8217;t know the width and height of the picture yet, we cannot set any negative margins yet. We will do that in our JavaScript function.</p>
<pre class="brush:css">.pp_preview{
	position:fixed;
	top:150%;
	left:50%;
}</pre>
<p>The full image will have a bigger white border at its bottom where we will insert the description:</p>
<pre class="brush:css">.pp_preview img{
	position:absolute;
	top:0px;
	left:0px;
	border:10px solid #fff;
	border-bottom:45px solid #fff;
	-moz-box-shadow:1px 1px 7px #000;
	-webkit-box-shadow:1px 1px 7px #000;
	box-shadow:1px 1px 7px #000;
}</pre>
<p>The description will be at the bottom of the preview element. In the JavaScript we will set the width and height of the preview div to the one of the image dynamically, so the description will be positioned at the thicker bottom border of the image.</p>
<pre class="brush:css">.pp_descr{
	height:45px;
	line-height:45px;
	font-size:20px;
	width:100%;
	bottom:0px;
	left:0px;
	position:absolute;
	text-align:center;
	color:#00021c;
}</pre>
<p>We will cufonize the description using a nice hand written font (see at the end).</p>
<p>And now, let&#8217;s add some real magic!</p>
<h3>The JavaScript</h3>
<p>There will be many animations throughout the JavaScript. The albums will slide in from the bottom when the page loads. Once an album is clicked, we will spread the thumbnails evenly by giving them an according left value. When we choose a thumbnail, we need to create the preview div and slide it in from the bottom. The image will get resized so that it fits into the window.</p>
<p>Let&#8217;s start by defining some initial variables. First, we want to know if we are dealing with Internet Explorer since we don&#8217;t want to use the rotation of the full image here (it&#8217;s buggy when used together with the slide in animation):</p>
<pre class="brush:js">var ie 			= false;
if ($.browser.msie) {
	ie = true;
}</pre>
<p>We will use some index variables for the navigation and save some elements:</p>
<pre class="brush:js">//current album/image displayed
var current		= -1;
var album		= -1;
//windows width
var w_width 	= $(window).width();
//caching
var $albums 	= $('#pp_thumbContainer div.album');
var $loader		= $('#pp_loading');
var $next		= $('#pp_next');
var $prev		= $('#pp_prev');
var $images		= $('#pp_thumbContainer div.content img');
var $back		= $('#pp_back');</pre>
<p>We want to spread the albums evenly throughout the page, so we will calculate the according left value:</p>
<pre class="brush:js">var nmb_albums	= $albums.length;
var spaces 		= w_width/(nmb_albums+1);
var cnt			= 0;
//preload all the images (thumbs)
var nmb_images	= $images.length;
var loaded  	= 0;
$images.each(function(i){
	var $image = $(this);
	$('&lt;img /&gt;').load(function(){
		++loaded;
		if(loaded == nmb_images){
			//let's spread the albums evenly at the bottom of the page
			$albums.each(function(){
				var $this 	= $(this);
				++cnt;
				var left	= spaces*cnt - $this.width()/2;
				$this.css('left',left+'px');
				$this.stop().animate({'bottom':'0px'},500);
			}).unbind('click').bind('click',spreadPictures);
			//also rotate each picture of an album with a random number of degrees
			$images.each(function(){
				var $this = $(this);
				var r = Math.floor(Math.random()*41)-20;
				$this.transform({'rotate'	: r + 'deg'});
			});
		}
	}).attr('src', $image.attr('src'));
});</pre>
<p>The <strong>spreadPictures</strong> function will do a similar thing: it will move the chosen album to the left and spread all the thumbnails:</p>
<pre class="brush:js">function spreadPictures(){
	var $album = $(this);
	//track which album is opened
	album = $album.index();
	//hide all the other albums
	$albums.not($album).stop().animate({'bottom':'-90px'},300);
		$album.unbind('click');
		//now move the current album to the left
		//and at the same time spread its images throughout
		//the window, rotating them randomly, hide the description of the album

	//store the current left for the reverse operation
	$album.data('left',$album.css('left'))
		  .stop()
		  .animate({'left':'0px'},500)
		  .find('.descr')
		  .stop()
		  .animate({'bottom':'-30px'},200);
		var total_pic 	= $album.find('.content').length;
		var cnt			= 0;
		//each picture
		$album.find('.content')
			  .each(function(){
			var $content = $(this);
			++cnt;
			//window width
			var w_width 	= $(window).width();
			var spaces 		= w_width/(total_pic+1);
			var left		= (spaces*cnt) - (140/2);
			var r 			= Math.floor(Math.random()*41)-20;
			//var r = Math.floor(Math.random()*81)-40;
		$content.stop().animate({'left':left+'px'},500,function(){
			$(this).unbind('click')
					   .bind('click',showImage)
					   .unbind('mouseenter')
					   .bind('mouseenter',upImage)
					   .unbind('mouseleave')
					   .bind('mouseleave',downImage);
		}).find('img')
		  .stop()
		  .animate({'rotate': r+'deg'},300);
		$back.stop().animate({'left':'0px'},300);
			});
}</pre>
<p>Now, we will define what happens when we click on the item to go back to the albums view. We will animate the album to its initial left position and slide the other albums up again. If the user was viewing a full image, we will make it slide up, out of the window (hideCurrentPicture):</p>
<pre class="brush:js">$back.bind('click',function(){
	$back.stop().animate({'left':'-100px'},300);
	hideNavigation();
	//there's a picture being displayed
	//lets slide the current one up
	if(current != -1){
		hideCurrentPicture();
	}

	var $current_album = $('#pp_thumbContainer div.album:nth-child('+parseInt(album+1)+')');
	$current_album.stop()
				  .animate({'left':$current_album.data('left')},500)
				  .find('.descr')
				  .stop()
				  .animate({'bottom':'0px'},500);

	$current_album.unbind('click')
				  .bind('click',spreadPictures);

	$current_album.find('.content')
			  .each(function(){
				var $content = $(this);
				$content.unbind('mouseenter mouseleave click');
				$content.stop().animate({'left':'0px'},500);
		});

	$albums.not($current_album).stop().animate({'bottom':'0px'},500);
	});</pre>
<p>The next function, called <strong>showImage</strong>, will display the full image by sliding it in from the bottom. If there was another image being shown, we will slide that one up. For centering the preview, we need to set its negative margins according to the width and height of the image. We will also rotate the preview randomly:</p>
<pre class="brush:js">function showImage(nav){
	if(nav == 1){
		//reached the first one
		if(current==0){
			return;
		}
		var $content = $('#pp_thumbContainer div.album:nth-child('+parseInt(album+1)+')')
					   .find('.content:nth-child('+parseInt(current)+')');
		//reached the last one
		if($content.length==0){
			current-=2;
			return;
		}
	}
	else
	var $content 	= $(this);

	//show ajax loading image
	$loader.show();

	//there's a picture being displayed
	//lets slide the current one up
	if(current != -1){
		hideCurrentPicture();
	}

	current 				= $content.index();
	var $thumb				= $content.find('img');
	var imgL_source 	 	= $thumb.attr('alt');
	var imgL_description 	= $thumb.next().html();
	//preload the large image to show
	$('&lt;img style=""/&gt;').load(function(){
		var $imgL 	= $(this);
		//resize the image based on the windows size
		resize($imgL);
		//create an element to include the large image
		//and its description
		var $preview = $('&lt;div /&gt;',{
			'id'		: 'pp_preview',
			'className'	: 'pp_preview',
			'html'     	: '&lt;div class="pp_descr"&gt;&lt;span&gt;'+imgL_description+'&lt;/span&gt;&lt;/div&gt;',
			'style'		: 'visibility:hidden;'
	});
		$preview.prepend($imgL);
		$('#pp_gallery').prepend($preview);
		var largeW 	= $imgL.width()+20;
		var largeH 	= $imgL.height()+10+45;
		//change the properties of the wrapping div
		//to fit the large image sizes
		$preview.css({
			'width'			:largeW+'px',
			'height'		:largeH+'px',
			'marginTop'		:-largeH/2-20+'px',
			'marginLeft'	:-largeW/2+'px',
			'visibility'	:'visible'
		});
		Cufon.replace('.pp_descr');
		//show navigation
		showNavigation();

		//hide the ajax image loading
		$loader.hide();

		//slide up (also rotating) the large image
		var r 			= Math.floor(Math.random()*41)-20;
		if(ie)
			var param = {
				'top':'50%'
			};
		else
			var param = {
				'top':'50%',
				'rotate': r+'deg'
			};
		$preview.stop().animate(param,500);
	}).error(function(){
		//error loading image.
		//Maybe show a message : 'no preview available'
	}).attr('src',imgL_source);
}</pre>
<p>The next two functions handle the navigation through the images:</p>
<pre class="brush:js">//click next image
$next.bind('click',function(){
	current+=2;
	showImage(1);
});

//click previous image
$prev.bind('click',function(){
	showImage(1);
});</pre>
<p>The function <strong>hideCurrentPicture</strong> will make the preview slide up. We will not use any rotation animation if the browser is IE:</p>
<pre class="brush:js">//slides up the current picture
function hideCurrentPicture(){
	current = -1;
	var r 	= Math.floor(Math.random()*41)-20;
	if(ie)
		var param = {
			'top':'-100%'
		};
	else
		var param = {
			'top':'-100%',
			'rotate': r+'deg'
		};
	$('#pp_preview').stop()
					.animate(param,500,function(){
						$(this).remove();
					});
}</pre>
<p>The <strong>showNavigation</strong> and <strong>hideNavigation</strong> functions will take care of showing and hiding the navigation items:</p>
<pre class="brush:js">//shows the navigation buttons
function showNavigation(){
	$next.stop().animate({'right':'0px'},100);
	$prev.stop().animate({'left':'0px'},100);
}

//hides the navigation buttons
function hideNavigation(){
	$next.stop().animate({'right':'-40px'},300);
	$prev.stop().animate({'left':'-40px'},300);
}</pre>
<p>When hovering over a thumbnail, we want it to move up a little and rotate slightly:</p>
<pre class="brush:js">function upImage(){
	var $content 	= $(this);
	$content.stop().animate({
		'marginTop'		: '-70px'
	},400).find('img')
		  .stop()
		  .animate({'rotate': '0deg'},400);
}</pre>
<p>When the mouse leaves the currently hovered thumbnail, we want it to drop back, rotating randomly again:</p>
<pre class="brush:js">function downImage(){
	var $content 	= $(this);
	var r 			= Math.floor(Math.random()*41)-20;
	$content.stop().animate({
		'marginTop'		: '0px'
	},400).find('img').stop().animate({'rotate': r + 'deg'},400);
}</pre>
<p>And finally, we will use a resize function to fit the full image into the window:</p>
<pre class="brush:js">function resize($image){
	var widthMargin		= 50
	var heightMargin 	= 200;

	var windowH      = $(window).height()-heightMargin;
	var windowW      = $(window).width()-widthMargin;
	var theImage     = new Image();
	theImage.src     = $image.attr("src");
	var imgwidth     = theImage.width;
	var imgheight    = theImage.height;

	if((imgwidth &gt; windowW)||(imgheight &gt; windowH)){
		if(imgwidth &gt; imgheight){
			var newwidth = windowW;
			var ratio = imgwidth / windowW;
			var newheight = imgheight / ratio;
			theImage.height = newheight;
			theImage.width= newwidth;
			if(newheight&gt;windowH){
				var newnewheight = windowH;
				var newratio = newheight/windowH;
				var newnewwidth =newwidth/newratio;
				theImage.width = newnewwidth;
				theImage.height= newnewheight;
			}
		}
		else{
			var newheight = windowH;
			var ratio = imgheight / windowH;
			var newwidth = imgwidth / ratio;
			theImage.height = newheight;
			theImage.width= newwidth;
			if(newwidth&gt;windowW){
				var newnewwidth = windowW;
				var newratio = newwidth/windowW;
				var newnewheight =newheight/newratio;
				theImage.height = newnewheight;
				theImage.width= newnewwidth;
			}
		}
	}
	$image.css({'width':theImage.width+'px','height':theImage.height+'px'});
}</pre>
<p>Since we cufonize the description, we need to add the following lines to the head of the HTML:</p>
<pre class="brush:xml">&lt;script src="js/cufon-yui.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script src="js/Note_this_400.font.js" type="text/javascript"&gt;&lt;/script&gt;</pre>
<p>You can find the beautiful &#8220;Note This&#8221; font on <a href="http://www.fontsquirrel.com/fonts/Note-this" target="_blank">www.fontsquirrel.com</a>.</p>
<p>And that&#8217;s it! We hope you enjoyed this tutorial and find it useful!!</p>
<p><a class="demo" href="http://tympanus.net/Tutorials/PolaroidPhotobarGallery/" target="_blank">View demo</a><a class="download" href="http://tympanus.net/Tutorials/PolaroidPhotobarGallery/PolaroidPhotobarGallery.zip">Download source</a></p>
<div class="googlead"><!-- wp_ad_camp_1 --></div>
<div class="partner_section_post"><span>Message from Testking</span>Enjoy the free  learning  of web design with <a href="http://www.testkingsite.com/cisco/646-364.html">testking 646-364</a> tutorials.  Download <a href="http://www.testkingsite.com/exin/EX0-101.html">testking EX0-101</a> design tutorials and <a href="http://www.testkingsite.com/cisco/642-374.html">testking 642-374</a> study guides to become expert in web designing .</div>
]]></content:encoded>
			<wfw:commentRss>http://tympanus.net/codrops/2010/09/28/polaroid-photobar-gallery/feed/</wfw:commentRss>
		<slash:comments>111</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 10/19 queries in 0.013 seconds using disk: basic
Content Delivery Network via codropspz.tympanus.netdna-cdn.com

 Served from: tympanus.net @ 2013-05-21 14:54:01 by W3 Total Cache -->