简体   繁体   English

创建缩放到容器宽度的 100% 的未知大小图像行

[英]Creating rows of unknown-size images that scale to 100% of container width

Given a set of images with random dimensions, I'm trying to display them in rows so that each row takes up 100% of the container width, and the space between each image is approximately the same.给定一组具有随机尺寸的图像,我试图将它们按行显示,以便每一行占据容器宽度的 100%,并且每个图像之间的空间大致相同。 Because I don't know the dimensions beforehand, I also don't know how many images will end up in a row.因为我事先不知道尺寸,所以我也不知道连续会出现多少张图像。 Right now, I'm using a container with flex wrap, and inside the container is a list of image wrappers with a set height and max-width (so very wide images are cropped).现在,我正在使用一个带有 flex wrap 的容器,容器内部是一个图像包装列表,具有设置的高度和最大宽度(因此裁剪了非常宽的图像)。 The images themselves have height: 100% and width: auto.图像本身具有高度:100% 和宽度:自动。 Then I have a resizing function that uses the offset top values to figure out which images are in a row, and scales them up based on a factor calculated from the sum of the widths of the images in that row.然后我有一个调整大小的函数,它使用偏移量最高值来确定哪些图像在一行中,并根据从该行中图像的宽度总和计算出的因子将它们放大。

It kind of works, but not very well - for one thing, I'm executing the resizing function on a timeout because if I don't, it will try to resize before the images are all loaded, which causes problems.它有点工作,但不是很好 - 一方面,我正在超时执行调整大小功能,因为如果我不这样做,它会在图像全部加载之前尝试调整大小,这会导致问题。 Also, the factor isn't perfect, so I end up with slightly jagged edges on the right side of the container.此外,这个因素并不完美,所以我最终在容器的右侧出现了略微锯齿状的边缘。 I can do the resizing twice, and that gives results that are close enough, but that seems silly.我可以进行两次调整大小,这会得到足够接近的结果,但这似乎很愚蠢。 I know I can give the container justify-content: space-between to take care of jagged edges on the left and right of the container, but it would be nice to just get it right (and the differences in spacing are kind of annoying).我知道我可以给容器 justify-content: space-between 处理容器左侧和右侧的锯齿状边缘,但只要把它弄对就好了(间距的差异有点烦人) . The last issue is if the window is resized after loading, the whole grid is messed up.最后一个问题是如果窗口在加载后调整大小,整个网格就会混乱。 I guess I could solve this with setInterval on the resizing function, but that seems messy (and this is already a messy solution).我想我可以在调整大小函数上使用 setInterval 来解决这个问题,但这看起来很混乱(这已经是一个混乱的解决方案)。

( Edit : I tried using setInterval, and it gives nicer results for everything but the window-resizing problem, because once you shrink the window enough to cause flex to wrap differently, sizing the window back up will never allow things to wrap the way they did before.) 编辑:我尝试使用 setInterval,它为除窗口大小调整问题之外的所有内容提供了更好的结果,因为一旦您将窗口缩小到足以导致 flex 以不同方式包裹,调整窗口大小将永远不会允许事物以它们的方式包裹以前做过。)

Is there a better solution?有更好的解决方案吗? The timeout and window-resizing are the main problems.超时和窗口大小调整是主要问题。 Ideally, I would end up with something like the Google Image results page, or the front page of DeviantArt.理想情况下,我最终会得到类似于 Google 图片结果页面或 DeviantArt 的首页的内容。 I'm fine with using another grid framework, as long as it does what I need.我可以使用另一个网格框架,只要它满足我的需要。 Here's my code (I'm using Bootstrap, so some of the formatting is in the HTML classes):这是我的代码(我使用的是 Bootstrap,所以一些格式在 HTML 类中):

HTML/ERB: HTML/ERB:

<div class="img-grid d-flex flex-wrap m-n1">
  <% images = create_placeholder_array %>
  <% images.each do |img| %>
    <%= link_to(img[:url],
      class: 'img-wrapper position-relative m-1') do %>
      <%= image_tag(img[:url], class: 'grid-img-wide', height: img[:height], width: img[:width]) %>
    <% end %>
  <% end %>
</div>

(The create_placeholder_array helper just makes an array of URLs to placeholder.com for images with random sizes.) (create_placeholder_array 助手只是为随机大小的图像制作一个指向 placeholder.com 的 URL 数组。)

CSS: CSS:

.img-wrapper {
  max-width: 320px;
  min-width: 100px;
  height: 200px;
  overflow: hidden;
}

.grid-img-wide {
  height: 100%;
  width: auto;
}

JavaScript/JQuery: JavaScript/JQuery:

document.addEventListener("turbolinks:load", function () {
    imagesPerRow = 0
    widthPerRow = 0
    currOffset = $('.img-wrapper').offset().top
    setTimeout(function() {
      $('.img-wrapper').each(function(i) {
        if (currOffset == $(this).offset().top) {
          imagesPerRow++;
          widthPerRow += $(this).outerWidth(true);
        } else {
          factor = $('.img-grid').innerWidth() / widthPerRow;
          console.log('factor: ' + factor);
          $('.img-wrapper').slice(i - imagesPerRow, i).each(function() {
            $(this).css('height', $(this).innerHeight() * factor + 'px');
            $(this).css('max-width', $(this).innerWidth() * factor + 'px');
          })
          currOffset = $(this).offset().top;
          imagesPerRow = 1;
          widthPerRow = $(this).outerWidth(true);
        }
      });
    }, 1000)
});

Thanks for your help!谢谢你的帮助!

have you tried changing your javascript reference of the event listener from document to window?您是否尝试将事件侦听器的 javascript 引用从文档更改为窗口?

refer to this to learn the difference. 请参阅this以了解差异。

window.addEventListener("load", function () {
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM