STEP 1: Create divs inside of your page that will contain the carousel elements
.gallery.gallery-main.gallery-main-imageimg(src=”/images/gallery3.jpg”).gallery-filmstripa(href=””)img(src=”/images/gallery1.jpg”)a(href=””)img(src=”/images/gallery2.jpg”)a(href=””)img(src=”/images/gallery3.jpg”)a(href=””)img(src=”/images/gallery4.jpg”)a(href=””)img(src=”/images/gallery5.jpg”)
STEP 2: Set the styles for all of the elements inside of your carousel:
The Displayed Image Gallery:
/*set styles for the wrapper around the image that will be displayed on click*/
.gallery {background-color: black;}
.gallery > .gallery-main {position: relative;height: 400px;overflow: hidden;}
/*set styles for the inner container for the image that will be displayed on click*/
.gallery > .gallery-main > .gallery-main-image {position: absolute;top: 0; bottom: 0;right: 0; left: 0;}
/*set styles for the image itself*/
.gallery > .gallery-main > .gallery-main-image > img {display: block;margin: 0 auto;max-height: 100%;max-width: 100%;height: 400px;}
The Filmstrip that contains thumbnails of the images to be displayed:
/*set styles for the filmstrip container*/
.gallery > .gallery-filmstrip {position: relative;height: 280px;margin-top: 10px;}
/*set styles for everything inside the filmstrip container*/
.gallery > .gallery-filmstrip > * {position: absolute;top: 0;left: 0;}
/*position everything inside the filmstrip in the center*/.gallery > .gallery-filmstrip > * {position: absolute;top: 0;left: 0;}
/*set animation class to the filmstrip on click*/.gallery > .gallery-filmstrip-animated > * {transition: transform 1s, opacity 1s;}
/*set a height and width for the gallery filmstrip images*/.gallery > .gallery-filmstrip img {height: 200px;width: 200px;}
STEP 3: Create functions using jQuery and Javascript that will allow you to iterate through your images using the styles and animations you just created.
const initializeGallery = function() {positionGalleryFilmstrip(0, false)
$(‘.gallery-filmstrip > *’).on(‘click’, function(event) {event.preventDefault();const cell = $(this);const index = cell.index()console.log(‘CLICKED’, index)positionGalleryFilmstrip(index-2)})}
initializeGallery()
const visibleIndicies = function(totalNumberOfCells, numberOfVisibleCells, offset){let visible = []for (let index = 0; index < numberOfVisibleCells; index++) {visible[index] = (index+offset) % totalNumberOfCells}return visible}
const zIndexForPosition = function(position){return ((position === 0 || position === 4) ? 1 :(position === 1 || position === 3) ? 2 :3)}
const opacityForPosition = function(position){return ((position === 0 || position === 4) ? 0.4 :(position === 1 || position === 3) ? 0.7 :1)}
const transformForPosition = function(position){return ({0: ‘translateX(160px) translateY(31px) scale(.8)’,1: ‘translateX(300px) translateY(31px) scale(1)’,2: ‘translateX(500px) translateY(31px) scale(1.3)’,3: ‘translateX(700px) translateY(31px) scale(1)’,4: ‘translateX(860px) translateY(31px) scale(.8)’,})[position]}
const visibleIndicies = function(totalNumberOfCells, numberOfVisibleCells, offset) {let visible = []for (let index = 0; index < numberOfVisibleCells; index++) {visible[index] = (index+offset) % totalNumberOfCells}return visible}
const positionGalleryFilmstrip = function(offset, animate=true){const filmstrip = $(‘.gallery-filmstrip’)const numberOfCells = 5;const cells = filmstrip.children()if (offset < 0) offset += cells.lengthconst visibleCells = visibleIndicies(cells.length, numberOfCells,offset)if (animate){filmstrip.addClass(‘gallery-filmstrip-animated’)}else{filmstrip.removeClass(‘gallery-filmstrip-animated’)}cells.each(function(index){const cell = $(this)let position = visibleCells.indexOf(index)if (isBefore(index, visibleCells, cells.length)){cell.css({display: ‘block’,zIndex: ‘0’,opacity: ‘0’,transform: ‘translateX(100px) translateY(31px) scale(.6)’,})}else if (isAfter(index, visibleCells, cells.length)){cell.css({display: ‘block’,zIndex: ‘0’,opacity: ‘0’,transform: ‘translateX(890px) translateY(31px) scale(.6)’,})}else if (position === -1){cell.css({display: ‘none’,zIndex: ‘0’,opacity: ‘1’,transform: ‘’,})}else{cell.css({display: ‘block’,zIndex: zIndexForPosition(position),opacity: opacityForPosition(position),transform: transformForPosition(position),})}if (position === 2){const src = cell.find(‘> img’).attr(‘src’)const image = $(‘<img>’).attr(‘src’, src)const gallery = filmstrip.closest(‘.gallery’)const galleryMain = gallery.find(‘> .gallery-main’)const currentImageWrapper = galleryMain.find(‘.gallery-main-image:first’)const nextImageWrapper = currentImageWrapper.clone()const nextImage = nextImageWrapper.find(‘> img’)if (nextImage.attr(‘src’) === src) return;nextImage.attr(‘src’, src)galleryMain.prepend(nextImageWrapper)currentImageWrapper.fadeOut(function(){currentImageWrapper.remove()})}})}
Whoa!! What is happening here? Let’s break it out and go over it step by step:
const positionGalleryFilmstrip = function(offset, animate=true){const filmstrip = $(‘.gallery-filmstrip’)const numberOfCells = 5;const cells = filmstrip.children()}
if (offset < 0) offset += cells.lengthconst visibleCells = visibleIndicies(cells.length, numberOfCells, offset)
if (animate){filmstrip.addClass(‘gallery-filmstrip-animated’)}else{filmstrip.removeClass(‘gallery-filmstrip-animated’)}
cells.each(function(index){const cell = $(this)let position = visibleCells.indexOf(index)if (isBefore(index, visibleCells, cells.length)){cell.css({display: ‘block’,zIndex: ‘0’,opacity: ‘0’,transform: ‘translateX(100px) translateY(31px) scale(.6)’,})} else if (isAfter(index, visibleCells, cells.length)){cell.css({display: ‘block’,zIndex: ‘0’,opacity: ‘0’,transform: ‘translateX(890px) translateY(31px) scale(.6)’,})}else if (position === -1){cell.css({display: ‘none’,zIndex: ‘0’,opacity: ‘1’,transform: ‘’,})}else{cell.css({display: ‘block’,zIndex: zIndexForPosition(position),opacity: opacityForPosition(position),transform: transformForPosition(position),})}
if (position === 2){const src = cell.find(‘> img’).attr(‘src’)const image = $(‘<img>’).attr(‘src’, src)const gallery = filmstrip.closest(‘.gallery’)const galleryMain = gallery.find(‘> .gallery-main’)const currentImageWrapper = galleryMain.find(‘.gallery-main-image:first’)const nextImageWrapper = currentImageWrapper.clone()const nextImage = nextImageWrapper.find(‘> img’)if (nextImage.attr(‘src’) === src) return;nextImage.attr(‘src’, src)galleryMain.prepend(nextImageWrapper)currentImageWrapper.fadeOut(function(){currentImageWrapper.remove()})}})}
const isBefore = function(index, visibleCells, cellsLength){let beforeFirstIndex = visibleCells[0]-1if (beforeFirstIndex < 0) beforeFirstIndex += cellsLengthreturn index === beforeFirstIndex}
const isAfter = function(index, visibleCells, cellsLength){let afterLastIndex = visibleCells[visibleCells.length-1]+1if (afterLastIndex > cellsLength) afterLastIndex -= cellsLengthreturn index === afterLastIndex}