使用jQuery,HTML5,CSS3制作一个中间顶层最大,两端逐渐变淡、变小的轮播图
先上效果图
实现原理
只需要计算出几个参数,那么各个盒子的大小、位置、透明度这些就都能解决了
1. 整个容器的高度:对大小不一的盒子进行绝对定位,垂直居中显示
2.中间盒子相对于容器的偏移 left :计算左右两边盒子的水平位置,也是用绝对定位 left 来做
3.盒子之间露出来部分宽度:计算左右两边盒子的水平位置,每个盒子到底有多宽的距离能显示
4.一个比例,0 到 1 之间:根据这个比例计算左右两边的盒子相对于中间盒子的大小、透明度;比例大一点,两边盒子就大一点,透明度就低一点。
想一下:左右两边盒子的索引减去中间盒子的索引的绝对值var n = Math.abs(midIndex - LRIndex);
越是靠近左边或者右边,那么 n 值就越大,比如设定一个比例var rate = 0.8;
在对 rate 进行 n 次幂运算var r = Math.pow(rate,n).toFixed(2)
,如果n
越大那么得到的 r
的值越小,toFixed(2)
是取两位小数,为了方便一点。那么左右两边盒子的大小和透明度都根据r
值来计算,是不是对应了越往左边或者右边盒子越小,不透明度越小。
上源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>中间对齐层叠轮播图</title>
<style type="text/css">
body{
margin: 0;
background-color: #EEEEEE;
}
.container{
width: 1000px;
height: 500px;
border: 1px solid crimson;
margin: 50px auto;
position: relative;
}
.content{
font-size: 100px;
text-align: center;
color: #EEEEEE;
position: absolute;
user-select: none;
transition: all 0.5s;
}
</style>
</head>
<body>
<div class="container">
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
<div class="content">4</div>
<div class="content">5</div>
<div class="content">6</div>
<div class="content">7</div>
<div class="content">8</div>
<div class="content">9</div>
</div>
<script src="../jQuery1.11.0.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var middleRotate = (function($,window){
var container = $('.container');//最外层容器
var containerHeight = container.height();//最外层盒子的高度
var contents = container.find('.content');//需要轮换的盒子
var mid = Math.floor(contents.length / 2);//中间的那个盒子
/* 修改rate值和distance值,再看看效果,你会明白很多 */
var rate = 0.9; //盒子进行大小变化,透明度变化的比率基数
var distance = 60; //两个盒子层叠之后露出来的宽度
//中间盒子的样式
var middleStyle = {
width: '300px',
height: '400px',
lineHeight: '400px',
top: '50px',
left: '350px',
opacity : 1,
zIndex: 20,
backgroundColor: 'indigo'
};
var midWidth = 300;//这三个变量都是根据middleStyle的值来设置
var midHeight = 400;
var midLeft = 350;
var timer = null;//设置一个自动轮换的定时器
var intervalTime = 3000;//自动轮换的间隔时间
//对盒子进行排序的函数
function order()
{
contents = container.find('.content'); //顺序变化之后要重新获取
/**
* 在函数开始就给中间位置的盒子设置样式
* 其他左右两边的盒子都是根据中间盒子的属性来计算自己的位置
*/
contents.eq(mid).css(middleStyle);
//遍历contents设置每一个盒子的样式
$.map(contents,function(value,index){
var n = Math.abs(mid-index),// n 值就相当于当前盒子在中间盒子旁边第几个
r = Math.pow(rate,n).toFixed(2),// r 值为当前盒子相对于中间盒子的大小、透明度的比例
posLeft = 0;//当前盒子应该在哪里
if(index !== mid)
{
/*
注意:
这里要先将当前value计算出来的宽度和高度储存下来,
是因为需要防止 transition-duration的执行时间没有完成,
使用$(value).width()/height()无法获取到正确的宽度和高度
*/
var valueHeight = r * midHeight,//当前盒子的宽高根据 r 值相对于中间盒子来计算
valueWidth = r * midWidth;
if(index < mid) { //在中间盒子的左边
posLeft = midLeft - n*distance;
} else if(index > mid) {//在中间盒子的右边
posLeft = midLeft + midWidth + n*distance - valueWidth;
}
$(value).css({
width : valueWidth + 'px',
height : valueHeight + 'px',
lineHeight : valueHeight+'px',
left : posLeft+'px',
top : (containerHeight - valueHeight) / 2 +'px',//根据容器的高度进行垂直居中 top 值的计算
zIndex : index>mid ? 20-index : index,
opacity : Math.pow(r,n).toFixed(2),//这里直接使用 r 也没有问题,只是直接使用 r ,透明度变化不明显,所以再进行一次幂运算
backgroundColor : '#'+Math.floor(Math.random()*100000+900000)//随机一个颜色,没什么作用,只是为了方便查看
});
}
});
}
//添加事件函数
function addEvent()
{
//移入外层容器,轮播图暂停,移出继续轮播
container.hover(function(){
clearInterval(timer);
},function(){
autoPlay();
});
//点击左右两边的盒子,将其显示在中间
contents.on('click',function(){
var index = $(this).index();
//如果点击的是中间的盒子就不用再重新排序了
if(index === mid) {
return;
}
/*
点击时将被点击的盒子放到中间
点击左边盒子时,后面的盒子往前排
点击右边盒子时,前面的盒子往后排
*/
if(index < mid) {
for (var i = 0; i < mid-index; i++) {
container.prepend(contents.eq(contents.length-1-i));
}
} else if(index > mid) {
for (var i = 0; i < index-mid; i++) {
container.append(contents.eq(i));
}
}
//每点击一次就要重新排序
order();
});
}
//自动轮换函数
function autoPlay() {
timer = setInterval(function(){
contents.eq(mid+1).click();
},intervalTime);
}
function init(){
order();
addEvent();
autoPlay();
}
return init;
}(jQuery,window));
middleRotate();
</script>
</body>
</html>