在网上看到了一个仿3D的轮播效果。很有意思,就模仿做了一下。
原示例可以参考 http://www.jq22.com/jquery-info20579
jq22这个例子是用jQuery写的。我这里就用原生态JS写一次。采用面向对象的思路来写。
整体思路就是:
1、结合CSS3实现两边图片的倾斜和图片轮转的动画
2、JS只负责增加和删除类。
从“顶部”看这个轮播图,示例如下:分别用三个类代表图片的关键三个位置current,prev,next。没有类的,就在current图片的后面。
HTML结构:注意,内容图片的大小肯定是一样的
<div class="pic3DBox" id="pic3DBox">
<!--图片部分-->
<ul>
<li><a href="#"><img src="temp/yys_banner1.jpg" alt=""></a></li>
<li><a href="#"><img src="temp/yys_banner2.jpg" alt=""></a></li>
<li><a href="#"><img src="temp/yys_banner3.jpg" alt=""></a></li>
<li><a href="#"><img src="temp/yys_banner4.jpg" alt=""></a></li>
</ul>
<!--图片部分 end-->
<a href="javascript:void(0)" class="prevBtn" id="pic3DPrev">
<img src="images/banner_left.png">
</a>
<a href="javascript:void(0)" class="nextBtn" id="pic3DNext">
<img src="images/banner_right.png">
</a>
</div>
CSS
*{
margin: 0;
padding: 0;
}
ul,li,ol{
list-style: none;
}
body{
background:#000 url("../temp/yys_bg.jpg") top center no-repeat;
}
/*整个框架*/
.pic3DBox{
width: 1200px;
height: 700px;
margin-left: auto;
margin-right: auto;
position: relative; /*相对定位,让图片能转来转去*/
perspective: 500px;
}
/* 图片部分大小设置 */
.pic3DBox ul li,.pic3DBox ul li a{
width: 720px;
height: 520px;
overflow: hidden;
}
.pic3DBox ul li a{
display: block;
}
}
/* 每张图片都绝对定位 */
.pic3DBox ul li{
position: absolute;
z-index: 1;
transform: scale(0.5,0.5); /* 没有类的图片,都在current的后面,比较小的状态 */
top:50%;
margin-top: -260px; /* 图片位置控制好 */
left:50%;
margin-left: -360px;
transition:all 0.5s; /* 过渡属性,动画就靠它了 */
}
/* 当前图片,大小位置控制好 */
.pic3DBox ul li.current{
left:50%;
margin-left: -360px;
transform:scale(1,1);
z-index: 100;
}
/* 上一张 */
.pic3DBox ul li.prev{
left:0;
margin-left:-72px;
transform:scale(0.5,0.5) rotateY(10deg);
z-index: 50;
}
/* 下一张 */
.pic3DBox ul li.next{
left:624px;
margin-left:-72px;
transform:scale(0.5,0.5) rotateY(-10deg);
z-index: 50;
}
/* 按钮,及其位置 */
.pic3DBox .prevBtn, .pic3DBox .nextBtn{
display: block;
width: 80px;
height: 84px;
background: #f30;
overflow: hidden;
position: absolute;
z-index: 200;
top:50%;
margin-top: -40px;
opacity: 0.5;
transition:all 0.5s;
}
.pic3DBox .prevBtn{
left:0;
}
.pic3DBox .nextBtn{
right:0;
}
/* 按钮的hover 效果*/
.pic3DBox .prevBtn:hover ,.pic3DBox .nextBtn:hover{
opacity: 1;
}
JavaScript部分:
/* 创建3D效果类 */
function Pic3D( obj ){
this.boxId = (obj&&obj.boxId) || "pic3DBox";
this.prevClass =(obj&&obj.prevClass)|| "prev";
this.nextClass = (obj&&obj.nextClass)|| "next";
this.currentClass = (obj&&obj.currentClass) || "current";
this.prevBtn = (obj&&obj.prevBtn) || "pic3DPrev";
this.nextBtn = (obj&&obj.nextBtn) || "pic3DNext";
this.isBtn = (obj&&obj.isBtn) || true; // 是否允许有按钮
}
// 初始化方法
Pic3D.prototype.init = function(){
// 初始化相关标签
var _this = this;
_this.boxEle = document.getElementById( _this.boxId );
_this.ul = _this.boxEle.getElementsByTagName("ul")[0];
_this.liEles = _this.boxEle.getElementsByTagName("li");
if( !!_this.isBtn){
_this.prevEle = document.getElementById( _this.prevBtn );
_this.nextEle = document.getElementById( _this.nextBtn );
}
// 初始化当前展示图片序号
_this.nowp = 0 ;
_this.addEvents(); // 给标签添加事件
};
// 添加事件方法
Pic3D.prototype.addEvents = function(){
var _this = this;
var i = 0 ;
var lis = _this.liEles;
// 如果 图片个数少于3个,克隆出来,凑足3个
if( lis.length < 3 ){
for(var k = 0 ; k <= 3-lis.length; k++){
var newLi = lis[0].cloneNode(true);
_this.ul.appendChild( newLi );
}
_this.liEles = _this.boxEle.getElementsByTagName("li"); // 重新获取 li
lis = _this.liEles;
}
// 初始化class
lis[0].className = _this.currentClass;
lis[1].className = _this.nextClass;
lis[lis.length-1].className = _this.prevClass;
// 遍历 i 标签
for( i=0 ; i <= lis.length-1 ; i++){
lis[i].index = i; // 给每个图片一个索引
lis[i].onclick = function(e){ // 给每个图片添加点击事件
var el = this;
var n = el.index;
_this.nowp = n;
// 如果图片上有指定的类,就阻止默认事件,不要跳转页面。
if( el.className === _this.nextClass || el.className === _this.prevClass ){
e.preventDefault();
}
_this.showPic(n); // 展示第n张图
}
}
// 按钮事件
if( !!_this.isBtn){
_this.prevEle.onclick = function(e){
var el = this; // 防止跟对象的 this 搞混。
var n = _this.nowp; // 当前要展示的图片的索引
n--;
if( n < 0 ){
n= lis.length-1;
}
_this.showPic(n); // 展示第n张图
_this.nowp = n;
};
_this.nextEle.onclick = function(e){
var el = this; // 防止跟对象的 this 搞混。
var n = _this.nowp; // 当前要展示的图片的索引
n++;
if( n >= lis.length ){
n=0;
}
_this.showPic(n); // 展示第n张图
_this.nowp = n;
};
}
};
// 图片展示方法。本质就是给标签增加类,删除类。
Pic3D.prototype.showPic = function(n){
console.info(n);
var _this = this;
var lis = _this.liEles;
var nextLi,prevLi;
if( n === lis.length-1 ){
nextLi = 0;
}else{
nextLi = n + 1;
}
if( n === 0 ){
prevLi = lis.length - 1;
}else{
prevLi = n-1;
}
for(var i=0 ; i<=lis.length-1 ; i++){
lis[i].className = "";
}
lis[n].className = _this.currentClass;
lis[nextLi].className = _this.nextClass;
lis[prevLi].className = _this.prevClass;
};
var mypic = new Pic3D();
mypic.init({
boxId:"pic3DBox",
prevClass:"prev",
nextClass:"next",
currentClass:"current",
prevBtn:"pic3DPrev",
nextBtn:"pic3DNext",
isBtn:true
});