Вопрос по изображениям

Tracktor
Tracktor
1,1K
9
Содержание:
  1. Комментарии
Здравствуйте. Вопрос по изображениям.

Что делать, если необходимо расположить рядом несколько изображений разных размеров (например, одно горизонтальное, другое вертикальное, разные по длине и ширине) таким образом, чтобы их общая ширина была равна ширине блока, в котором они находятся, но высота изображений была одна, без потери соотношения их сторон? Возможно ли такое с использованием Bootstrap? При этом, нужно сохранять их адаптивность (т.е. уменьшать при уменьшении размеров экрана). Пробовал класс img-responsive, но он, как я понял, просто вписывает изображение в ширину блока…

Комментарии: 9

  1. Сергей
    Сергей
    2017-02-13 11:17:14
    Может вам sapegin.github.io/jquery.mosaicflow/ поможет. На itchief.ru и урок по этому есть itchief.ru/lessons/bootstrap-3/bootstrap-3-create-image-galleries
  1. Tracktor
    Tracktor
    2017-02-13 12:48:33
    Видел этот урок. Уже думал по поводу подобных галерей, но всё равно немного не то, что нужно… В примере по ссылке высота изображений разная, а я хочу получить одну высоту всех изображений в блоке и выстроить их ровненько в ряд по ширине блока.
  • Tracktor
    Tracktor
    2017-02-13 10:44:34
    Спасибо. Попробовал, но всё равно получается немного не то. Наверное, я не точно сформулировал задачу.
    Изображения необходимо будет добавлять статьи на сайте, а скрипт поместить например перед закрытием на постоянной основе, чтобы он, видя обозначенный блок (в моём примере это div.main), совершал в нём все эти рассчёты с изображениями… Плюс, хочется видеть изображения в их полном, «необрезанном» виде. Высота контейнера при этом неважна, главная задача ровно расположить изображения по всей ширине контейнера без изменения их пропорций…
    1. Tracktor
      Tracktor
      2017-02-11 10:28:26
      Александр, спасибо за ответ. Но похоже, мне всё-таки нужен будет вариант с Javascript. В данном способе, как я понял, изображения подключаются через css свойство background, а в моём случае изображения будут добавляться динамически (то есть, придётся к каждой статье на сайте менять это свойство для картинок). Плюс, картинок может быть не две, а больше.

      На одном из форумов подсказали интересное решение на JS:

      HTML:
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
      <div class="main" style="width: 800px; border: 1px solid black; margin: 0 auto;">
        <img src="http://nemalo.net/uploads/posts/2015-08/1440496077_java.jpg"><img src="https://trashbox.ru/ifiles/533976_72c4c8_screenshot_08/html-css-php-js-book-1.2.4-9.png">
      </div>
      
      JS:
      function imgSize(href){
        var img = new Image();
        img.src = href;
        img.onload = function() {
          sum += img.width / img.height;
      	loaded++;
      	if (loaded == count) $('.main img').height($('.main').width() / sum);
        };
      }
      
      var sum = 0;
      var count = $('.main img').length;
      var loaded = 0;
      $('.main img').each(function() {
        imgSize($(this).attr('src'));
      });
      Код работает, но есть три минуса:
      1. Изображения нужно добавлять вплотную друг к другу, таким образом смотрится не очень красиво без отступов.
      2. Размеры изображений вычисляются в пикселях, что приводит к потере адаптивности. Если ширину блока main задавать в процентах — размеры картинок всё равно остаются в пикселях, и при изменении размеров экрана вёрстка рушится.
      3. Если нужно создать на странице, например, два таких блока по два изображения в каждом, всё равно скрипт будет считать их общие размеры, и результат получится не тот, что нужен.

      К сожалению, с моим незнанием языка Javascript, не хватает мозгов, чтобы допилить данный скрипт…
      Если у вас найдётся время и желание помочь с этим делом, был бы очень признателен :)
      1. Александр Мальцев
        Александр Мальцев
        2017-02-11 17:41:47
        Можно конечно и так сделать, но тут необходимо будет всё вычислять.
        С помощью JavaScript можно не только изображения, но и целые блоки добавлять.
        Например, в HTML создать только контейнер:
        <div id="images" class="container"></div>
        
        Скрипт JavaScript (с использованием jQuery) для динамического вывода изображений:
        <script>
        $(function(){
          var images = {
            'rows': 2,
            'landscape': ['img/l1.jpg','img/l2.jpg'],
            'portrait': ['img/p1.jpg','img/p2.jpg']
          }
          var container = $('#images');
          for (var i=0; i<images['rows'];i++) {
            container.append('<div class="rowflex" style="height: 200px;">'+
              '<div id="landscape-image'+i+'" class="colflex-xs-12 colflex-md-8"></div>'+
              '<div id="portrait-image'+i+'" class="colflex-xs-12 colflex-md-4"></div>'+
              '</div>');
            $('#landscape-image'+i).css({
              'background':'url('+images['landscape'][i]+')',
              'background-size':'cover'
            });
            $('#portrait-image'+i).css({
              'background':'url('+images['portrait'][i]+')',
              'background-size':'cover'  
            });  
          }
        });
        </script>
        
        Т.е. создаём объект images и записываем туда, сколько необходимо вывести количество блоков (например, 2) и также пути к изображениям для каждого блока.

        Тогда эти стили можно удалить из CSS:
        #landscape-image {
          background: url(img/image_1.jpg);
          background-size: cover;
        }
        #portrait-image {
          background: url(img/image_2.jpg);
          background-size: cover;
        }
        
      2. Александр Мальцев
        Александр Мальцев
        2017-02-18 02:27:00
        Можно конечно и этот доработать…
        Чтобы он работал адаптивно необходимо рассчитывать тогда не высоту, а ширину и устанавливать её в процентах от ширины контейнера.
        <script>
        $(function () {
          // id - идентификатор блока, содержащий изображения
          // width - ширина всех изображений % от ширины контейнера
          // img-margin - отступы
          // img-radius - скруления углов
          var resizePictures = function(id,totalwidth,img_margin,img_radius){
            var sum = 0;
            var count = $(id).find('img').length;
            var loaded = 0;
            function imgSize(href){
              var img = new Image();
              img.src = href;
              img.onload = function() {
                sum += img.width / img.height;                                         
        	  loaded++;
        	  if (loaded == count) {
                    $(id).find('img').each(function(){
                    $(this).css({
                      'width': ((($(this).width() / $(this).height()) / sum)*totalwidth)+'%',
                      'margin': img_margin,
                      'border-radius':img_radius
                    });
                  });
                };
              };
            };	  
            $(id).find('img').each(function() {
              imgSize($(this).attr('src'));
            });
          };
          resizePictures('#main',90,'3px','4px');
        });
        </script>
        
        Добавление отступов в вышепредставленном скрипте осуществляется посредством margin, и указывать их лучше в пикселях. Иначе изображения получатся немного разные, т.к. они имеют не одинаковую ширину.
        Если необходимо установить несколько таких блоков, то необходимо просто вызвать ещё раз функцию resizePictures и передать ей в качестве параметра нужный идентификатор блока.
        resizePictures('#main',90,'3px','4px');
        Но, решение на свойстве background даже на основании этого скрипта было бы более простым…
      3. Tracktor
        Tracktor
        2017-02-20 14:37:26
        Громадное спасибо!
        Пара вопросов:
        1. Можно ли сразу добавить в скрипт несколько контейнеров, в которых будут ресайзиться изображения? например,
        resizePictures('#main-1',90,'3px','4px');
        resizePictures('#main-2',90,'3px','4px');
        resizePictures('#main-3',90,'3px','4px');
        
        Идея в том, чтобы подключить скрипт перед </боди> и больше к нему не возвращаться, а в статьях просто прописывать нужные классы блокам (вряд ли больше трёх будет в статье)…
        2. Правильно ли я сделал, заменив «id» на «className» во всём скрипте, если хочу идентифицировать блок с изображениями по классу, а не по ид? Вроде, работает.
      4. Александр Мальцев
        Александр Мальцев
        2017-02-21 10:12:35
        1. Да, можно:
        <div id="main-1" style="margin: 0 auto; text-align:center;">
          <img src="img/1.jpg"><img src="img/2.jpg"><img src="img/3.jpg">
        </div>
        <div id="main-2" style="margin: 0 auto; text-align:center;">
          <img src="img/4.jpg"><img src="img/5.jpg"><img src="img/6.jpg">
        </div>
        <div id="main-3" style="margin: 0 auto; text-align:center;">
          <img src="img/7.jpg"><img src="img/8.jpg"><img src="img/9.jpg">
        </div>
        
        2. Можно использовать вместо id и имя класса.
    2. Александр Мальцев
      Александр Мальцев
      2017-02-10 16:25:27
      Добрый день. Без JavaScript это можно выполнить только на Flexbox. Только вам необходимо указать высоту контейнера с изображениями.
      Код HTML:
      <div class="container">
        <div class="rowflex" style="height: 200px;">
          <div id="landscape-image" class="colflex-xs-12 colflex-md-8"></div>
      	<div id="portrait-image" class="colflex-xs-12 colflex-md-4"></div>
        </div>
      </div>
      
      Код CSS:
      .rowflex {
        display: -webkit-box;
        display: -webkit-flex;
        display: -ms-flexbox;
        display: flex;
        -webkit-flex-wrap: wrap;
        -ms-flex-wrap: wrap;
        flex-wrap: wrap;
      }
      @media (min-width: 768px) {
        .colflex-md-4 {
          -webkit-box-flex: 0;
          -webkit-flex: 0 0 33.333333%;
          -ms-flex: 0 0 33.333333%;
          flex: 0 0 33.333333%;
          max-width: 33.333333%;
        }
        .colflex-md-8 {
          -webkit-box-flex: 0;
          -webkit-flex: 0 0 66.666666%;
          -ms-flex: 0 0 66.666666%;
          flex: 0 0 66.666666%;
          max-width: 66.666666%;
        }
      }
      @media (max-width: 767px) {
        .colflex-xs-12 {
          -webkit-box-flex: 0;
          -webkit-flex: 0 0 100%;
          -ms-flex: 0 0 100%%;
          flex: 0 0 100%%;
          max-width: 100%%;
        }
      }
      #landscape-image {
        background: url(img/image_1.jpg);
        background-size: cover;
      }
      #portrait-image {
        background: url(img/image_2.jpg);
        background-size: cover;
      }