仿3D效果的图片轮播

在网上看到了一个仿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
});
发布了73 篇原创文章 · 获赞 97 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_42703239/article/details/91395409