Стильное портфолио на jQuery с Lightbox эффектом
Вне зависимости от тематики ресурса, рано или поздно каждому может пригодиться портфолио на сайте. Особенно такой элемент будет интересен профессиональным фотографам или дизайнерам интерьеров. Но, к сожалению, движок Joomla в первозданном своём виде мало что может предложить для реализации данной затеи. В большинстве случаев люди скачивают специальные расширения и хорошо, если они вас устраивают в том виде, в котором предлагают разработчики. Обычно часть контента урезано, а для того чтобы получить полноценный вариант, требуется выложить некую сумму. Так же встречаются и крупные расширения, вам нужно создать портфолио, а там много лишнего, что вам лично не нужно. Так почему же не создать своё собственное, подходящее к вашим требованиям? Давайте сделаем своими руками в обход движка, чтобы не забивать себе голову сложностью разработки компонентов и плагинов. Добавим особый скрипт, который будет отвечать за вывод полноразмерных картинок, а миниатюры выстроим в ряд, как в галереи, при помощи библиотеки jQuery. Под всё это будет отдельная страница, а в верхней части поместим небольшое меню, вдруг кому пригодиться. Для работы неважно, какую версию cms вы используете, так же какой шаблон по умолчанию выставлен.
1. Создание папок и добавление изображений
Первым делом необходимо создать на рабочем столе папку с названием portfolio-lightbox. Внутри будут располагаться все файлы, отвечающие за работу портфолио, а вот изображения поместим в подпапку с именем images. Найдите 10 изображений в jpg формате с размером 1920х1200px. Переименуйте их следующим образом: image-1, image-2 и т.д. Положить все картинки в папку images. Вот как должно выглядеть:
2. Создаём страницу на html
Для того чтобы создать страницу на HTML нужно всего два файла index.html (отвечает за генерацию страницы в браузере) и style.css (визуальное оформление). Создав их, помещаем в нашу папку portfolio-lightbox.
Открываем в любом текстовом редакторе index.html и пишем в него это:
HTML код:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251" /> <title>Portfolio jQuery</title> <link rel="stylesheet" type="text/css" href="style.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script type="text/javascript" src="jquery-gallary.js"></script> <script type="text/javascript" src="lightbox.min.js"></script> </head> <body> <br><br> <div><a href="#">&lt; BACK TO HOME</a></div> <div><a href="#">MENU 1</a></div> <div><a href="#">MENU 2</a></div> <div><a href="#">MENU 3</a></div> <div><a href="#">MENU 4</a></div> <br><br> <div id="images"> <span id="i1"><a href="images/image-1.jpg" rel="lightbox"><img src="images/image-1.jpg" /></a></span> <span id="i2"><a href="images/image-2.jpg" rel="lightbox"><img src="images/image-2.jpg" /></a></span> <span id="i3"><a href="images/image-3.jpg" rel="lightbox"><img src="images/image-3.jpg" /></a></span> <span id="i4"><a href="images/image-4.jpg" rel="lightbox"><img src="images/image-4.jpg" /></a></span> <span id="i5"><a href="images/image-5.jpg" rel="lightbox"><img src="images/image-5.jpg" /></a></span> <span id="i6"><a href="images/image-6.jpg" rel="lightbox"><img src="images/image-6.jpg" /></a></span> <span id="i7"><a href="images/image-7.jpg" rel="lightbox"><img src="images/image-7.jpg" /></a></span> <span id="i8"><a href="images/image-8.jpg" rel="lightbox"><img src="images/image-8.jpg" /></a></span> <span id="i9"><a href="images/image-9.jpg" rel="lightbox"><img src="images/image-9.jpg" /></a></span> <span id="i10"><a href="images/image-10.jpg" rel="lightbox"><img src="images/image-10.jpg" /></a></span> </div> </body> </html>
Здесь подключили последнею библиотеку jQuery, таблицу стилей, два скрипта (о них позже). Ещё добавили наши изображения и создали небольшое меню из пяти пунктов, один из которых мы будем использовать для возврата на сайт. На 15 строке, там, где написано «BACK TO HOME», вставляем ссылку на главную страницу своего сайта. Так посетители смогут возвращаться обратно на ваш ресурс.
Теперь вставляем код в style.css:
CSS код:
body { margin: 0; padding: 0; background: #000000; } #images { white-space: nowrap; overflow: hidden; font-size: 0; line-height: 0; } #images span img { margin: 0; font-size: 15px; width: inherit; position: absolute; height: inherit; width: 100%; height: 100%; } #images span { display: inline-block; position: relative; margin: 5px; box-shadow: 0px 0px 6px 1px #ffffff; } a img { border: 0; } #images span img:hover { box-shadow: 0px 0px 6px 1px #ffffff; } #bars { background: #000; width: 100%; color: #fff; font-weight: bold; position: relative; padding: 30px 0 30px 0 ; z-index: 10000; box-shadow: 0px 0px 40px rgba(0,0,0,1); font-size: 56px; text-align: center; font-family: 'Myriad Pro', Helvetica, Arial, sans-serif; } #bars a { opacity: 1 !important; color: #fff; font-family: 'Myriad Pro', Helvetica, Arial, sans-serif; font-size: 20px; text-decoration: none; font-weight: bold; } .link-back { font: bold 12px Arial, Helvetica, sans-serif; text-decoration: none; width: 160px; text-align: center; display: inline-block; } .link-back a { text-decoration: none; padding: 10px; display: block; background: #6f89b9; color: #fff; } .lightboxOverlay { position: absolute; top: 0; left: 0; z-index: 9999; background-color: #82959e; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); opacity: 0.8; display: none; } .lightbox { position: absolute; left: 0; width: 100%; z-index: 10000; text-align: center; line-height: 0; font-weight: normal; } .lightbox .lb-image { /*display: block;*/ height: auto; width: auto; -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; } .lightbox a img { border: none; } .lb-outerContainer { /*position: relative;*/ background-color: #000; *zoom: 1; /*width: 250px;*/ /*height: 250px;*/ margin: 0 auto; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 8px; } .lb-outerContainer:after { content: ""; display: table; clear: both; } .lb-container { padding: 6px; } .lb-dataContainer { margin: 0 auto; padding-top: 5px; *zoom: 1; width: 100%; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } .lb-dataContainer:after { content: ""; display: table; clear: both; } .lb-data { padding: 0 4px; color: #bbbbbb; } .lb-data .lb-details { width: 85%; float: left; text-align: left; line-height: 1.1em; } .lb-data .lb-caption { font-size: 13px; font-weight: bold; line-height: 1em; } .lb-data .lb-number { display: block; clear: left; padding-bottom: 1em; font-size: 12px; color: #999999; } .lb-data .lb-close { display: block; float: right; width: 30px; height: 30px; text-align: right; outline: none; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70); opacity: 0.7; } .lb-data .lb-close:hover { cursor: pointer; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); opacity: 1; }
Тут написаны стили не только для галереи, но и для lightbox эффекта (всплывающее окно с оригинальной картинкой).
3. Создаём скрипты
У нас буду два скрипта, первый это lightbox.min.js. Он отвечает за вывод всплывающего окна тех элементов, которые имеют значения rel=”lightbox” в тегах. Если обратите внимание на код в index.html, то увидите, что я выставил это значение всем изображениям. Вот какой вид имеют эти ссылки:
HTML код:
<a href="images/image-1.jpg" rel="lightbox"><img src="images/image-1.jpg" /></a>
Ссылка состоит из двух частей:
<a href="images/image-1.jpg" rel="lightbox"> - картинка, которая будет открыта только во всплывающем окне после нажатия (за работу отвечает lightbox.min.js).
<img src="images/image-1.jpg" /> - миниатюра на странице (за показ и построение будет отвечать второй срипт jquery-gallary.js).
jquery-gallary.js будет определять какое количество изображений необходимо для завершения ряда. Если по ширине вашего экрана изображения выстроятся таким образом, что следующий ряд будет не полным, скрипт автоматически добавить картинки из первой строки по порядку. При этом вы можете менять количество изображений в портфолио как угодно. Ещё он отвечает за небольшое увеличение миниатюры при наведении курсора.
Создаём jquery-gallary.js, lightbox.min.js и бросаем их в папку portfolio-lightbox.
В jquery-gallary.js вставляем код:
jQuery код:
$(document).ready(function() { var imageWidth = 384; // Ширина миниатюры var imageHeight = 240; // Высота миниатюры $('#images span').css({'width' : imageWidth, 'height' : imageHeight}); function imageNumber() { $('.appended').remove(); $('#images span').removeClass(); $('.wrapper').each(function() { var wrapperContent = $(this).html(); $(this).replaceWith(wrapperContent); }); var windowWidth = $(window).width(); var numberOfImages = ($("#images span").length); var imagesPerRow = Math.ceil(windowWidth / imageWidth); if(numberOfImages % imagesPerRow != 0) { var numberOnRow = Math.round((1 - (numberOfImages/imagesPerRow % 1)) * imagesPerRow); var number = 0; while(number <= numberOnRow) { $('#i'+number).clone(true).appendTo($('#images')).attr('class', 'appended'); ++number; } var nuAppended = $('.appended').length; var nextA = parseFloat(numberOfImages)+1; while(nuAppended > 0) { $('.appended').each(function() { $(this).attr('id', 'i'+nextA); ++nextA; --nuAppended; }); } } var slices = $("#images span"); for(var i = 0; i < slices .length; i+=imagesPerRow) { slices .slice(i, i+imagesPerRow).wrapAll("<div class='wrapper'></div>"); } } function hovering() { $('#images .wrapper span img').hover(function() { $(this).css({ 'width' : '150%', 'height' : '150%', 'z-index' : '7000' }); }, function() { $(this).css({ 'height' : '100%', 'width' : '100%', 'box-shadow' : 'inset 0px 0px 20px rgba(0,0,0,0.8)', 'z-index' : '2000' }); }); $('#images .wrapper:not(:first, :last) span:not(:first-child) img').hover(function() { $(this).css({ 'right' : '-25%', 'bottom' : '-25%' }); }, function() { $(this).css({ 'z-index' : '2000', 'right' : '0', 'bottom' : '0' }); }); $('#images .wrapper:first span:not(:first) img').hover(function() { $(this).css({ 'right' : '-25%', 'top' : '0' }); }, function() { $(this).css({ 'z-index' : '2000', 'right' : '0', 'bottom' : '0' }); }); $('#images .wrapper:first span:first-child img').hover(function() { $(this).css({ 'left' : '0', 'top' : '0' }); }, function() { $(this).css({ 'left' : '0', 'top' : '0' }); }); $('#images .wrapper:not(:first, :last) span:first-child img').hover(function() { $(this).css({ 'left' : '0', 'top' : '-25%' }); }, function() { $(this).css({ 'left' : '0', 'top' : '0' }); }); $('#images .wrapper:last span img:not(:first)').hover(function() { $(this).css({ 'left' : '-25%', 'top' : '-50%' }); }, function() { $(this).css({ 'left' : '0', 'top' : '0', }); }); $('#images .wrapper:last span:first img').hover(function() { $(this).css({ 'left' : '0', 'top' : '-50%' }); }, function() { $(this).css({ 'left' : '0', 'top' : '0' }); }); } imageNumber(); hovering(); $(window).resize(function() { imageNumber(); hovering(); }); });
Вверху есть две строчки с imageWidth и imageHeight, они нужны для выбора размера миниатюр. Сейчас стоит 384х240px – такое значение специально выставлено для изображений с размером 1920x1200px. При использовании других вариантов, данные значения нужно менять.
Теперь в lightbox.min.js пишем этот большой код:
jQuery код:
(function(){ var b,d,c;b=jQuery;c=(function(){function b(){ this.fadeDuration=500; this.fitImagesInViewport=true; //false открыть изображение в полный размер this.resizeDuration=700; this.showImageNumberLabel=true; //false скрыть количество изображений на странице this.wrapAround=true //false отключить повтор изображений на странице } b.prototype.albumLabel=function(b,c){ return"Image "+b+" of "+c}; return b})(); d=(function(){function c(b){ this.options=b;this.album=[]; this.currentImageIndex=void 0; this.init() } c.prototype.init=function(){ this.enable(); return this.build()}; c.prototype.enable=function(){ var c=this;return b('body') .on('click','a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(d){c.start(b(d.currentTarget)) ;return false}) }; c.prototype.build=function(){ var c=this;b("<div id='lightboxOverlay' class='lightboxOverlay'></div><div id='lightbox' class='lightbox'><div class='lb-outerContainer'><div class='lb-container'><img class='lb-image' src='' /></div></div><div class='lb-dataContainer'><div class='lb-data'><div class='lb-details'><span class='lb-caption'></span><span class='lb-number'></span></div></div></div></div>") .appendTo(b('body')); this.$lightbox=b('#lightbox'); this.$overlay=b('#lightboxOverlay'); this.$outerContainer=this.$lightbox.find('.lb-outerContainer'); this.$container=this.$lightbox.find('.lb-container'); this.containerTopPadding=parseInt(this.$container.css('padding-top'),10); this.containerRightPadding=parseInt(this.$container.css('padding-right'),10); this.containerBottomPadding=parseInt(this.$container.css('padding-bottom'),10); this.containerLeftPadding=parseInt(this.$container.css('padding-left'),10); this.$overlay.hide().on('click',function(){c.end();return false}); this.$lightbox.hide().on('click',function(d){if(b(d.target).attr('id')==='lightbox'){c.end()}return false}); this.$outerContainer.on('click',function(d){if(b(d.target).attr('id')==='lightbox'){c.end()}return false}); this.$lightbox.find('.lb-prev').on('click',function(){if(c.currentImageIndex===0){c.changeImage(c.album.length-1)}else{c.changeImage(c.currentImageIndex-1)}return false}); this.$lightbox.find('.lb-next').on('click',function(){if(c.currentImageIndex===c.album.length-1){c.changeImage(0)}else{c.changeImage(c.currentImageIndex+1)}return false}); return this.$lightbox.find('.lb-loader, .lb-close').on('click',function(){c.end(); return false})};c.prototype.start=function(c){var f,e,j,d,g,n,o,k,l,m,p,h,i;b(window).on("resize",this.sizeOverlay);b('select, object, embed').css({visibility:"hidden"}); this.$overlay.width(b(document).width()).height(b(document).height()).fadeIn(this.options.fadeDuration); this.album=[];g=0;j=c.attr('data-lightbox'); if(j){h=b(c.prop("tagName")+'[data-lightbox="'+j+'"]');for(d=k=0,m=h.length;k<m;d=++k){e=h[d]; this.album.push({link:b(e).attr('href'),title:b(e).attr('title')}); if(b(e).attr('href')===c.attr('href')){g=d}}}else{if(c.attr('rel')==='lightbox'){ this.album.push({link:c.attr('href'),title:c.attr('title')})}else{i=b(c.prop("tagName")+'[rel="'+c.attr('rel')+'"]'); for(d=l=0,p=i.length;l<p;d=++l){e=i[d]; this.album.push({link:b(e).attr('href'),title:b(e).attr('title')}); if(b(e).attr('href')===c.attr('href')){g=d}}}}f=b(window);o=f.scrollTop()+f.height()/10;n=f.scrollLeft(); this.$lightbox.css({top:o+'px',left:n+'px'}).fadeIn(this.options.fadeDuration); this.changeImage(g)}; c.prototype.changeImage=function(f){var d,c,e=this; this.disableKeyboardNav();d=this.$lightbox.find('.lb-image'); this.sizeOverlay(); this.$overlay.fadeIn(this.options.fadeDuration);b('.lb-loader').fadeIn('slow'); this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide(); this.$outerContainer.addClass('animating'); c=new Image(); c.onload=function(){var m,g,h,i,j,k,l;d.attr('src',e.album[f].link);m=b(c);d.width(c.width);d.height(c.height); if(e.options.fitImagesInViewport){ l=b(window).width(); k=b(window).height(); j=l-e.containerLeftPadding-e.containerRightPadding-20; i=k-e.containerTopPadding-e.containerBottomPadding-110; if((c.width>j)||(c.height>i)){if((c.width/j)>(c.height/i)){h=j; g=parseInt(c.height/(c.width/h),10); d.width(h); d.height(g)}else{g=i; h=parseInt(c.width/(c.height/g),10); d.width(h); d.height(g)}} } return e.sizeContainer(d.width(),d.height())};c.src=this.album[f].link; this.currentImageIndex=f}; c.prototype.sizeOverlay=function(){return b('#lightboxOverlay').width(b(document).width()).height(b(document).height())}; c.prototype.sizeContainer=function(f,g){var b,d,e,h,c=this; h=this.$outerContainer.outerWidth(); e=this.$outerContainer.outerHeight(); d=f+this.containerLeftPadding+this.containerRightPadding; b=g+this.containerTopPadding+this.containerBottomPadding; this.$outerContainer.animate({width:d,height:b}, this.options.resizeDuration,'swing'); setTimeout(function(){ c.$lightbox.find('.lb-dataContainer').width(d); c.$lightbox.find('.lb-prevLink').height(b); c.$lightbox.find('.lb-nextLink').height(b); c.showImage()}, this.options.resizeDuration)}; c.prototype.showImage=function(){ this.$lightbox.find('.lb-loader').hide(); this.$lightbox.find('.lb-image').fadeIn('slow'); this.updateNav(); this.updateDetails(); this.preloadNeighboringImages(); this.enableKeyboardNav()}; c.prototype.updateNav=function(){ this.$lightbox.find('.lb-nav').show(); if(this.album.length>1){if(this.options.wrapAround){ this.$lightbox.find('.lb-prev, .lb-next').show()}else{if( this.currentImageIndex>0){this.$lightbox.find('.lb-prev').show()} if(this.currentImageIndex<this.album.length-1){ this.$lightbox.find('.lb-next').show()}}}}; c.prototype.updateDetails=function(){var b=this; if(typeof this.album[this.currentImageIndex].title!=='undefined'&&this.album[this.currentImageIndex].title!==""){ this.$lightbox.find('.lb-caption').html( this.album[this.currentImageIndex].title).fadeIn('fast')}if( this.album.length>1&&this.options.showImageNumberLabel){ this.$lightbox.find('.lb-number').text( this.options.albumLabel(this.currentImageIndex+1,this.album.length)).fadeIn('fast')}else{ this.$lightbox.find('.lb-number').hide()} this.$outerContainer.removeClass('animating'); this.$lightbox.find('.lb-dataContainer').fadeIn( this.resizeDuration,function(){return b.sizeOverlay()})}; c.prototype.preloadNeighboringImages=function(){var c,b;if( this.album.length>this.currentImageIndex+1){c=new Image();c.src=this.album[this.currentImageIndex+1].link}if( this.currentImageIndex>0){b=new Image();b.src=this.album[this.currentImageIndex-1].link}}; c.prototype.enableKeyboardNav=function(){b(document).on('keyup.keyboard',b.proxy(this.keyboardAction,this))}; c.prototype.disableKeyboardNav=function(){b(document).off('.keyboard')}; c.prototype.keyboardAction=function(g){var d,e,f,c,b;d=27;e=37;f=39;b=g.keyCode;c=String.fromCharCode(b).toLowerCase(); if(b===d||c.match(/x|o|c/)){ this.end()}else if(c==='p'||b===e){if( this.currentImageIndex!==0){ this.changeImage(this.currentImageIndex-1)}}else if(c==='n'||b===f){if( this.currentImageIndex!==this.album.length-1){this.changeImage(this.currentImageIndex+1)}}}; c.prototype.end=function(){ this.disableKeyboardNav();b(window).off("resize",this.sizeOverlay); this.$lightbox.fadeOut(this.options.fadeDuration); this.$overlay.fadeOut(this.options.fadeDuration); return b('select, object, embed').css({visibility:"visible"})}; return c})(); b(function(){var e,b;b=new c(); return e=new d(b)}) } ) .call(this);
Для того чтобы впоследствии закрыть всплывающее окно, необходимо нажать на любое свободное место.
4. Бросаем на сервер
На этом этапе портфолио готово, если открыть index.html в браузере вы увидите полностью рабочую страницу. Здесь можно посмотреть ДЕМО. Но нам ведь нужно чтобы посетители сайта смогли тоже увидеть её, поэтому, папку portfolio-lightbox с уже готовыми файлами бросаем на сервер в корень сайта (это место где лежат configuration.php и htaccess.txt).
5. Настраиваем меню
Открываем панель управления и в основном меню создаём ещё один пункт с заголовком Portfolio. Тип пункта меню выбираем «системные ссылки – внешний url». Вставляем ссылку такого типа http://вашсайт.ru/portfolio-lightbox/index.html.
Домен используем свой. Теперь гости сайта смогут заходить в ваше портфолио через этот пункт в основном меню.
Заключение
У такого способа есть очевидные плюсы. Для создания данного портфолио мы использовали всего четыре файла, два из которых скрипты, когда как при разработке сложного компонента ушло бы куда больше времени и сил. Меняя таблицу стилей и выбирая размер миниатюр под свои изображения, можно создать по-настоящему уникальную галерею. Меню вставил только для того, чтобы вы могли использовать его в качестве навигации. При желании их можно удалить или создайте ещё страницы, а пункты используйте для перехода между разного рода портфолио.
Соседние материалы | ||||
Шесть способов улучшить SEO Joomla! сайта | Форма обратной связи для Joomla своими руками |