在本教程中,我们将创建一个漂亮的和新鲜的图像库。这个想法是将相册显示为一个滑动器,当选择一个相册时,我们会将相册的图片显示为一个漂亮的照片堆栈。在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)中完全发挥功能(尽管没有那些漂亮的属性)。