Skip to content

Commit

Permalink
Multiple galleries support, added close button and many improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
feimosi committed Jul 24, 2014
1 parent ee66e42 commit e565187
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 90 deletions.
138 changes: 92 additions & 46 deletions src/baguetteBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

var baguetteBox = function(selector) {
// Buttons SVG shapes
var leftArrow = '<svg width="45" height="60" xmlns="http://www.w3.org/2000/svg" version="1.1">' +
'<polyline points="10 30 30 10 50 30" stroke="rgba(255,255,255,0.5)" stroke-width="5"' +
'stroke-linecap="butt" fill="none" stroke-linejoin="round" transform="translate(0, 60) rotate(-90)"/>' +
Expand All @@ -13,35 +14,56 @@ var baguetteBox = function(selector) {
'<polyline points="10 30 30 10 50 30" stroke="rgba(255,255,255,0.5)" stroke-width="5"' +
'stroke-linecap="butt" fill="none" stroke-linejoin="round" transform="translate(45) rotate(90)"/>' +
'</svg>',
closeX = '<svg width="45" height="60" xmlns="http://www.w3.org/2000/svg" version="1.1">' +
'</svg>';
closeX = '<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" version="1.1">' +
'<g stroke="rgb(187, 187, 187)" stroke-width="4">' +
'<line x1="5" y1="5" x2="25" y2="25"/>' +
'<line x1="5" y1="25" x2="25" y2="5"/>' +
'</g></svg>';
var overlayID = 'baguetteBoxOverlay';
var sliderID = 'baguetteBoxSlider';
// DOM Elements references
var overlay, slider, previousButton, nextButton, closeButton;
var currentIndex = 0;
// Image index inside the slider
var currentIndex = 0, currentGallery = -1;
// Array of all active galleries
var galleries = document.querySelectorAll(selector);
var images = document.querySelectorAll(selector + ' a');
// Map of galleries images
var imagesMap = {};
// Array containing temporary images elements
var imagesArray = [];

init();

[].forEach.call(
images,
function (element, index) {
element.addEventListener('click', function(event) {
event.preventDefault();
showOverlay(index);
}, false);
}
);

function init() {
buildOverlay();
// For each gallery bind a click event to every image inside it
[].forEach.call(
galleries,
function (galleryElement, galleryIndex) {
galleryElement.dataset.baguetteBoxId = galleryIndex;
imagesMap[galleryIndex] = galleryElement.querySelectorAll('a');
[].forEach.call(
imagesMap[galleryIndex],
function (imageElement, imageIndex) {
imageElement.addEventListener('click', function(event) {
event.preventDefault();
prepareOverlay(galleryIndex);
showOverlay(imageIndex);
}, false);
}
);
}
);
}

function buildOverlay() {
overlay = document.getElementById(overlayID);
// Check if the overlay already exists, if not - create it
if(!overlay) {
overlay = document.createElement('div');
overlay = document.querySelector('body').appendChild(overlay);
overlay.id = overlayID;
}
// Check if the overlay already exists, if yes return
if(overlay)
return;
overlay = document.createElement('div');
overlay = document.querySelector('body').appendChild(overlay);
overlay.id = overlayID;
// Create gallery slider element
slider = document.createElement('div');
slider = overlay.appendChild(slider);
Expand All @@ -50,25 +72,25 @@ var baguetteBox = function(selector) {
// Create all necessary buttons
previousButton = document.createElement('button');
previousButton.id = 'previousButton';
previousButton.className = 'baguetteBoxButton';
previousButton.innerHTML = leftArrow;
previousButton = overlay.appendChild(previousButton);

nextButton = document.createElement('button');
nextButton.id = 'nextButton';
nextButton.className = 'baguetteBoxButton';
nextButton.innerHTML = rightArrow;
nextButton = overlay.appendChild(nextButton);

closeButton = document.createElement('button');
closeButton.id = 'closeButton';
closeButton.innerHTML = closeX;
closeButton = overlay.appendChild(closeButton);
closeButton.style.display = 'none';

/*
Assign event listeners
*/
previousButton.className = nextButton.className = closeButton.className = 'baguetteBoxButton';

bindEvents();
}

function bindEvents() {
// When clicked on the overlay (outside displayed image) close it
overlay.addEventListener('click', function(event) {
if(event.target && event.target.nodeName !== "IMG")
Expand Down Expand Up @@ -99,27 +121,44 @@ var baguetteBox = function(selector) {
}, false);
}

function showOverlay(index){
// Return if overlay is already visible
if(overlay.style.display === 'block')
function prepareOverlay(galleryIndex) {
if(currentGallery === galleryIndex)
return;
currentGallery = galleryIndex;
// Empty slider of previous contents
while (slider.firstChild) {
slider.removeChild(slider.firstChild);
}
imagesArray = [];
// Prepare and append images containers
for(var i = 0; i < images.length; i++) {
imagesArray.push(returnImageElement());
for(var i = 0; i < imagesMap[galleryIndex].length; i++) {
imagesArray.push(returnImageContainer());
slider.appendChild(imagesArray[i]);
}
}

function returnImageContainer() {
var fullImage = document.createElement('div');
fullImage.className = 'fullImage';
return fullImage;
}

function showOverlay(index) {
// Return if overlay is already visible
if(overlay.style.display === 'block')
return;
// Show proper image and set current index to a new value
overlay.style.display = 'block';
currentIndex = index;
showImage(currentIndex);
setOffset();
updateOffset();
// Fade in overlay
setTimeout(function() {
overlay.className = 'visible';
}, 10);
}

function hideOverlay(){
function hideOverlay() {
// Return if overlay is already hidden
if(overlay.style.display === 'none')
return;
Expand All @@ -133,39 +172,46 @@ var baguetteBox = function(selector) {
function showImage(index) {
if(index > imagesArray.length - 1)
return;
var imageElement = imagesArray[index];
imageElement.innerHTML = '<img src="' + images[index].getAttribute('href') + '">';
var imageContainer = imagesArray[index];
imageElement = imagesMap[currentGallery][index];
imageCaption = imageElement.dataset.caption;
imageCaption = typeof imageCaption !== 'undefined' ? '<figcaption>' + imageCaption + '</figcaption>' : '';
imageContainer.innerHTML = '<figure><img src="' + imageElement.getAttribute('href') + '">' + imageCaption + '</figure>';
}

function showNextImage() {
if(currentIndex <= images.length - 2) {
if(currentIndex <= imagesArray.length - 2) {
currentIndex++;
setOffset();
updateOffset();
} else {
slider.className = 'bounceFromRight';
setTimeout(function() {
slider.className = '';
}, 400);
}
}

function showPreviousImage() {
if(currentIndex >= 1) {
currentIndex--;
setOffset();
updateOffset();
} else {
slider.className = 'bounceFromLeft';
setTimeout(function() {
slider.className = '';
}, 400);
}
}

function setOffset() {
function updateOffset() {
slider.style.left = -currentIndex * 100 + '%';
preload();
}

function preload() {
if(currentIndex <= images.length - 2)
if(currentIndex <= imagesArray.length - 2)
showImage(currentIndex + 1);
if(currentIndex >= 1)
showImage(currentIndex - 1);
}

function returnImageElement() {
var fullImage = document.createElement('div');
fullImage.className = 'fullImage';
return fullImage;
}
};
113 changes: 79 additions & 34 deletions src/baguetteBox.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,105 @@
width: 100%;
height: 100%;
opacity: 0;
z-index: 100000;
z-index: 1000000;
background-color: #222;
background-color: rgba(0,0,0,.8);
transition: opacity .5s ease;

.fullImage img {
display: inline-block;
max-height: 100%;
max-width: 100%;
vertical-align: middle;
box-shadow: 0 0 8px rgba(0,0,0,.6);
&.visible {
opacity: 1;
}

.fullImage {
display: inline-block;
width: 100%;
height: 100%;
line-height: 1px;
text-align: center;
width: 100%;
display: inline-block;

figure {
display: inline-block;
position: relative;
margin: 0;
max-height: 100%;
max-width: 100%;
}

img {
max-height: 100%;
max-width: 100%;
vertical-align: middle;
box-shadow: 0 0 8px rgba(0,0,0,.6);
}

figcaption {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
line-height: 1.8;
color: #ccc;
background-color: rgba(0,0,0,.6);
font-family: sans-serif;
}

&:before {
content: "";
display: inline-block;
height: 50%;
}
}

.fullImage:before {
content: "";
display: inline-block;
height: 50%;
}

#baguetteBoxSlider {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
white-space: nowrap;
transition: left .4s ease;

&.bounceFromRight {
animation: bounceFromRight .4s ease-out;
}

&.bounceFromLeft {
animation: bounceFromLeft .4s ease-out;
}
}

@keyframes bounceFromRight{
0% { margin-left: 0; }
50% { margin-left: -30px; }
100% { margin-left: 0; }
}

#baguetteBoxOverlay.visible {
opacity: 1;
@keyframes bounceFromLeft{
0% { margin-left: 0; }
50% { margin-left: 30px; }
100% { margin-left: 0; }
}

.baguetteBoxButton {
position: absolute;
cursor: pointer;
outline: none;
padding: 0;
margin: 0;
border: 0;
border-radius: 15%;
background-color: rgba(68,68,68,0.5);
transition: background-color .4s ease;

&:hover {
background-color: rgba(68,68,68,0.8);
}

&.arrowButton {
display: inline-block;
top: calc(50% - 30px);
width: 45px;
height: 60px;
padding: 0;
border: 0;
border-radius: 15%;
background-color: rgba(0,0,0,0.4);
transition: background-color .4s ease;
}

&.arrowButton:hover {
background-color: rgba(0,0,0,0.8);
}
}

Expand All @@ -71,12 +119,9 @@
left: 16px;
}

#baguetteBoxSlider {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
white-space: nowrap;
transition: left .4s ease;
#closeButton {
top: 20px;
right: 24px;
width: 30px;
height: 30px;
}
Loading

0 comments on commit e565187

Please sign in to comment.