视觉效果


即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。

图解瀑布流算法

当第一排排满足够多的等宽图片时(如下图情况),自然而然的考虑到之后放置的图片会往下面排放。

那么第六张图片,放置在什么位置呢?是下图的位置么?

我们通过瀑布流算法实验得到,后面紧跟的第六张图片的位置应该是这个位置。

为什么呢?
因为放置它之前,这一列的高度为所有列中最小,所以会放置在这个地方。
所以我们知道了,如果再继续放置下去,第七张图片应该是这个位置,对吗?

通过瀑布流算法实验得出位置正确。看懂这个图示应该就能理解了瀑布流的原理算法。

代码实现

这里使用了jQuery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>
<style>
.waterfall img {
position: absolute;
width: 100px;
margin: 10px;
/* 布局transition效果 */
transition: all .4s;
}
</style>
</head>
<body>
<div class="waterfall">
<img src="./img/1.jpg">
<img src="./img/2.jpg">
<img src="./img/3.jpg">
<img src="./img/4.jpg">
<img src="./img/5.jpg">
<img src="./img/6.jpg">
<img src="./img/7.jpg">
<img src="./img/8.jpg">
<img src="./img/9.jpg">
<img src="./img/10.jpg">
<img src="./img/11.jpg">
<img src="./img/12.jpg">
<img src="./img/13.jpg">
<img src="./img/14.jpg">
<img src="./img/15.jpg">
</div>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
var colCount   //定义列数
var colHeightArry= [] //定义列高度数组
var imgWidth = $('.waterfall img').outerWidth(true) //单张图片的宽度

colCount = parseInt($('.waterfall').width()/imgWidth) //计算出列数
for(var i = 0 ; i < colCount; i ++){
colHeightArry[i] = 0
}
//[0,0,0]
$('.waterfall img').on('load',function(){
var minValue = colHeightArry[0] //定义最小的高度
var minIndex = 0 //定义最小高度的下标
for(var i = 0 ; i < colCount; i ++){
if(colHeightArry[i] < minValue){ //如果最小高度组数中的值小于最小值
minValue = colHeightArry[i] //那么认为最小高度数组中的值是真正的最小值
minIndex = i //最小下标为当前下标
}
}

$(this).css({
left: minIndex * imgWidth,
top: minValue
})
colHeightArry[minIndex] += $(this).outerHeight(true)
})


//当窗口大小重置之后,重新执行
$(window).on('resize',function(){
reset()
})


//当窗口加载完毕,执行瀑布流
$(window).on('load',function(){
reset()
})

//定义reset函数
function reset(){
var colHeightArry= []
colCount = parseInt($('.waterfall').width()/imgWidth)
for(var i = 0 ; i < colCount; i ++){
colHeightArry[i] = 0
}
$('.waterfall img').each(function(){
var minValue = colHeightArry[0]
var minIndex = 0
for(var i = 0 ; i < colCount; i ++){
if(colHeightArry[i] < minValue){
minValue = colHeightArry[i]
minIndex = i
}
}

$(this).css({
left: minIndex * imgWidth,
top: minValue
})
colHeightArry[minIndex] += $(this).outerHeight(true)
})
}

效果展示

总结瀑布流布局原理