• 分享一个用原生JavaScript写的带缓动效果的图片幻灯


      朋友让帮忙找个原生JS写的带缓动效果的图片幻灯,类似Tmall首页的效果,找了一圈后发现网上JS写的图片幻灯很多,相关的jQuery插件也很多,但用原生JS写的带缓动效果的却不多。没办法只好自己动手,现在把代码分享给大家,希望对大家有用。

      代码中的缓动公式用了司徒正美博客中整理的代码:http://www.cnblogs.com/rubylouvre/archive/2009/09/17/1567607.html

      缓动公式的推导主要利用了物理中的加速度知识,推荐过程可以看看这篇文章:http://floatyears.info/javascript-animation-easing

      HTML部分:

    <div id="J-Slide">
        <ul class="JSlide-list">
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_01.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_02.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_03.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_04.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_05.jpg" alt=""/></li>
        </ul>
        <ul class="JSlide-num">
            <li class="current">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
        </ul>
        <div class="JSlide-mask"></div>
    </div>

      这部分比较简单,跟Tmall首页效果一样,几张图片,左下角是图片索引,并有一个半透明的遮罩层。

      CSS部分:

    body,ul,li{
        margin:0;
        padding:0;
    }
    ul{
        list-style:none;
    }
    #J-Slide{
        width:600px;
        height:400px;
        position:relative;
        margin:50px auto;
        overflow:hidden;
    }
    #J-Slide .JSlide-list{
        position:absolute;
        width:3000px;
        left:0;
        top:0;
    }
    #J-Slide .JSlide-list li{
        float:left;
    }
    #J-Slide .JSlide-list li img{
        width:600px;
        height:400px;
    }
    #J-Slide .JSlide-num{
        position:absolute;
        left:0;
        bottom:0;
        height:30px;
        padding:5px;
        width:100%;
        z-index:10;
    }
    #J-Slide .JSlide-num li{
        width:30px;
        height:30px;
        margin-left:10px;
        float:left;
        font-size:16px;
        color:white;
        background:#716584;
        line-height:30px;
        text-align:center;
        cursor:pointer;
        border-radius:15px;
    }
    #J-Slide .JSlide-mask{
        position:absolute;
        left:0;
        background:black;
        bottom:0;
        width:100%;
        height:40px;
        opacity:0.3;
        filter:Alpha(opacity = 30);
        z-index:1;
    }
    #J-Slide .JSlide-num .current{
        background:#B91919;
    }

      CSS部分比较简单,直接用absolute定位。

      JavaScript库部分:

    (function(){
        /*
        *参数说明:
        *id 必须
        *picwidth 可选
        *speed 可选
        *
        *作者:artwl
        *出处:http://artwl.cnblogs.com
        */
        var JCP_Slide=function(id,picwidth,speed){
            if(!(this instanceof JCP_Slide))
                return new JCP_Slide(id,picwidth,speed);
            var obj=document.getElementById(id),
                childs=obj.getElementsByTagName("ul");
            this.author="artwl";
            this.jslideList=childs[0];
            this.jslideNums=childs[1].children;
            this.speed= speed || 5000;
            this.picwidth= picwidth || (obj.currentStyle ? parseFloat(obj.currentStyle.width) : parseFloat(document.defaultView.getComputedStyle(obj,null).width));
            this.currentIndex=0;
            this.distance=this.picwidth;
            this.currentLeftPos=0;
            this.runHandle=null;
            this.len=this.jslideNums.length;
        }
    
        JCP_Slide.prototype={
            bindMouse:function(){
                var self=this;
                for(var i=0;i<this.len;i++){
                    this.jslideNums[i].onmouseover=(function(index){
                        return function(){
                            self.currentIndex=index;
                            clearInterval(self.runHandle);
                            var prev=-1;
                            for(var k=0;k<self.len;k++){
                                if(self.jslideNums[k].className === "current")
                                    prev = k;
                                self.jslideNums[k].className = k === index ? "current" : "" ;
                            }
                            if(prev != index){
                                self.distance=(prev - index)*self.picwidth;
                                self.currentLeftPos = -prev * self.picwidth;
                                self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc})
                            }
                        }
                    })(i);
                    this.jslideNums[i].onmouseout=function(){
                        self.autoRun();
                    }
                }
            },
            autoRun:function(){
                var self=this;
                this.runHandle=setInterval(function(){
                    self.distance=-self.picwidth;
                    for(var k=0;k<self.len;k++){
                        self.jslideNums[k].className = "" ;
                    }
                    self.currentIndex++;
                    self.currentIndex%=5;
                    self.jslideNums[self.currentIndex].className = "current";
                    self.currentLeftPos = -(self.currentIndex-1) * self.picwidth;
                    if(self.currentIndex == 0){
                        self.distance = (self.len-1)*self.picwidth;
                        self.currentLeftPos = -self.distance;
                    }
                    self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc});
                },self.speed);
            },
            easeOutCirc:function(pos){
                return Math.sqrt(1 - Math.pow((pos-1), 2))
            },
            transition:function(el){
                el.style.position = "absolute";
                var options = arguments[1] || {},
                begin =  options.begin,//开始位置
                change = options.change,//变化量
                duration = options.duration || 500,//缓动效果持续时间
                field = options.field,//必须指定,基本上对top,left,width,height这个属性进行设置
                ftp = options.ftp || 50,
                onStart = options.onStart || function(){},
                onEnd = options.onEnd || function(){},
                ease = options.ease,//要使用的缓动公式
                end = begin + change,//结束位置
                startTime = new Date().getTime();//开始执行的时间
                onStart();
                (function(){
                    setTimeout(function(){
                        var newTime = new Date().getTime(),//当前帧开始的时间
                        timestamp = newTime - startTime,//逝去时间
                        delta = ease(timestamp / duration);
                        el.style[field] = Math.ceil(begin + delta * change) + "px";
                        if(duration <= timestamp){
                            el.style[field] = end + "px";
                            onEnd();
                        } else {
                            setTimeout(arguments.callee,1000/ftp);
                        }
                    },1000/ftp);
                })();
            },
            play:function(){
                this.bindMouse();
                this.autoRun();
            }
        };
    
        window.JCP_Slide=JCP_Slide;
    })();

      这个JS库是核心,入口有三个参数,第一个是最外层的div的id(必须),第二个参数是图片宽度(可选),默认为最外层DIV宽度,第三个参数为自动切换的时间间隔(可选),默认为5秒。

      bindMouse是绑定鼠标的悬浮和移出事件,autoRun是让图片正动切换,play方法调用了这两个方法。

      easeOutCirc是一个先快后慢的缓动公式,transition是缓动函数,这两个方法的用法请参考 司徒正美 的博客:http://www.cnblogs.com/rubylouvre/archive/2009/09/17/1567607.html

      调用示例:

    window.onload=function(){
        JCP_Slide("J-Slide").play();
    };

      完整代码为:

    View Code
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8"/>
        <title> New Document </title>
        <style type="text/css">
            body,ul,li{
                margin:0;
                padding:0;
            }
            ul{
                list-style:none;
            }
            #J-Slide{
                width:600px;
                height:400px;
                position:relative;
                margin:50px auto;
                overflow:hidden;
            }
            #J-Slide .JSlide-list{
                position:absolute;
                width:3000px;
                left:0;
                top:0;
            }
            #J-Slide .JSlide-list li{
                float:left;
            }
            #J-Slide .JSlide-list li img{
                width:600px;
                height:400px;
            }
            #J-Slide .JSlide-num{
                position:absolute;
                left:0;
                bottom:0;
                height:30px;
                padding:5px;
                width:100%;
                z-index:10;
            }
            #J-Slide .JSlide-num li{
                width:30px;
                height:30px;
                margin-left:10px;
                float:left;
                font-size:16px;
                color:white;
                background:#716584;
                line-height:30px;
                text-align:center;
                cursor:pointer;
                border-radius:15px;
            }
            #J-Slide .JSlide-mask{
                position:absolute;
                left:0;
                background:black;
                bottom:0;
                width:100%;
                height:40px;
                opacity:0.3;
                filter:Alpha(opacity = 30);
                z-index:1;
            }
            #J-Slide .JSlide-num .current{
                background:#B91919;
            }
        </style>
        <script>
            (function(){
                /*
                *参数说明:
                *id 必须
                *picwidth 可选
                *speed 可选
                *
                *作者:artwl
                *出处:http://artwl.cnblogs.com
                */
                var JCP_Slide=function(id,picwidth,speed){
                    if(!(this instanceof JCP_Slide))
                        return new JCP_Slide(id,picwidth,speed);
                    var obj=document.getElementById(id),
                        childs=obj.getElementsByTagName("ul");
                    this.author="artwl";
                    this.jslideList=childs[0];
                    this.jslideNums=childs[1].children;
                    this.speed= speed || 5000;
                    this.picwidth= picwidth || (obj.currentStyle ? parseFloat(obj.currentStyle.width) : parseFloat(document.defaultView.getComputedStyle(obj,null).width));
                    this.currentIndex=0;
                    this.distance=this.picwidth;
                    this.currentLeftPos=0;
                    this.runHandle=null;
                    this.len=this.jslideNums.length;
                }
    
                JCP_Slide.prototype={
                    bindMouse:function(){
                        var self=this;
                        for(var i=0;i<this.len;i++){
                            this.jslideNums[i].onmouseover=(function(index){
                                return function(){
                                    self.currentIndex=index;
                                    clearInterval(self.runHandle);
                                    var prev=-1;
                                    for(var k=0;k<self.len;k++){
                                        if(self.jslideNums[k].className === "current")
                                            prev = k;
                                        self.jslideNums[k].className = k === index ? "current" : "" ;
                                    }
                                    if(prev != index){
                                        self.distance=(prev - index)*self.picwidth;
                                        self.currentLeftPos = -prev * self.picwidth;
                                        self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc})
                                    }
                                }
                            })(i);
                            this.jslideNums[i].onmouseout=function(){
                                self.autoRun();
                            }
                        }
                    },
                    autoRun:function(){
                        var self=this;
                        this.runHandle=setInterval(function(){
                            self.distance=-self.picwidth;
                            for(var k=0;k<self.len;k++){
                                self.jslideNums[k].className = "" ;
                            }
                            self.currentIndex++;
                            self.currentIndex%=5;
                            self.jslideNums[self.currentIndex].className = "current";
                            self.currentLeftPos = -(self.currentIndex-1) * self.picwidth;
                            if(self.currentIndex == 0){
                                self.distance = (self.len-1)*self.picwidth;
                                self.currentLeftPos = -self.distance;
                            }
                            self.transition(self.jslideList,{field:'left',begin:self.currentLeftPos,change:self.distance,ease:self.easeOutCirc});
                        },self.speed);
                    },
                    easeOutCirc:function(pos){
                        return Math.sqrt(1 - Math.pow((pos-1), 2))
                    },
                    transition:function(el){
                        el.style.position = "absolute";
                        var options = arguments[1] || {},
                        begin =  options.begin,
                        change = options.change,
                        duration = options.duration || 500,
                        field = options.field,
                        ftp = options.ftp || 50,
                        onStart = options.onStart || function(){},
                        onEnd = options.onEnd || function(){},
                        ease = options.ease,
                        end = begin + change,
                        startTime = new Date().getTime();
                        onStart();
                        (function(){
                            setTimeout(function(){
                                var newTime = new Date().getTime(),
                                timestamp = newTime - startTime,
                                delta = ease(timestamp / duration);
                                el.style[field] = Math.ceil(begin + delta * change) + "px";
                                if(duration <= timestamp){
                                    el.style[field] = end + "px";
                                    onEnd();
                                } else {
                                    setTimeout(arguments.callee,1000/ftp);
                                }
                            },1000/ftp);
                        })();
                    },
                    play:function(){
                        this.bindMouse();
                        this.autoRun();
                    }
                };
    
                window.JCP_Slide=JCP_Slide;
            })();
    
            window.onload=function(){
                JCP_Slide("J-Slide").play();
            };
        </script>
    </head>
    <body>
    <div id="J-Slide">
        <ul class="JSlide-list">
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_01.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_02.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_03.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_04.jpg" alt=""/></li>
            <li><img src="http://images.cnblogs.com/cnblogs_com/artwl/357654/o_05.jpg" alt=""/></li>
        </ul>
        <ul class="JSlide-num">
            <li class="current">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
        </ul>
        <div class="JSlide-mask"></div>
    </div>
    </body>
    </html>

      运行效果:

    • 1
    • 2
    • 3
    • 4
    • 5
     
  • 相关阅读:
    PHPCMS 商品浏览记录及其遇到的问题
    9月10日
    phpcms v9 数据库操作函数
    html Meta (整合)
    不同内核浏览器的差异以及浏览器渲染(转)
    position属性absolute与relative(转载)
    html规范,某人总结
    切图神器Assistor PS(PS外挂神器,亲证免费可用,下面是转载的使用方法)
    Android开发学习笔记:圆角的Button
    sublime text 2 技巧
  • 原文地址:https://www.cnblogs.com/artwl/p/2673649.html
Copyright © 2020-2023  润新知