• js瀑布流效果


    js瀑布流效果,宽度自适应,当滚动条滚动到一定的位置按需要加载更多图片,

    把最新取得的图片动态从中间散开铺向应有的位置。

    一打开网页,刷新的效果,当浏览器窗口宽度只能容纳三张图片的时候:

    当浏览器窗口宽度可以容纳4张图片的时候:

    js瀑布流效果制作分析

    (附件)

    完整代码:

    <!--
    Author: XiaoWen
    Create a file: 2016-12-06 14:56:55
    Last modified: 2017-01-12 18:29:28
    Start to work:
    Finish the work:
    Other information:
    -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>瀑布流</title>
      <script src="js/tween.js"></script>
      <script src="js/time_move.js"></script>
      <style>
        *{
          margin: 0;
          padding: 0;
        }
        img{
          border: none;
          width: 220px;
          vertical-align: bottom;
          border-radius:8px;
          box-shadow:0 0 8px #ccc;
          margin: 10px;
          padding: 10px;
        }
        #box{
          position: relative;
          margin:20px auto 0;
        }
        .nv{
          float: left;
          position: absolute;
        }
      </style>
    </head>
    <body>
    <div id="box">
      <div class="nv"><img src="img/1.jpg"></div>
      <div class="nv"><img src="img/2.jpg"></div>
      <div class="nv"><img src="img/3.jpg"></div>
      <div class="nv"><img src="img/4.jpg"></div>
      <div class="nv"><img src="img/5.jpg"></div>
      <div class="nv"><img src="img/6.jpg"></div>
      <div class="nv"><img src="img/7.jpg"></div>
      <div class="nv"><img src="img/8.jpg"></div>
      <div class="nv"><img src="img/9.jpg"></div>
      <div class="nv"><img src="img/10.jpg"></div>
      <div class="nv"><img src="img/11.jpg"></div>
      <div class="nv"><img src="img/12.jpg"></div>
      <div class="nv"><img src="img/13.jpg"></div>
      <div class="nv"><img src="img/14.jpg"></div>
      <div class="nv"><img src="img/15.jpg"></div>
      <div class="nv"><img src="img/16.jpg"></div>
      <div class="nv"><img src="img/17.jpg"></div>
      <div class="nv"><img src="img/18.jpg"></div>
      <div class="nv"><img src="img/19.jpg"></div>
      <div class="nv"><img src="img/20.jpg"></div>
    </div>
    <script>
    window.onload=function(){
    
    //////// 布局
      var yx=document.documentElement.clientWidth;
      var yz=document.documentElement.clientHeight;
      var xw=260; //图片宽度
      var oImgw=220; //图片实际宽度
      var num=Math.floor(yx/xw); //把可视区域的宽/图片宽度=该有几张图 ,不足1张时向下取整
      var amet=box.getElementsByTagName('div');
      box.style.width=xw*num+'px';
      var n=[]; //保存第一行第张图片的高度
      for(var i=0;i<amet.length;i++){
        if(i<num){ //第一行
          amet[i].style.top=0;
          amet[i].style.left=i*xw+'px'; //下标*宽度
          n.push(amet[i].offsetHeight); //保存到数组
        }else{
          var iMin=Math.min.apply(false,n); //获取所有图片中的最小高度
          m=getkey(n,iMin); //返回最小值的下标
          amet[i].style.top=iMin+'px'; //下一张的top=高度最小的那张图片的高度
          amet[i].style.left=(m*xw)+'px'; //下一张的位置=高度最小的那张图片的下标*他的宽度
          n[m]+=amet[i].offsetHeight;
          //把新加上的图片和之前最高度小的图片,让他们两张的高度加起来
          //用这样的方式把最小值改变,否则每次取到的最小值都是一样的
        }
      }
      function getkey(a,b){
        var ikey=0;
        for(var i=0;i<a.length;i++){
          if(a[i]==b){
            ikey=i;
            break
          }
        }
        return ikey
      }
    
    //////// 滚动加载
      var bopen=true; //运行结束才进行请求
      window.onscroll=function(){
        var yy=document.documentElement.scrollTop||document.body.scrollTop;
        var olist=amet[amet.length-1]; //最后一张图片
        //当上次运行结束,并用当页面滚动到最后一张图高度的一半以上才开始加载
        if(bopen&&yy+yz>olist.offsetHeight/2+olist.offsetTop){
          bopen=false;
          var xhr=new XMLHttpRequest();;
          xhr.open('get','waterfall.php',true);
          xhr.send();
          xhr.onreadystatechange=function(){
            if(xhr.readyState==4&&xhr.status==200){
              var alist=JSON.parse(xhr.responseText); //获取数据,转换text为json
              for(var i=0;i<alist.length;i++){ //获取每个对象
                var iMin=Math.min.apply(false,n); //获取最小数
                var m=getkey(n,iMin); //最小数在数组中的下标
                var oImg=document.createElement('img'); //创建img标签
                oImg.src=alist[i].url;
                oImg.style.height=oImgw/alist[i].width*alist[i].height;
                var op=document.createElement('div');
                op.className='nv';
                op.appendChild(oImg); //把 img 插入 div 中
                box.appendChild(op); //把 div 插入 #box
                op.style.top=yz+yy+'px';
                op.style.left=(yz-xw)/2+'px';
                //////// 让合并到一起的对象对象从四周散开
                timeMove(op,{
                  left:m*xw,
                  top:iMin
                },Tween.Sine.easeOut,1000);
                n[m]+=op.offsetHeight;
              }
              bopen=true; //运动完成
            }
          }
        }
      }
    }
    </script>
    </body>
    </html>

    动作插件1

    js/Tween.js

    /*Tween动画算法,来源于FLASH中的ActionScript Tween类
    命名空间Tween
    整理:CJ(挂个名)
    参数说明
    curTime:当前时间,即动画已经进行了多长时间,开始时间为0
    start:开始值
    dur:动画持续多长时间
    alter:总的变化量
    
    Elastic中的参数
    extent:正弦波的幅度
    cycle:正弦波的周期
    
    Back中的s,过冲量,此处数值越大,过冲越大
    
    相对应的下面还分easeIn,easeOut,easeInOut方法
    easeIn() 加速度运动,初始速度为0
    easeOut() 减速度运动,结束速度为0
    easeInOut() 先加速后减速,开始与结束时速度都为0
    具体参见ActionScript 3.0 语言和组件参考   
    */
    var Tween = {
        Linear:function (start,alter,curTime,dur) {return start+curTime/dur*alter;},//最简单的线性变化,即匀速运动
        Quad:{//二次方缓动
            easeIn:function (start,alter,curTime,dur) {
                return start+Math.pow(curTime/dur,2)*alter;
            },
            easeOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur;
                return start-(Math.pow(progress,2)-2*progress)*alter;
            },
            easeInOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur*2;
                return (progress<1?Math.pow(progress,2):-((--progress)*(progress-2) - 1))*alter/2+start;
            }
        },
        Cubic:{//三次方缓动
            easeIn:function (start,alter,curTime,dur) {
                return start+Math.pow(curTime/dur,3)*alter;
            },
            easeOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur;
                return start-(Math.pow(progress,3)-Math.pow(progress,2)+1)*alter;
            },
            easeInOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur*2;
                return (progress<1?Math.pow(progress,3):((progress-=2)*Math.pow(progress,2) + 2))*alter/2+start;
            }
        },
        Quart:{//四次方缓动
            easeIn:function (start,alter,curTime,dur) {
                return start+Math.pow(curTime/dur,4)*alter;
            },
            easeOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur;
                return start-(Math.pow(progress,4)-Math.pow(progress,3)-1)*alter;
            },
            easeInOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur*2;
                return (progress<1?Math.pow(progress,4):-((progress-=2)*Math.pow(progress,3) - 2))*alter/2+start;
            }
        },
        Quint:{//五次方缓动
            easeIn:function (start,alter,curTime,dur) {
                return start+Math.pow(curTime/dur,5)*alter;
            },
            easeOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur;
                return start-(Math.pow(progress,5)-Math.pow(progress,4)+1)*alter;
            },
            easeInOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur*2;
                return (progress<1?Math.pow(progress,5):((progress-=2)*Math.pow(progress,4) +2))*alter/2+start;
            }
        },
        Sine :{//正弦曲线缓动
            easeIn:function (start,alter,curTime,dur) {
                return start-(Math.cos(curTime/dur*Math.PI/2)-1)*alter;
            },
            easeOut:function (start,alter,curTime,dur) {
                return start+Math.sin(curTime/dur*Math.PI/2)*alter;
            },
            easeInOut:function (start,alter,curTime,dur) {
                return start-(Math.cos(curTime/dur*Math.PI/2)-1)*alter/2;
            }
        },
        Expo: {//指数曲线缓动
            easeIn:function (start,alter,curTime,dur) {
                return curTime?(start+alter*Math.pow(2,10*(curTime/dur-1))):start;
            },
            easeOut:function (start,alter,curTime,dur) {
                return (curTime==dur)?(start+alter):(start-(Math.pow(2,-10*curTime/dur)+1)*alter);
            },
            easeInOut:function (start,alter,curTime,dur) {
                if (!curTime) {return start;}
                if (curTime==dur) {return start+alter;}
                var progress =curTime/dur*2;
                if (progress < 1) {
                    return alter/2*Math.pow(2,10* (progress-1))+start;
                } else {
                    return alter/2* (-Math.pow(2, -10*--progress) + 2) +start;
                }
            }
        },
        Circ :{//圆形曲线缓动
            easeIn:function (start,alter,curTime,dur) {
                return start-alter*Math.sqrt(-Math.pow(curTime/dur,2));
            },
            easeOut:function (start,alter,curTime,dur) {
                return start+alter*Math.sqrt(1-Math.pow(curTime/dur-1));
            },
            easeInOut:function (start,alter,curTime,dur) {
                var progress =curTime/dur*2;
                return (progress<1?1-Math.sqrt(1-Math.pow(progress,2)):(Math.sqrt(1 - Math.pow(progress-2,2)) + 1))*alter/2+start;
            }
        },
        Elastic: {//指数衰减的正弦曲线缓动
            easeIn:function (start,alter,curTime,dur,extent,cycle) {
                if (!curTime) {return start;}
                if ((curTime==dur)==1) {return start+alter;}
                if (!cycle) {cycle=dur*0.3;}
                var s;
                if (!extent || extent< Math.abs(alter)) {
                    extent=alter;
                    s = cycle/4;
                } else {s=cycle/(Math.PI*2)*Math.asin(alter/extent);}
                return start-extent*Math.pow(2,10*(curTime/dur-1)) * Math.sin((curTime-dur-s)*(2*Math.PI)/cycle);
            },
            easeOut:function (start,alter,curTime,dur,extent,cycle) {
                if (!curTime) {return start;}
                if (curTime==dur) {return start+alter;}
                if (!cycle) {cycle=dur*0.3;}
                var s;
                if (!extent || extent< Math.abs(alter)) {
                    extent=alter;
                    s =cycle/4;
                } else {s=cycle/(Math.PI*2)*Math.asin(alter/extent);}
                return start+alter+extent*Math.pow(2,-curTime/dur*10)*Math.sin((curTime-s)*(2*Math.PI)/cycle);
            },
            easeInOut:function (start,alter,curTime,dur,extent,cycle) {
                if (!curTime) {return start;}
                if (curTime==dur) {return start+alter;}
                if (!cycle) {cycle=dur*0.45;}
                var s;
                if (!extent || extent< Math.abs(alter)) {
                    extent=alter;
                    s =cycle/4;
                } else {s=cycle/(Math.PI*2)*Math.asin(alter/extent);}
                var progress = curTime/dur*2;
                if (progress<1) {
                    return start-0.5*extent*Math.pow(2,10*(progress-=1))*Math.sin( (progress*dur-s)*(2*Math.PI)/cycle);
                } else {
                    return start+alter+0.5*extent*Math.pow(2,-10*(progress-=1)) * Math.sin( (progress*dur-s)*(2*Math.PI)/cycle);
                }
            }
        },
        Back:{
            easeIn: function (start,alter,curTime,dur,s){
                if (typeof s == "undefined") {s = 1.70158;}
                return start+alter*(curTime/=dur)*curTime*((s+1)*curTime - s);
            },
            easeOut: function (start,alter,curTime,dur,s) {
                if (typeof s == "undefined") {s = 1.70158;}
                return start+alter*((curTime=curTime/dur-1)*curTime*((s+1)*curTime + s) + 1);
            },
            easeInOut: function (start,alter,curTime,dur,s){
                if (typeof s == "undefined") {s = 1.70158;}
                if ((curTime/=dur/2) < 1) {
                    return start+alter/2*(Math.pow(curTime,2)*(((s*=(1.525))+1)*curTime- s));
                }
                return start+alter/2*((curTime-=2)*curTime*(((s*=(1.525))+1)*curTime+ s)+2);
            }
        },
        Bounce:{
            easeIn: function(start,alter,curTime,dur){
                return start+alter-Tween.Bounce.easeOut(0,alter,dur-curTime,dur);
            },
            easeOut: function(start,alter,curTime,dur){
                if ((curTime/=dur) < (1/2.75)) {
                    return alter*(7.5625*Math.pow(curTime,2))+start;
                } else if (curTime < (2/2.75)) {
                    return alter*(7.5625*(curTime-=(1.5/2.75))*curTime + .75)+start;
                } else if (curTime< (2.5/2.75)) {
                    return alter*(7.5625*(curTime-=(2.25/2.75))*curTime + .9375)+start;
                } else {
                    return alter*(7.5625*(curTime-=(2.625/2.75))*curTime + .984375)+start;
                }
            },
            easeInOut: function (start,alter,curTime,dur){
                if (curTime< dur/2) {
                    return Tween.Bounce.easeIn(0,alter,curTime*2,dur) *0.5+start;
                } else {
                    return Tween.Bounce.easeOut(0,alter,curTime*2-dur,dur) *0.5 + alter*0.5 +start;
                }
            }
        }
    };
    View Code

    动作插件2

    js/time_move.js

    function timeMove(obj, target, type, times, fn) {
        clearInterval(obj.timer);
        var iStartTime = new Date().getTime();
        var oCur = {};
        for(var sAttr in target) {
            if(sAttr == 'opacity') {
                oCur[sAttr] = Math.round(parseFloat(getStyle(obj, 'opacity'))*100);
            } else {
                oCur[sAttr] = parseInt(getStyle(obj, sAttr));
            }
        }
        obj.timer = setInterval(function () {
            var iChangeTime = new Date().getTime();
            var iScale = 1 - Math.max((iStartTime + times - iChangeTime)/times, 0);
    
            for(var sAttr in target) {
                var iCur = type(oCur[sAttr], target[sAttr] - oCur[sAttr], times * iScale, times);
    
                if(sAttr == 'opacity') {
                    obj.style.opacity = iCur/100;
                    obj.style.filter = 'alpha(opacity:' + iCur + ')';
                } else {
                    obj.style[sAttr] = iCur + 'px';
                }
            }
    
            if(iScale == 1) {
                clearInterval(obj.timer);
                fn && fn();
            }
        }, 30);
    }
    // 获取属性样式
    function getStyle(obj, sAttr) {
        if(obj.currentStyle) {
            return obj.currentStyle[sAttr];
        } else {
            return getComputedStyle(obj, false)[sAttr];
        }
    }
    View Code

    php后台文件

    /waterfall.php

    <?php
        $data = array(
            array(
                'url' => 'img/1.jpg',
                'width' => 595,
                'height' => 914,
            ),
            array(
                'url' => 'img/2.jpg',
                'width' => 900,
                'height' => 1318,
            ),
            array(
                'url' => 'img/3.jpg',
                'width' => 600,
                'height' => 850,
            ),
            array(
                'url' => 'img/4.jpg',
                'width' => 512,
                'height' => 726,
            ),
            array(
                'url' => 'img/5.jpg',
                'width' => 567,
                'height' => 850,
            ),
            array(
                'url' => 'img/6.jpg',
                'width' => 361,
                'height' => 510,
            ),
            array(
                'url' => 'img/7.jpg',
                'width' => 510,
                'height' => 765,
            ),
            array(
                'url' => 'img/8.jpg',
                'width' => 400,
                'height' => 600,
            ),
            array(
                'url' => 'img/9.jpg',
                'width' => 460,
                'height' => 690,
            ),
            array(
                'url' => 'img/10.jpg',
                'width' => 683,
                'height' => 1024,
            ),
            array(
                'url' => 'img/11.jpg',
                'width' => 960,
                'height' => 1280,
            ),
            array(
                'url' => 'img/12.jpg',
                'width' => 427,
                'height' => 640,
            ),
            array(
                'url' => 'img/13.jpg',
                'width' => 607,
                'height' => 914,
            ),
            array(
                'url' => 'img/14.jpg',
                'width' => 402,
                'height' => 600,
            ),
            array(
                'url' => 'img/15.jpg',
                'width' => 720,
                'height' => 480,
            ),
            array(
                'url' => 'img/16.jpg',
                'width' => 658,
                'height' => 989,
            ),
            array(
                'url' => 'img/17.jpg',
                'width' => 641,
                'height' => 960,
            ),
            array(
                'url' => 'img/18.jpg',
                'width' => 658,
                'height' => 987,
            ),
            array(
                'url' => 'img/19.jpg',
                'width' => 600,
                'height' => 900,
            ),
            array(
                'url' => 'img/20.jpg',
                'width' => 683,
                'height' => 993,
            ),
        );
        echo json_encode($data);
    View Code
  • 相关阅读:
    【bzoj3083】遥远的国度 树链剖分+线段树
    【bzoj2226】[Spoj 5971] LCMSum 欧拉函数
    xml、json的序列化与反序列化
    什么是安全证书,访问者到底是怎么校验安全证书的,服务端返回安全证书后,客户端再向谁验证呢?
    查看发票组代码后的总结和有感
    网址的正则表达式、常用正则表达式、在线正则表达式检测
    XamlParseException异常
    委托,lambda,匿名方法
    windows中断与共享的连接(samba)
    linux ubuntu 11.04 samba 服务器设置
  • 原文地址:https://www.cnblogs.com/daysme/p/6279414.html
Copyright © 2020-2023  润新知