来源自rnnoise,但非rnn

  图片的横向瀑布流,其实简单地按顺序排列就可以了
  
  但要实现每行中各图片都等高(各行不一定等高,但每行里面等高),且每行都占满,就需要用到flex的特性了
  
  控制每行图片高度都一致,可能会影响图片的比例,所以不能简单暴力地设置高度,需要按比例来动态计算
  
  另外,如要限制图片展示的行数,则只需判断好每行总高度与容器总高度的关系即可
  
  这里就来实现一下这个小功能
  
  点我预览
  
  因为都是假数据的关系,图片的宽高值是随机数,并非原图宽高值,仅作参考
  
  看完上面那张大大的图,先想一下可以怎么实现..
  
  要实现每行都能够占满,需要用到 flex-grow 这个属性
  
  flex-grow基于flex-basis基准值来计算,而flex-basis则基于项目的width、min|max-width相关的值来计算,或者手动定义
  
  使用flex-grow可以分配按比例分配主轴的剩余空间
  
  如果有10张图片需要放置,第一行仅可以放置四张图片,剩余100px的空间,那么各图片的flex-grow可以直接配置成图片的宽度width值,即可很方便精准地分配好这剩余的空间
  
  第二行可以放五张图片,剩余N px的空间... 按照这种计算方式来铺满每一行
  
  复制代码
  
  <h1 class="get-latest-update">
  
  <a href="javascript:;">获取最近更新</a>
  
  </h1>
  
  <div class="img-items"></div>
  
  <script type="text/template" id="img-item-tpl">
  
  <div class="img-item" style="flex-grow: {{width}}; width: {{width}}px;">
  
  <a href="#/img/{{id}}" style="padding-top: {{paddingTop}}%;">
  
  <img data-src="{{src}}" src="{{src}}" width="100%" height="100%">
  
  </a>
  
  </div>
  
  </script>
  
  复制代码
  
  上面页面模板中,flex-grow 与 width的值一致,用以按比例分配每行剩余空间
  
  另外可以看到这里有个 padding-top 的百分比值
  
  我们都知道  padding-top 的百分比值是基于父元素的宽度来计算的,根据盒模型,一般这种计算方式是为了获取固定宽高比
  
  当父元素有宽度,但高度为0时,整体高度则由padding-top值来撑开,则父元素就有了一个设定的宽高比,
  
  同时我们将子元素(这里是图片)position值设置为absolute,宽高占满父元素,则子元素图片也有了一定的宽高比,实现按比例的图片缩放
  
  来看看对应的样式设置
  
  复制代码
  
  body {
  
  background-color: #f2f2f2;
  
  }
  
  .get-latest-update {
  
  font-size: 20px;
  
  cursor: pointer;
  
  > a {
  
  color: #0183fd;
  
  text-decoration: none;
  
  }
  
  }
  
  .img-items {
  
  display: flex;
  
  flex-wrap: wrap;
  
  overflow: hidden;
  
  }
  
  .img-item {
  
  margin-right: 10px;
  
  margin-bottom: 10px;
  
  background-color: #fff;
  
  box-shadow: 0 0 10px #ddd;
  
  > a {
  
  position: relative;
  
  display: block;
  
  width: 100%;
  
  }
  
  img {
  
  position: absolute;
  
  top: 0;
  
  left: 0;
  
  width: 100%;
  
  height: www.gcyl158.com 100%;
  
  }
  
  }
  
  复制代码
  
  那么,这个width和padding-top的该怎么计算出来呢
  
  核心代码是
  
  复制代码
  
  // 图片预定义的高度
  
  var baseHeight = 200;
  
  for (var i = 1; i <= num; ++i) {
  
  var w = getRandom(width.min, width.max);
  
  var h = getRandom(height.min, height.max);
  
  imgs.push({
  
  id: i,
  
  src: imgSrcBase[Math.floor(i / 10)] + (i % 10 + 1) + '.jpg',
  
  // 设置图片的宽度,需根据预定义的高度值来做好比例处理
  
  // 为了让每行各图片按自身宽度自动flex-glow,同时利用这个比例处理保证每行图片的高度一致
  
  width: w * baseHeight / h,
  
  height: h,
  
  // padding-top的百分比,用以基于父元素宽度设置该元素的高度
  
  // 为了保证图片宽高按比例
  
  paddingTop: h / w * 100
  
  });
  
  }
  
  复制代码
  
  paddingTop的值,按照以下这个映射关系来看就好
  
  容器高度 == 容器宽度 * paddingTop %
  
  最终会形成
  
  容器高度 == 图片高度
  
  容器宽度 == 图片宽度
  
  所以
  
  图片高度 == 图片宽度 * paddingTop %
  
  width值的计算可能比较绕
  
  假设这里 width直接取 图片宽度w值,就会出现一行中图片高度不一致的情况
  
  因为最终的图片高度即为容器的高度,而容器的高度是由容器宽度决定的(注意这里的paddingTop值已经确定),而容器宽度就是由这里的width来决定的。图片宽度的不同,就直接导致了最终高度的不同
  
  所以,为了确保图片高度一致,假设有三张图片 50*50  100*100  50*150  放在了同一行中,flex布局会将三张图片所在容器的高度自适应为最高的那个150,如果flex-grow值起作用了,这个最高值还会再多一些
  
  我们可以考虑最简单的情况,正好放满一行。那么最终三张图片的高度都应该为150,按照各自的图片比例来调整,则最终第一张图片宽度的计算  50 / 50 === width / 150 , 则 width = 50 / 50 * 150
  
  可能有些行最高的图片还是不够高,为了也能够显示出比较大的图片,我们还可以定义好这个基准高度值,比如 baseHeight设置为 200
  
  所以,最终每一张图片的宽度width值为 w / h * baseHeight
  
  还要一个问题,如何实现只显示三行
  
  显示三行,每行的图片数量不固定,这是通过flex布局自动排列每一行的,都会经过 基本排列 -> 分配剩余空间 的步骤
  
  目前想到的方法是对每一行的容器所占位置进行累加,最后对比即可
  
  不过这种方式会有比较大的性能损耗,看还能不能有更优雅的做法吧
  
  复制代码
  
  // 设置显示的图片行数
  
  function setLineLimit(num) {
  
  // 内容区宽度
  
  var contentWidth =www.gcyL157.com $('.img-items').outerWidth();
  
  // 定义的外边距
  
  var marginWidth www.gcyl159.com= 10;
  
  // 每行宽度
  
  var curWidth www.mhylpt.com= 0;
  
  // 行标识
  
  var lineIndex = 1;
  
  // 初始需将图片设置为可见,否则flex无法自适应排版
  
  $('.img-item').show()
  
  .each(function() {
  
  var $item = $(this);
  
  var itemWidth = $item.outerWidth();
  
  // 隐藏多余的行
  
  if (lineIndex > num) {
  
  $item.hide();
  
  return;
  
  }
  
  $item.show();
  
  // 某一行
  
  if (curWidth + itemWidth + marginWidth <= contentWidth + marginWidth) {
  
  curWidth += itemWidth + marginWidth;
  
  }
  
  // 下一行
  
  else {
  
  ++lineIndex;
  
  curWidth = itemWidth;
  
  if (lineIndex > num) {
  
  $item.hide();
  
  }
  
  }
  
  });
  
  }
  
  复制代码
  
  主要注意的点是,为了兼顾视窗缩放的过程中,自动排列也能照常进行,在计算的时候需要将每个项先显示出来,再进入计算环节
  
  // 视窗缩放时处理可视的图片
  
  $(window).resize(throttle(setLineLimit.bind(this, 3), 200));

猜你喜欢

转载自blog.csdn.net/li123128/article/details/84695775
RNN