瀑布流效果,用女神图片用三种方法实现,比在浏览器看过瘾,哈哈哈

第一种方法:采用纯CSS的"多列"属性

实现瀑布流用到的一些多列属性:
1. column-count:指定元素的列数
2. column-gap:指定列之间的差距
3. column-width:指定列的宽度
效果图:
在这里插入图片描述
上代码:

imageUrl:string[]=["https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1589350346618&di=de03b3da00a0f34c39686d5807358867&imgtype=0&src=http%3A%2F%2Fspider.nosdn.127.net%2Ffa1e529588bb26cc1138af1cccd7e138.jpeg","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1589350346614&di=4cbbfb5f8866e8db964f910b052549df&imgtype=0&src=http%3A%2F%2Fdingyue.nosdn.127.net%2FdbiHYV2Ii%3Dit4aHh5w%3DNSerym2eozFdZFWYpEDmhETTft1543830889499compressflag.jpg","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1589350346613&di=e0f058157679cd453bb9f55ec0d31ae2&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201605%2F04%2F20160504123249_3KQFV.jpeg","https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=98853028,1799253278&fm=26&gp=0.jpg","https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1589350814762&di=fd1b01941ee66948102a9a2d453bac97&imgtype=0&src=http%3A%2F%2Fc1.haibao.cn%2Fimg%2F600_0_100_1%2FliTPb8Fw0hHUk%2Fpiccommon%2F1220%2F12209%2FliTPb8Fw0hHUk.jpg","https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=826485233,505117694&fm=26&gp=0.jpg","http://img5.imgtn.bdimg.com/it/u=2473598420,2292311239&fm=26&gp=0.jpg","http://b-ssl.duitang.com/uploads/item/201705/03/20170503082132_shZFk.jpeg","http://b-ssl.duitang.com/uploads/item/201708/08/20170808200725_S5dhK.jpeg","http://img3.duitang.com/uploads/item/201605/29/20160529071411_CwjB5.thumb.700_0.jpeg","http://img3.duitang.com/uploads/item/201606/18/20160618080624_fxJRk.jpeg","http://b-ssl.duitang.com/uploads/item/201806/08/20180608120338_ulawx.thumb.700_0.jpg","http://b-ssl.duitang.com/uploads/item/201806/22/20180622123913_icbup.jpg"];

<div class="body" id="body">
    <div class="container" id="container">
        <div *ngFor="let img of imageUrl"><img src={{img}}></div>
    </div>
</div>


*{
    margin:0px;
    padding:0px;
}
.body{
    background-color: aliceblue;
}
.container{
    position: relative;
    width:921px;
    background-color:  bisque;
    margin:0px auto;
    column-count: 4;
    column-width:225px;
    column-gap: 3.5px;
}
.container div{
    padding:10px;  
}
img{
    border-radius: 10%;
    width:205px;
    position: relative;
}
注意点:
  1. 采用column实现瀑布流,它的图片排布顺序是“由上往下”排布的,即imageUrl数组中的第二个图片的src显示在效果图中第一列第二张图片的位置。
  2. 这里不能设置具体的height,如果设置了具体的height,如果height值不足以装下所有图片,那么就会出现"横向"滚动条,而不是纵向滚动条,就算设置overflow-y:auto,也是出现横向滚动条;如果height值过大,图片不多,那又有很多空余地方。因此不用设置height,让它根据图片的多少自动响应。
  3. column一开始是用于“文本”按多列显示,实现瀑布流是意外的发现。

第二种方法:采用纯CSS的“flex”布局

知识点:

  1. 弹性盒子由弹性容器和弹性子元素组成。
  2. 弹性容器通过设置display属性的值为flex或inline-flex即声明为弹性容器。

flex经常使用的一些属性:

  1. flex-direction:用于弹性子元素的漂浮方向
  2. justify-content:内容对齐属性应用在弹性容器上,把弹性项沿着弹性容器的主轴线对齐。
  3. align-content:设置或检索弹性盒子元素在纵轴方向上的对齐方式。
  4. flex-wrap:用于指定弹性盒子的子元素换行方式。
  5. order:用整数值来定义排列顺序,数值小的排在前面,可以为负值。

效果图:
在这里插入图片描述
上代码:

