Skip to content

Instantly share code, notes, and snippets.

@jasonmerino
Created May 17, 2013 15:53
Show Gist options
  • Save jasonmerino/5600019 to your computer and use it in GitHub Desktop.
Save jasonmerino/5600019 to your computer and use it in GitHub Desktop.
A CodePen by Jason. Coverflow-Esque Gallery
<div class="contain" id="contain"></div>
var images = [
{
src: 'http://distilleryimage9.s3.amazonaws.com/8f68309ce4f511e1b0c912313b089111_7.jpg',
title: 'Puzzle Time!'
},
{
src: 'http://distilleryimage11.s3.amazonaws.com/3d174250f7cf11e1bb3e22000a1e9b9f_7.jpg',
title: 'Yahtzee. #winning'
},
{
src: 'http://distilleryimage1.s3.amazonaws.com/de1e97922f2111e19896123138142014_7.jpg',
title: 'New Kindle'
},
{
src: 'http://distilleryimage9.s3.amazonaws.com/3a0ede28294511e19e4a12313813ffc0_7.jpg',
title: 'TK-421'
},
{
src: 'http://distilleryimage3.s3.amazonaws.com/f09bcba834d311e1abb01231381b65e3_7.jpg',
title: 'Vintage Video Game Night!'
}
];
var classes = ['prev', 'active', 'next', 'next-next', 'prev-prev', 'no-transition'];
var $el = {
container: $('#contain')
};
var container = {
width: 0,
height: 0,
moveSpace: 0,
left: true,
active: 1
};
var buildGallery = function (images) {
var markup = '';
for (var i = 0; i < images.length; i++) {
var imgClass = '';
if (container.active === i) {
imgClass = 'active';
}
else if (container.active === i + 1) {
imgClass = 'prev';
}
else if (container.active === i - 1) {
imgClass = 'next';
}
markup += '<div style="background-image: url(' + images[i].src + ')" title="' + images[i].title + '" class="' + imgClass + '"></div>';
}
$el.container.html(markup);
$el.images = $('.contain > div');
$el.active = $('.active');
$el.prev = $('.prev');
$el.next = $('.next');
}(images);
var changeUp = function (index) {
if (index < 0) {
index = container.active = 0;
}
else if ((index + 1) > images.length) {
index = container.active = images.length - 1;
}
$el.images.removeClass(classes.join(' ')).addClass('no-transition');
var $img = $el.images.eq(index);
$el.prev = $img.prev('div').toggleClass('prev no-transition');
$el.prev.prev('div').toggleClass('prev-prev');
$el.active = $img.toggleClass('active no-transition');
$el.next = $img.next('div').toggleClass('next no-transition');
$el.next.next('div').toggleClass('next-next');
$el.images.css('transform', '');
};
$el.images.on('click', function (e) {
var index = $el.images.index(this);
container.active = index;
changeUp(index);
});
var touch = {
active: false,
startPosX: 0,
startPosY: 0,
currentPosX: 0,
correntPosY: 0
};
$el.container.on('touchstart', function (event) {
$el.next.next('div').addClass('next-next');
$el.prev.prev('div').addClass('prev-prev');
$el.images.addClass('no-transition');
touch.startPosX = event.originalEvent.touches[0].clientX;
touch.startPosY = event.originalEvent.touches[0].clientY;
container.width = event.currentTarget.offsetWidth;
container.height = event.currentTarget.offsetHeight;
if (touch.startPosX > (container.width / 2)) {
container.moveSpace = touch.startPosX;
container.left = false;
}
else {
container.moveSpace = container.width - touch.startPosX;
container.left = true;
}
});
$el.container.on('touchmove', function (event) {
event.preventDefault();
// track touch status
touch.active = true;
touch.currentPosX = event.originalEvent.touches[0].clientX;
touch.currentPosY = event.originalEvent.touches[0].clientY;
// decide translates for visible moving elements
var activeTranslate = (130 / container.moveSpace) * (touch.currentPosX - touch.startPosX);
var prevTranslate = -130 + activeTranslate;
var nextTranslate = 130 + activeTranslate;
// helper to simplify things
var translatePercent = (activeTranslate / 130) * 100;
// decide scales for visible moving elements
var activeScale;
var prevScale;
var nextScale;
if (touch.currentPosX > touch.startPosX) {
activeScale = (((translatePercent * 70) / 100) + (100 - translatePercent)) / 100;
prevScale = (70 + ((30/100) * translatePercent)) / 100;
nextScale = 0.7;
}
else {
activeScale = (((translatePercent * -1 * 70) / 100) + (100 + translatePercent)) / 100;
prevScale = 0.7;
nextScale = (70 + ((30/100) * (translatePercent * -1))) / 100;
}
// translate and scale all the things
if (activeTranslate <= 130 && activeTranslate >= -130) {
$el.active.css('transform', 'scale(' + activeScale + ') translate3d(' + activeTranslate + '%, 0%, 0)');
if (prevTranslate <= 0 && prevTranslate >= -130) {
$el.prev.css('transform', 'scale(' + prevScale + ') translate3d(' + prevTranslate + '%, 0%, 0)');
}
if (nextTranslate >= 0 && nextTranslate <= 130) {
$el.next.css('transform', 'scale(' + nextScale + ') translate3d(' + nextTranslate + '%, 0%, 0)');
}
}
});
$el.container.on('touchend', function (event) {
var index;
if (touch.currentPosX > touch.startPosX) {
index = container.active = container.active - 1;
}
else {
index = container.active = container.active + 1;
}
if (touch.active) {
changeUp(index);
}
touch.active = false;
});
@import "compass";
html {
height: 100%;
}
body {
background: #222;
height: 100%;
font-family: verdana, sans-serif;
}
.contain {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
backface-visibility: hidden;
}
.contain > div {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
position: absolute;
left: 50%;
margin-left: -37.5%;
transition: transform .5s ease, opacity .5s ease, visibility .1s ease;
backface-visibility: hidden;
transform-style: preserve-3d;
visibility: hidden;
opacity: 0;
height: 75%;
width: 75%;
}
.contain > div:nth-child(1) {
}
.contain > div:after {
content: attr(title);
color: #fff;
font-size: 18px;
display: block;
background: rgba(0, 0, 0, .6);
padding: 1vh 2vw;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
box-sizing: border-box;
}
.contain > div.prev,
.contain > div.prev-prev,
.contain > div.active,
.contain > div.next,
.contain > div.next-next {
display: block;
visibility: visible;
opacity: 1;
z-index: 0;
}
.contain > div.active {
z-index: 2;
transform-origin: center center;
}
.contain > div.prev,
.contain > div.next {
z-index: 1;
}
.contain > div.prev,
.contain > div.prev-prev {
transform: scale(.7) translate3d(-130%, 0%, 0px);
}
.contain > div.next,
.contain > div.next-next {
transform: scale(.7) translate3d(130%, 0%, 0px);
}
.contain > div.no-transition {
transition: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment