Stacked & Scattered Polaroid Gallery with jQuery and CSS3

Stacked & Scattered Polaroid Gallery with jQuery and CSS3
File Size: 757 KB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   

A stacked, scattered, jQuery powered polaroid gallery that uses CSS3 for photo rotate and flip animations.

How to use it:

1. Load the latest jQuery JavaScript library in the document.

<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>

2. Create the Html template for your polaroid gallery.

<div class="wrap" id="wrap">
  <div class="photo photo_front" id="photo_{{index}}" onclick="turn(this)">
    <div class="photo-wrap">
      <div class="side side-front">
        <p class="image"><img src="photo/{{img}}"></p>
        <p class="caption">{{caption}}</p>
      </div>
      <div class="side side-back">
        <p class="desc">{{desc}}</p>
      </div>
    </div>
  </div>
</div>

3. Place your photos into the photo folder and prepare your data in the data.js as shown below.

var data = [];

var dataStr = "1.DeathNote<br>\
<br>\
Japanese Cartoon<br>\
<br>\
<br>\
2.FateUBW<br>\
<br>\
Japanese Cartoon<br>\
<br>\
<br>\
3.FateZero<br>\
<br>\
Japanese Cartoon<br>\
"
var d = dataStr.split("<br><br><br>");
for(var i = 0; i<d.length; i++){
  var c = d[i].split("<br><br>");
  data.push({
    img: c[0]+ ".jpg",
    caption: c[0].split(".")[1],
    desc: c[1]
  });
}

4. The primary CSS / CSS3 styles for the Polaroid Gallery.

.wrap {
  width: 100%;
  height: 600px;
  position: absolute;
  top: 50%;
  margin-top: -300px;
  background-color: #333;
  overflow: hidden;
  -webkit-perspective: 800px;
  -moz-perspective: 800px;
}

.photo {
  width: 260px;
  height: 320px;
  position: absolute;
  z-index: 1;
  box-shadow: 0 0 1px rgba(0,0,0,.01);
  -webkit-transition: all 0.6s;
  -moz-transition: all 0.6s;
  left: 50%;
  top: 50%;
  margin: -160px 0 0 -130px;
}

.photo .side {
  width: 100%;
  height: 100%;
  background-color: #eee;
  position: absolute;
  top: 0;
  right: 0;
  padding: 20px;
  box-sizing: border-box;
}

.photo .side-front { /*display: none;*/
}

.photo .side-front .image {
  width: 100%;
  height: 250px;
  line-height: 250px;
  overflow: hidden;
}

.photo .side-front .image img { width: 100%; }

.photo .side-front .caption {
  text-align: center;
  font-size: 16px;
  line-height: 50px;
}

.photo .side-back { }

.photo .side-back .desc {
  color: #666;
  font-size: 14px;
  line-height: 1.5em;
}

.photo_center {
  left: 50%;
  top: 50%;
  margin: -160px 0 0 -130px;
  z-index: 999;
}

.photo-wrap {
  position: absolute;
  width: 100%;
  height: 100%;
  -webkit-transform-style: preserve-3d;
  -webkit-transition: all 0.6s;
  -moz-transform-style: preserve-3d;
  -moz-transition: all 0.6s;
}

.photo-wrap .side-front {
  -webkit-transform: rotateY(0deg);
  -moz-transform: rotateY(0deg);
}

.photo-wrap .side-back {
  -webkit-transform: rotateY(180deg);
  -moz-transform: rotateY(180deg);
}

.photo-wrap .side {
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
}

.photo_front .photo-wrap {
  -webkit-transform: rotateY(0deg);
  -moz-transform: rotateY(0deg);
}

.photo_back .photo-wrap {
  -webkit-transform: rotateY(180deg);
  -moz-transform: rotateY(180deg);
}

5. Style the dots navigation that helps you navigate between through photos like an image slider.

.nav {
  width: 80%;
  height: 30px;
  line-height: 30px;
  position: absolute;
  left: 10%;
  bottom: 20px;
  z-index: 999;
  text-align: center;
}

.nav .i {
  width: 30px;
  height: 30px;
  display: inline-block;
  cursor: pointer;
  background-color: #aaa;
  text-align: center;
  border-radius: 90%;
  -webkit-transform: scale(0.5);
  -webkit-transition: all 0.5s;
  -moz-transform: scale(0.5);
  -moz-transition: all 0.5s;
}

.nav .i_current {
  -webkit-transform: scale(0.8);
  -moz-transform: scale(0.8);
}

.nav .i_back {
  -webkit-transform: rotateY(-180deg) scale(0.8);
  -moz-transform: rotateY(-180deg) scale(0.8);
  background-color: #555;
}

6. The core JavaScript (jQuery script) to active the Polaroid Gallery.

$(document).ready(function(){
  addPhotos();
});

function select(selector) {
  var method = selector.substr(0,1) == '.' ? 'getElementsByClassName' : 'getElementById';
  return document[method](selector.substr(1));
}

function range() {
  var range = {left : {x : [], y : []}, right : {x : [], y : []}};
  var wrap = {
    w : select("#wrap").clientWidth,
    h : select("#wrap").clientHeight
  }
  var photo = {
    w : select(".photo")[0].clientWidth,
    h : select(".photo")[0].clientHeight
  }
  range.wrap = wrap;
  range.photo = photo;

  range.left.x = [0, wrap.w/2 - photo.w/2];
  range.left.y = [0, wrap.h - photo.w/2];
  range.right.x = [wrap.w/2 + photo.w/2, wrap.w];
  range.right.y = [0, wrap.h - photo.w/2];

  return range;
}

function sort(n) {
  var _photo = select('.photo');
  var photos = [];
  for(i=0; i<_photo.length; i++) {
    _photo[i].className = _photo[i].className.replace(/\s*photo_center\s*/, ' ');
    _photo[i].className = _photo[i].className.replace(/\s*photo_front\s*/, ' ');
    _photo[i].className = _photo[i].className.replace(/\s*photo_back\s*/, ' ');
    _photo[i].className += ' photo_front';
    _photo[i].style.left = '';
    _photo[i].style.top = '';
    _photo[i].style['transform'] = 'rotate(360deg) scale(1.3)';
    _photo[i].style['-webkit-transform'] = 'rotate(360deg) scale(1.3)';
    photos.push(_photo[i]);
  }
  var photo_center = select('#photo_' + n);
  photo_center.className += ' photo_center';

  photo_center = photos.splice(n, 1)[0];

  var photos_left = photos.splice(0, Math.ceil(photos.length/2));
  var photos_right = photos;

  var ranges = range();
  for(var i=0; i<photos_left.length; i++){
    photos_left[i].style.left = random(ranges.left.x) + "px";
    photos_left[i].style.top = random(ranges.left.y) + "px";
    photos_left[i].style['transform'] = 'rotate('+random([-150,150])+'deg) scale(1)';
    photos_left[i].style['-webkit-transform'] = 'rotate('+random([-150,150])+'deg) scale(1)';
  }
  for(var i = 0; i<photos_right.length; i++){
    photos_right[i].style.left = random(ranges.right.x) + "px";
    photos_right[i].style.top = random(ranges.right.y) + "px";
    photos_right[i].style['transform'] = 'rotate('+random([-150,150])+'deg) scale(1)';
    photos_right[i].style['-webkit-transform'] = 'rotate('+random([-150,150])+'deg) scale(1)';
  }
  var navs = select('.i');
  for(var i=0; i<navs.length; i++) {
    navs[i].className = navs[i].className.replace(/\s*i_current\s*/, ' ');
    navs[i].className = navs[i].className.replace(/\s*i_back\s*/, ' ');
  }
  select('#nav_' + n).className += ' i_current '; 
}

function random(range) {
  var max = Math.max(range[0], range[1]);
  var min = Math.min(range[0], range[1]);
  var diff = max - min;
  var number = Math.floor(Math.random() * diff + min);
  return number;
}

var data = data;
function addPhotos() {
  var template = select('#wrap').innerHTML;
  var html = [];
  var nav = [];
  for (i=0; i<data.length; i++) {
    var _html = template.replace('{{index}}', i)
    .replace('{{img}}', data[i].img)
    .replace('{{caption}}', data[i].caption)
    .replace('{{desc}}', data[i].desc);
    html.push(_html);
    nav.push('<span id="nav_'+i+'" class="i" onclick ="turn(select(\'#photo_'+i+'\'))">&nbsp;</span>');
  }
  html.push('<div class="nav">'+nav.join('')+'</div>');
  select('#wrap').innerHTML = html.join('');
  sort(random([0, data.length]));
}

function turn(elem) {
  var cls = elem.className;
  var n = elem.id.split("_")[1];

  if(! /photo_center/.test(cls)) {
    return sort(n);
  }

  if(/photo_front/.test(cls)) {
    cls = cls.replace(/photo_front/, 'photo_back'); 
    select('#nav_' + n).className += ' i_back ';
  } else {
    cls = cls.replace(/photo_back/, 'photo_front');
    select('#nav_' + n).className = select('#nav_' + n).className.replace(/\s*i_back\s*/, ' ');
  }
  return elem.className = cls;
}

This awesome jQuery plugin is developed by brucehan77. For more Advanced Usages, please check the demo page or visit the official website.