项目的github网址:https://github.com/chenmonkey/Merry-go-round
github在线演示网址:https://chenmonkey.github.io/Merry-go-round/
1-1、DOM结构搭建
<div class="main">
<div class="btu left"><</div>
<ul class="list">
<li class="item"><a href="#"><img src="img/1-1.jpg" width="100%"></a></li>
<li class="item"><a href="#"><img src="img/1-2.jpg" width="100%"></a></li>
<li class="item"><a href="#"><img src="img/1-3.jpg" width="100%"></a></li>
<li class="item"><a href="#"><img src="img/1-4.jpg" width="100%"></a></li>
<li class="item"><a href="#"><img src="img/1-5.jpg" width="100%"></a></li>
</ul>
<div class="btu right">></div>
</div>
1-2、基础css搭建静态展示效果
.main{position:relative;width:700px;height: 166px;}
/*.main a,.main img{display: block;}/*消除li里的a的padding的5px*/*/
.main .list{width:700px;height: 166px;}
.main .list .item{position: absolute;left:0;top:0}
.main .btu{position: absolute;top:0;width:100px;height: 166px;z-index: 10;cursor: pointer;}
.main .left{left:0;background:red url(../img/left.png) no-repeat center center;}
.main .right{right: 0;background:red url(../img/right.png) no-repeat center center;}
1-3、基本JS、JQ开发结构搭建
在index.html中
$(function(){
//Carrousel
//var carrousel=new Carrousel($(".J_Main").eq(0));//获取集合J_Main的第一个
Carrousel.init($(".J_Main"));//传递的J_Main是一个集合
});
在carrousel.js中
//封装插件
;(function($){/*前面加分号是为了规避在之前引入的脚本未封闭报错*/
var Carrousel=function(poster){
alert(poster);
};
Carrousel.prototype={
};
Carrousel.init=function(posters){/*posters加s表示集合*/
var _this_=this;//this指Carrousel
posters.each(function(){
new _this_($(this));//this指posters里的每一个
});
}
window["Carrousel"]=Carrousel;//全局变量注册
})(jQuery);
2-1、需求分析和配置参数设置
<!--节点属性配置参数(封装插件):幻灯片宽度、幻灯片高度、幻灯片第一帧宽度、幻灯片第一高度、图片显示比例关系、轮播速度、是否自动播放、播放间隔时间、上下对齐模式-->
<div class="J_Main main" data-setting='{
"width":700,
"height":166,
"phWidth":540,
"phHeight":166,
"scale":0.9,
"speed":1000,
"autoPlay":true,
"delay":5000,
"verticalAlign":"middle"
}'>
2-2、默认配置参数设置及拓展
//封装插件
;(function($){/*前面加分号是为了规避在之前引入的脚本未封闭报错*/
var Carrousel=function(poster){
//保存单个旋转木马对象
this.poster=poster;
//默认配置参数
this.setting={
"width":700,
"height":166,
"phWidth":540,
"phHeight":166,
"scale":0.9,
"speed":500,
"verticalAlign":"middle"
};
$.extend(this.setting,this.getSetting());//扩展配置参数属性,,第二个对象覆盖第一个对象
console.log(this.setting);//打印出人工配置的参数
};
Carrousel.prototype={
//获取人工配置参数
getSetting:function(){
var setting=this.poster.attr("data-setting");
if(setting&&setting!=""){//表示已有人工配置参数
return $.parseJSON(setting);
}else{
return {};//返回一个空对象
}
}
};
Carrousel.init=function(posters){/*posters加s表示集合*/
var _this_=this;//this指Carrousel
posters.each(function(){
new _this_($(this));//this指posters里的每一个
});
};
window["Carrousel"]=Carrousel;//全局变量注册
})(jQuery);
2-3、设置基本参数值
setSettingValue:function(){
//main区域的宽高
this.poster.css({
width:this.setting.width,
height:this.setting.height
});
//ul区域的宽高
this.itemMain.css({
width:this.setting.width,
height:this.setting.height
});
//计算左右切换按钮宽高
var w=(this.setting.width-this.setting.phWidth)/2;
this.leftBtu.css({
width:w,
height:this.setting.height
});
this.rightBtu.css({
width:w,
height:this.setting.height
});
//计算幻灯片第一帧的位置刚好在左右按钮之间的位置
this.firstItem.css({
left:w
});
},
2-4、按钮和第一帧层级关系设置
2-5、右边帧的位置关系设置
//设置剩余帧的位置关系
setRestPic:function(){
var self=this;
var restItems=this.items.slice(1),//除第一帧之外剩余的图片(长度为4)
averLength=restItems.length/2,//左右两边平均剩余帧数的长度
rightRest=restItems.slice(0,averLength),//右边剩余帧数的长度为2
level=Math.floor(this.items.length/2);//帧层级关系
//设置右边帧的位置关系、宽高、top
var rw=this.setting.phWidth,//右边第一帧宽度
rh=this.setting.phHeight,//右边第一帧高度
gap=((this.setting.width-this.setting.phWidth)/2)/level;//帧与帧之间间隙的宽度
var firstLeft=(this.setting.width-this.setting.phWidth)/2;//第一帧距离左按钮的宽度,即left值
var fixOffsetLeft=firstLeft+rw
rightRest.each(function(i){
level--;
rw=rw*self.setting.scale;//右边每一帧自身宽度
rh=rh*self.setting.scale;//右边每一帧自身高度
var j=i;
$(this).css({
zIndex:level,
width:rw,
height:rh,
opacity:1/(++j),
left:fixOffsetLeft+(++i)*gap-rw,
top:(self.setting.height-rh)/2//幻灯片居中排列
});
})
}
2-6、左边帧的散列关系
//设置左边帧的位置关系 (以右边最后一帧作为比例进行循环)
var lw=rightRest.last().width(),//左边第一帧宽度=右边最后一帧的宽度
lh=rightRest.last().height(),//左边第一帧高度=右边最后一帧的高度
oloop=Math.floor(this.items.length/2);//帧层级关系,为2
leftRest.each(function(i){
$(this).css({
zIndex:level,
width:lw,
height:lh,
opacity:1/oloop,
left:i*gap,
top:(self.setting.height-lh)/2//幻灯片居中排列
});
lw=lw/self.setting.scale;
lh=lh/self.setting.scale;
oloop--;
});
2-7、帧的展示方式
垂直居中:"verticalAlign":"middle"
上对齐:"verticalAlign":"top"
下对齐:"verticalAlign":"bottom"
(1)在rightRest循环中:top:self.setVertucalAlign(rh)//幻灯片居中排列
(2)在leftRest循环中:top:self.setVertucalAlign(lh)//幻灯片居中排列
//设置垂直排列对齐方式
setVertucalAlign:function(height){
var verticalAlign=this.setting.verticalAlign,//保存对齐类型
top=0;
if(verticalAlign==="middle"){
top=(this.setting.height-height)/2;
}else if(verticalAlign==="top"){
top=0;
}else if(verticalAlign==="bottom"){
top=this.setting.height-height;
}else{
top=(this.setting.height-height)/2;
}
return top;
}
修改人工配置的 verticalAlign属性值
2-8、左旋转 所有帧
if(dir==="left"){
this.items.each(function(){
var self=$(this),//当前帧
prev=self.prev().get(0)?self.prev():_this_.lastItem,//当前帧的上一帧,如果上一帧不存在则取最后一帧
width=prev.width(),
height=prev.height(),
zIndex=prev.css("zIndex"),
opacity=prev.css("opacity"),
left=prev.css("left"),
top=prev.css("top");
self.animate({
width:width,
height:height,
zIndex:zIndex,
opacity:opacity,
left:left,
top:top
});
});
2-9、右旋转所有帧(同左旋转)
3-1、解决快速点击多次切换时的bug
//左旋转所有帧的按钮事件
this.leftBtu.click(function(){
if(self.rotateFlag){
self.rotateFlag=false;
self.carrouseRotate("left");//旋转
}
});
self.animate({
width:width,
height:height,
zIndex:zIndex,
opacity:opacity,
left:left,
top:top
},function(){
_this_.rotateFlag=true;
});
3-2、自动播放幻灯片
(1)播放速度
(2)自动播放
//执行自动播放功能
autoPlay:function(){
var self=this;
window.setInterval(function(){
self.leftBtu.click();
},this.setting.delay);
}
(3)当鼠标放在幻灯片上时,清除自动播放
this.poster.hover(function(){
window.clearInterval(self.timer);
},function(){
self.autoPlay();
});
(4)偶数帧的解决方案
克隆第一张幻灯片,将它放在最后
/*若幻灯片是偶数个,则克隆第一张幻灯片,将它放置最后*/
if(this.items.length%2==0){
this.itemMain.append(this.items.eq(0).clone());
this.items=this.itemMain.children();
}