<div class="body" id="body">
    <div class="container">
        <div>
            <div *ngFor="let url of imageUrl1" class="item">
                <img src={{url}}>
            </div>
        </div>
        <div>
            <div *ngFor="let url of imageUrl2" class="item">
                <img src={{url}}>
            </div>
        </div>
        <div>
            <div *ngFor="let url of imageUrl1" class="item">
                <img src={{url}}>
            </div>
        </div>
        <div>
            <div *ngFor="let url of imageUrl2" class="item">
                <img src={{url}}>
            </div>
        </div>
    </div>    
</div>


.container{
    width:1000px;
    background-color: bisque;
    margin:0px auto;
    display: flex;
    flex-direction: row;
}
.container div{
    width:250px;
}
.container div .item{
    padding-top:12.5px;
    padding-left:12.5px;
}
img{
    border-radius: 10%;
    width:225px;
}

实现瀑布流的思路: 就是将container容器分成三个横向排布的容器,然后在在三个容器中加入子元素,让它们紧挨着纵向排布即可。flex-direction:row;使得三个子容器横向排列。

注意: 这两种纯CSS在静态网页上实现瀑布流是非常方便的,但要与后端处理的网页就需要用js实现的瀑布流更为合适。下面将用js实现瀑布流。

第三种方法:js实现瀑布流

思路: 在一个大容器中加入图片,由于每个装有图片的小容器是根据每列最小高度决定的,所以它的位置可能是在大容器的任意位置,因此图片容器必须是 “绝对” 定位。 那么是如何决定每个容器图片的位置呢?决定一个图片位置需由lefttop来确定,首先来说一下top,我们需用一个变量来记录每一列加载图片后的高度,然后用一个函数来找出最小的高度的一列,新生成的图片容器即移动到这列下面,当移动完成后务必将这列的目前高度更新,即加上新增的容器高度即可;left就简单了,比如在第二列,就往左移动一个图片容器的宽度,第三列就移动两个图片容器宽度。
效果图:
在这里插入图片描述
在这里插入图片描述
上代码:

<--html-->
<div class="body" id="body">
    <div class="container" id="container">
        
    </div>
</div>

<--css-->
.container{
    position: absolute;
    width:1000px;
    margin-left:267.5px;
}

<--ts-->
import { SetBodyService } from '../../services/set-body.service';
@Component({
  selector: 'app-waterfall-flow',
  templateUrl: './waterfall-flow.component.html',
  styleUrls: ['./waterfall-flow.component.css']
})
export class WaterfallFlowComponent implements OnInit {

  imageUrl:string[]=["http://img3.imgtn.bdimg.com/it/u=2720828083,1944181330&fm=214&gp=0.jpg",
  "http://pic1.win4000.com/wallpaper/4/55f7d8120e8d9.jpg",
  "http://a.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=c3eaf688ae1ea8d38a777c00a23a1c78/0dd7912397dda1445d242d81bab7d0a20cf486d0.jpg",
  "http://img1.doubanio.com/view/photo/l/public/p2286361348.jpg",
  "http://img4.imgtn.bdimg.com/it/u=1385458535,2707792223&fm=26&gp=0.jpg",
  "http://img3.doubanio.com/view/photo/l/public/p2245656810.jpg",
  "http://i0.hdslb.com/bfs/archive/d0c4ef29465c1e81c1b7ef3ee153226b69bfb988.jpg",
  "http://img3.doubanio.com/view/photo/l/public/p2238986974.jpg",
  "http://smimg5.mingxing.com.cpgzh.com/upload/pic/smpic/2016/5722/20161129093449_92506.jpg",
  "http://hbimg.b0.upaiyun.com/9defce59b7be7f69714ad38cfa0fdfa1a1cb646112bce-Fi6DY2_fw658",
  "http://img3.imgtn.bdimg.com/it/u=1565781473,2937605964&fm=214&gp=0.jpg",
  "http://img1.imgtn.bdimg.com/it/u=488153396,1617963994&fm=214&gp=0.jpg",
  "http://hbimg.b0.upaiyun.com/224dd07e9b2c907f85d8cf94543afaf3ee369b6c10d09-Z5ekDk_fw658",
  "http://c3.haibao.cn/img/0_0_100_1/1529996952.6817/ef999b1760f8bd7193cab921b8b53950.jpg",
  "http://img5.imgtn.bdimg.com/it/u=1169307261,3984018180&fm=26&gp=0.jpg",
  "http://cdn0.hbimg.cn/store/wm/piccommon/1211/12118/D525B7BBEAB6C0F2DBA98FCF38.jpg",
  "http://img3.imgtn.bdimg.com/it/u=4254713837,1862524406&fm=26&gp=0.jpg",
  "http://n.sinaimg.cn/translate/303/w1080h1623/20180515/ZHp2-fzrwiaz5438989.jpg",
  "http://c1.haibao.cn/img/460_690_100_1/liOzPRH2UgGA/piccommon/1220/12209/liOzPRH2UgGA.jpg"
];



