带jQuery和CSS3的美丽的照片堆叠图库

智能甄选 2018-01-07 18:29:38

在本教程中,我们将创建一个漂亮的和新鲜的图像库。这个想法是将相册显示为一个滑动器,当选择一个相册时,我们会将相册的图片显示为一个漂亮的照片堆栈。在photostack视图中,我们可以通过在所有堆栈后面加上一个平滑的动画来浏览图像。

我们将使用jQuery和CSS3属性来进行旋转的图像效果。我们还将使用webkit - box反射属性来镜像相册视图中的方框——查看谷歌Chrome或Apple Safari的演示,看看效果如何。

我们还将使用一些PHP来获取每个相册的图像。

所以,让我们开始吧!

标记

在我们的HTML结构中,我们将有几个元素。主要的是用缩略图和描述的专辑列,以及与照片堆栈的预览。

相册视图的结构如下:

<div id="ps_slider"> ... </div> ... </div> </div>

在开始时,相册div的不透明度将是0,我们将使用JavaScript在列中淡出。

我们需要在HTML中提供的信息是每个相册和缩略图图像的位置。使用我们的小PHP脚本,我们将得到相应的相册中的所有图像。

暗叠加的结构和照片堆叠的预览会是这样的:

<div id="ps_overlay"></a></div>

我们将把每个相册的图片动态地插入到ps_container div中。

现在,让我们看一下PHP。

PHP

我们的PHP文件将从我们的JavaScript中调用,我们将通过AJAX调用获得信息。PHP的外观如下:

$location = 'albums';$album_name = $_GET['album_name'];$files = glob($location . '/' . $album_name . '/*.{jpg,gif,png}', GLOB_BRACE);$encoded = json_encode($files);echo $encoded;unset($encoded);CSS

该画廊的风格将包含一些CSS3属性和一个Webkit特定的属性来实现镜像效果。

让我们首先重新设置一些边框和边距,并定义正文的一般样式:

