js瀑布流效果

js瀑布流效果,寬度自適應,當滾動條滾動到必定的位置按須要加載更多圖片,php

把最新取得的圖片動態從中間散開鋪向應有的位置。html

一打開網頁,刷新的效果,當瀏覽器窗口寬度只能容納三張圖片的時候:算法

當瀏覽器窗口寬度能夠容納4張圖片的時候:json

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>

 

動做插件1app

js/Tween.jside

/*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
相關文章
相關標籤/搜索