  columnHeight:number[]=[0,0,0,0];//记录每列的最新高度,确定新图片加载在哪列下面

  presentHeight:number;//图片被缩放后的高度

  minIndex:number;

  setWaterFall(){//设置瀑布流
    var parentDiv=document.getElementById("container");
    for(let i=0;i<this.imageUrl.length;i++){
    var divObj=document.createElement("div");//生成包裹着图片的容器
    divObj.setAttribute("style","width:250px;background-color:bisque");
    var newImg=new Image();
    //newImg.setAttribute("src",this.imageUrl[i]);
    newImg.src=this.imageUrl[i];
    alert(newImg.width);
    newImg.setAttribute("style"," width:225px;margin:12.5px;border-radius: 10%;")
    this.getPresentHeight(newImg);//须在设置newImg的style属性前更新缩小后的高度
    divObj.appendChild(newImg);
    parentDiv.appendChild(divObj);
    this.rightPosition(divObj);
    }
  }

  getMinColumn(){//找出四列最短的一列
    let min=this.columnHeight[0];
    let index=0;
    for(let i=1;i<4;i++){
      if(min>this.columnHeight[i]){
        min=this.columnHeight[i];
        index=i;
      }
    }
    this.minIndex=index;
  }

  updateColumnHeight(){//将图片加在最短列下面后,要更新最短列的高度
    this.columnHeight[this.minIndex]=this.presentHeight+25+this.columnHeight[this.minIndex];
  }

  getPresentHeight(picture:any){//获得图片的缩小后的高度
     this.presentHeight=picture.height/(picture.width/225);
     console.log(this.presentHeight);
  }

  rightPosition(divObj:any){//将装有图片的div移动到合适位置
    this.getMinColumn();//要移到合适位置,首先得更新最小列
    switch(this.minIndex){
      case 0:{
        divObj.style.position="absolute";
        divObj.style.left="0px";//第一列在横向不用移动
        divObj.style.top=`${this.columnHeight[0]}px`;
        break;
      }
      case 1:{
        divObj.style.position="absolute";
        divObj.style.left="250px";//第一列在横向不用移动
        divObj.style.top=`${this.columnHeight[1]}px`;
        break;
      }
      case 2:{
        divObj.style.position="absolute";
        divObj.style.left="500px";//第一列在横向不用移动
        divObj.style.top=`${this.columnHeight[2]}px`;
        break;
      }
      case 3:{
        divObj.style.position="absolute";
        divObj.style.left="750px";//第一列在横向不用移动
        divObj.style.top=`${this.columnHeight[3]}px`;
        break;
      }
    }
    this.updateColumnHeight();//设置位置后需更新最小列高度
  }
  


  constructor(
    private setBodyService:SetBodyService
  ) { }

  ngOnInit(): void {
    var body=document.getElementById("body");
    this.setBodyService.setBody(body);
    this.setWaterFall();
}
}


<--一个自定义服务-->

@Injectable({
  providedIn: 'root'
})
export class SetBodyService {

  constructor() { }
  setBody(obj:any){
    var width=window.screen.width;
    var height=window.screen.height;
    obj.setAttribute("style",`height:${height-72}px; width:${width-1}px`);
  }
}

最后反映我遇到的一个问题: 我在网上找图片时,发现有一些图片是通过newImg.height是无法获取图片的宽度或高度的,得到的高度为0,若为0,请务必删除该图片链接,更换其它图片,否则可能导致不能形成瀑布流效果。
小白一枚,有错请在评论区指教

猜你喜欢

转载自blog.csdn.net/weixin_43334673/article/details/106097385
今日推荐