body, ul, li, h1, h2, h3{ margin:0; padding:0;}body{ background:#121212; font-family:Arial, Helvetica, sans-serif; font-size:11px; color:#fff; overflow-x:hidden;}

我们将继续使用预览的风格。覆盖层将有以下样式:

.ps_overlay{    z-index:90;    background:#111;    width:100%;    height:100%;    position:fixed;    top:0px;    left:0px;    opacity:0.5;}

照片堆栈的容器将有一个定义的高度和宽度。我们将以“50% /负利润”的方式将其完全定位,并将其居中。

.ps_container{ width:480px; height:350px; position:absolute; top:50%; margin-top:-175px; left:50%; margin-left:-240px; z-index:100;}

该图像将有一个粗的白色边框和一个漂亮的框阴影。我们将把图像相对于它的容器,但是因为我们只知道图像的宽度和高度一旦我们动态地添加它们,我们将在JavaScript函数中设置页边距:

.ps_container img{ border:10px solid #fff; position:absolute; top:50%; left:50%; -moz-box-shadow:1px 1px 10px #000; -webkit-box-shadow:1px 1px 10px #000; box-shadow:1px 1px 10px #000;}

预览的关闭按钮将固定在窗口的右上方:

a.ps_close{ background:#000 url(../images/close.png) no-repeat center center; cursor:pointer; width:56px; height:56px; position:fixed; right:10px; top:10px; z-index:1000; -moz-border-radius:10px; -webkit-border-radius:10px; border-radius:10px; opacity:0.6;}

当用户在当前图像上方徘徊时,我们将显示一个“下一个照片”元素:

a.ps_next_photo{ position:absolute; top:50%; left:50%; width:56px; height:56px; margin:-28px 0 0 -28px; z-index:200; cursor:pointer; background:#000 url(../images/next_photo.png) no-repeat 50% 50%; opacity:0.6;    -moz-border-radius:10px;    -webkit-border-radius:10px;    border-radius:10px;}

最后两个元素的悬停类:

a.ps_next_photo:hover,a.ps_close:hover{ opacity:0.8; }

现在我们将为相册视图及其列定义样式。滑动器容器将相对地定位。在左侧和右侧边缘的自动值中,我们将容器水平放置在页面上:

.ps_slider{ width:845px; height:300px; position:relative; margin:110px auto 0px auto;}

导航元素将有以下样式:

.ps_slider a.next,.ps_slider a.prev{ position:absolute; background-color:#000;    background-position:center center;    background-repeat:no-repeat;    border:1px solid #232323;    width:20px;    height:20px;    top:50%;    margin-top:-10px;    opacity:0.6;    -moz-border-radius:5px;    -webkit-border-radius:5px;    border-radius:5px;    cursor:pointer;    outline:none;}.ps_slider a.prev{    left:-30px;    background-image:url(../images/prev.png);}.ps_slider a.next{    right:-30px;    background-image:url(../images/next.png);}.ps_slider a.prev:hover,.ps_slider a.next:hover{    border:1px solid #333;    opacity:0.9;}

我们还为导航元素定义了一个类,当它们被禁用时:

.ps_slider a.disabled,.ps_slider a.disabled:hover{    opacity:0.4;    border:1px solid #111;    cursor:default;}

每个专辑的专栏将会有以下的风格:

.ps_slider .ps_album{ width:140px; height:310px; padding:10px; background-color:#333; border:1px solid #444; position:absolute; top:0px; text-align:center; cursor:pointer; -moz-box-shadow:1px 1px 4px #000; -webkit-box-shadow:1px 1px 4px #000; box-shadow:1px 1px 4px #000; -webkit-box-reflect: below 5px -webkit-gradient( linear, left top, left bottom, from(transparent), color-stop(0.6, transparent), to(rgb(18, 18, 18)) );}

最后一个属性是Webkit框反射,它反映了列。我们说它应该像梯度一样对元素进行镜像。

我们为整个列添加一个hover类:

.ps_slider .ps_album:hover{ background-color:#383838;}

缩略图图像和列的内容将有以下样式:

.ps_slider .ps_album img{ height:90px; border:1px solid #444; -moz-box-shadow:1px 1px 4px #000; -webkit-box-shadow:1px 1px 4px #000; box-shadow:1px 1px 4px #000;}.ps_slider .ps_album .ps_desc{ display:block; color:#666; background:#111 url(../images/overlay.png) no-repeat bottom right; height:200px; margin-top:10px; text-align:left; line-height:20px; overflow:hidden; text-overflow:ellipsis; border:1px solid #393939; -moz-box-shadow:0px 0px 2px #000 inset; -webkit-box-shadow:0px 0px 2px #000 inset; box-shadow:0px 0px 2px #000 inset;}.ps_slider .ps_album:hover .ps_desc{ background-image:none;}.ps_slider .ps_album .ps_desc span{ display:block; margin:0px 10px 10px 10px; border-top:1px solid #333; padding-top:5px;}.ps_slider .ps_album .ps_desc h2{ margin:10px 10px 0px 10px; text-align:left; padding-bottom:5px; font-weight:normal; color:#ddd; text-shadow:0px 0px 1px #fff; border-bottom:1px solid #000;}

当我们点击相册时,加载元素将会显示,所有图片都将在预览中加载:

.ps_slider .loading{ background:#121212 url(../images/loading.gif) no-repeat 50% 50%; position:absolute; top:0px; left:0px; width:100%; height:100%; opacity:0.7;}

要使不透明度在IE中工作,您需要添加这个过滤器(具有正确的值):

过滤器:progid:DXImageTransform.Microsoft.Alpha(不透明度= 60);

我不想丑化代码。

让我们添加一个魔术!

JavaScript

首先,我们需要定义一些变量,帮助我们控制相册导航并保留一些元素。变量位置保存了每个相册列的左值。这取决于列的宽度。

/*** navR,navL are flags for controlling the albums navigation* first gives us the position of the album on the left* positions are the left positions for each of the 5 albums displayed at a time*/var navR,navL = false;var first = 1;var positions = { '0' : 0, '1' : 170, '2' : 340, '3' : 510, '4' : 680}var $ps_albums = $('#ps_albums');/*** number of albums available*/var elems = $ps_albums.children().length;var $ps_slider = $('#ps_slider');

我们将对专辑的专栏进行初步定位:

/*** position all the albums on the right side of the window*/var hiddenRight = $(window).width() - $ps_albums.offset().left;$ps_albums.children('div').css('left',hiddenRight + 'px');/*** move the first 5 albums to the viewport*/$ps_albums.children('div:lt(5)').each( function(i){ var $elem = $(this); $elem.animate({'left': positions[i] + 'px','opacity':1},800,function(){ if(elems > 5) enableNavRight(); }); });

为了在相册中滑动,我们将定义在单击next或之前的按钮时发生的情况,并创建两个用于向左或向右移动的函数:

/*** next album*/$ps_slider.find('.next').bind('click',function(){ if(!$ps_albums.children('div:nth-child('+parseInt(first+5)+')').length || !navR) return; disableNavRight(); disableNavLeft(); moveRight();});/*** we move the first album (the one on the left) to the left side of the window* the next 4 albums slide one position, and finally the next one in the list* slides in, to fill the space of the first one*/function moveRight () { var hiddenLeft = $ps_albums.offset().left + 163; var cnt = 0; $ps_albums.children('div:nth-child('+first+')').animate({'left': - hiddenLeft + 'px','opacity':0},500,function(){ var $this = $(this); $ps_albums.children('div').slice(first,parseInt(first+4)).each( function(i){ var $elem = $(this); $elem.animate({'left': positions[i] + 'px'},800,function(){ ++cnt; if(cnt == 4){ $ps_albums.children('div:nth-child('+parseInt(first+5)+')').animate({'left': positions[cnt] + 'px','opacity':1},500,function(){ //$this.hide(); ++first; if(parseInt(first + 4) < elems) enableNavRight(); enableNavLeft(); }); } }); } ); });}/*** previous album*/$ps_slider.find('.prev').bind('click',function(){ if(first==1 || !navL) return; disableNavRight(); disableNavLeft(); moveLeft();});/*** we move the last album (the one on the right) to the right side of the window* the previous 4 albums slide one position, and finally the previous one in the list* slides in, to fill the space of the last one*/function moveLeft () { var hiddenRight = $(window).width() - $ps_albums.offset().left; var cnt = 0; var last= first+4; $ps_albums.children('div:nth-child('+last+')').animate({'left': hiddenRight + 'px','opacity':0},500,function(){ var $this = $(this); $ps_albums.children('div').slice(parseInt(last-5),parseInt(last-1)).each( function(i){ var $elem = $(this); $elem.animate({'left': positions[i+1] + 'px'},800,function(){ ++cnt; if(cnt == 4){ $ps_albums.children('div:nth-child('+parseInt(last-5)+')').animate({'left': positions[0] + 'px','opacity':1},500,function(){ //$this.hide(); --first; enableNavRight(); if(first > 1) enableNavLeft(); }); } }); } ); });}

下一个助手函数处理禁用和启用导航项:

/*** disable or enable albums navigation*/function disableNavRight () { navR = false; $ps_slider.find('.next').addClass('disabled');}function disableNavLeft () { navL = false; $ps_slider.find('.prev').addClass('disabled');}function enableNavRight () { navR = true; $ps_slider.find('.next').removeClass('disabled');}function enableNavLeft () { navL = true; $ps_slider.find('.prev').removeClass('disabled');}

在接下来的步骤中,我们将定义当我们打开一个相册时会发生什么。我们首先让加载元素出现,并在加载所有图像后显示预览。源代码的信息来自对PHP类的AJAX调用。对于旋转效果,我们使用旋转的CSS3属性,我们将其限制在一定的度数范围内,这样我们就不会疯狂地旋转图像:

var $ps_container = $('#ps_container');var $ps_overlay = $('#ps_overlay');var $ps_close = $('#ps_close');/*** when we click on an album,* we load with AJAX the list of pictures for that album.* we randomly rotate them except the last one, which is* the one the User sees first. We also resize and center each image.*/$ps_albums.children('div').bind('click',function(){ var $elem = $(this); var album_name = 'album' + parseInt($elem.index() + 1); var $loading = $('<div />',{className:'loading'}); $elem.append($loading); $ps_container.find('img').remove(); $.get('photostack.php', {album_name:album_name} , function(data) { var items_count = data.length; for(var i = 0; i < items_count; ++i){ var item_source = data[i]; var cnt = 0; $('<img />').load(function(){ var $image = $(this); ++cnt; resizeCenterImage($image); $ps_container.append($image); var r = Math.floor(Math.random()*41)-20; if(cnt < items_count){ $image.css({ '-moz-transform' :'rotate('+r+'deg)', '-webkit-transform' :'rotate('+r+'deg)', 'transform' :'rotate('+r+'deg)' }); } if(cnt == items_count){ $loading.remove(); $ps_container.show(); $ps_close.show(); $ps_overlay.show(); } }).attr('src',item_source); } },'json');});/*** when hovering each one of the images, * we show the button to navigate through them*/$ps_container.live('mouseenter',function(){ $('#ps_next_photo').show();}).live('mouseleave',function(){ $('#ps_next_photo').hide();});

将当前图像放到堆栈后面的漂亮动画如下所定义:

/*** navigate through the images: * the last one (the visible one) becomes the first one.* we also rotate 0 degrees the new visible picture */$('#ps_next_photo').bind('click',function(){ var $current = $ps_container.find('img:last'); var r = Math.floor(Math.random()*41)-20; var currentPositions = { marginLeft : $current.css('margin-left'), marginTop : $current.css('margin-top') } var $new_current = $current.prev(); $current.animate({ 'marginLeft':'250px', 'marginTop':'-385px' },250,function(){ $(this).insertBefore($ps_container.find('img:first')) .css({ '-moz-transform' :'rotate('+r+'deg)', '-webkit-transform' :'rotate('+r+'deg)', 'transform' :'rotate('+r+'deg)' }) .animate({ 'marginLeft':currentPositions.marginLeft, 'marginTop' :currentPositions.marginTop },250,function(){ $new_current.css({ '-moz-transform' :'rotate(0deg)', '-webkit-transform' :'rotate(0deg)', 'transform' :'rotate(0deg)' }); }); });});

我们将顶部和左页边的空白赋予了一些创建“回退”效果的值。由于我们的结构总是显示顶部的最后一个图像,所以我们还需要在开始时插入移动的图像,这样它就会像上次一样在堆栈中出现。

点击关闭元素,我们回到相册视图:

/*** close the images view, and go back to albums*/$('#ps_close').bind('click',function(){ $ps_container.hide(); $ps_close.hide(); $ps_overlay.fadeOut(400);});

我们著名的resize函数根据给定的容器宽度和高度调整图像大小。

在函数的最后,我们应用了大小,我们也应用了负边距-记住,这是我们可以把一个绝对位置的元素放在中心位置的方法;我们在CSS中定义了top,并将其保留为50%,所以现在我们需要将其放到正确的位置,并使用这些边缘值。

/*** resize and center the images*/function resizeCenterImage($image){ var theImage = new Image(); theImage.src = $image.attr("src"); var imgwidth = theImage.width; var imgheight = theImage.height; var containerwidth = 460; var containerheight = 330; if(imgwidth > containerwidth){ var newwidth = containerwidth; var ratio = imgwidth / containerwidth; var newheight = imgheight / ratio; if(newheight > containerheight){ var newnewheight = containerheight; var newratio = newheight/containerheight; var newnewwidth =newwidth/newratio; theImage.width = newnewwidth; theImage.height= newnewheight; } else{ theImage.width = newwidth; theImage.height= newheight; } } else if(imgheight > containerheight){ var newheight = containerheight; var ratio = imgheight / containerheight; var newwidth = imgwidth / ratio; if(newwidth > containerwidth){ var newnewwidth = containerwidth; var newratio = newwidth/containerwidth; var newnewheight =newheight/newratio; theImage.height = newnewheight; theImage.width= newnewwidth; } else{ theImage.width = newwidth; theImage.height= newheight; } } $image.css({ 'width' :theImage.width, 'height' :theImage.height, 'margin-top' :-(theImage.height/2)-10+'px', 'margin-left' :-(theImage.width/2)-10+'px' });}});

这是它!我们希望您喜欢本教程并发现它有用!

由于Webkit的一些特性,如果你使用像Chrome或Safari这样的Webkit浏览器,这个演示是非常好的体验。它还将在所有最新的浏览器(如Firefox和IE)中完全发挥功能(尽管没有那些漂亮的属性)。

0 阅读:10
智能甄选

智能甄选

技术交流、资源共享,是程序员的网上乐园。