EvanLovely
7/29/2015 - 5:28 PM

Turn responsive img tags to background images

Turn responsive img tags to background images

/**
 * Background Image Helper
 */
Drupal.behaviors.imgToBG = {
  attach: function (context) {

    var $wrapper = $('.js-turn-img-to-bg', context);
    var debounceDelay = 300;

    (function imgToBG() {
      $wrapper.each(function () {
        $(this).find('img').each(function () {
          var $img = $(this);
          var src = '';
          var $wrapMe;

          if ($img.closest('picture').length && window.HTMLPictureElement) {
            // using responsive images with native support
            src = getCurrentResponsiveImage($img.closest('picture'));
            $wrapMe = $img.closest('picture');
          } else if ($img.closest('picture').length && !window.HTMLPictureElement) {
            // using responsive images with polyfill
            src = getCurrentResponsiveImage($img.closest('picture'));
            $wrapMe = $img.closest('picture');
          } else {
            // no responsive images
            src = $img.attr('src');
            $wrapMe = $img;
          }
          // settings complete
          if (src.length) {
            // we have a value

            if ($wrapMe.parent().hasClass('js-bg-img') === false) {
              // first run
              $wrapMe
                .hide() // @ todo use CSS class to hide instead
                .wrap('<div></div>')
                .parent()
                .attr('style', 'background-image: url(' + src + ');')
                .addClass('js-bg-img js-bg-img--expand');

              // certain components want a class so the styles can accomodate
              $img.parents('.media-block').addClass('has-bg-img');
            }

          } else {
            // error; no `src` found
            console.error("img src wasn't found, so it wasn't turned into a background image.", $img);
          }
        });
      });

    })();

    function getCurrentResponsiveImage($picture) {

      // get all paths and media queries from `picture > source`
      var images = [];
      $picture.find('source, img').each(function () {
        var $thisImage = $(this);
        var image = {};
        image.srcset = $thisImage.attr('srcset');
        if ($thisImage[0].localName === 'source') {
          // <source>
          image.media = $thisImage.attr('media');
        } else {
          // <img>
          image.media = "(min-width: 1px)";
        }
        images.push(image);
      });


      // get a list of all images that satisfy their media query from the `media` attribute of `<source>`
      var possibleImages = [];
      _.each(images, function (image) {
        if (Modernizr.mq(image.media) === true) {
          possibleImages.push(image);
          //console.log("going over: image.srcset", image);
        }
      });

      // since they are ordered from biggest to smallest; we want the biggest qualifying image
      return _.first(possibleImages).srcset;

    }

    // on resize, wait a sec, then update the background image
    $(window).resize(_.debounce(function () {
      $wrapper.each(function () {
        //console.log('updateResponsiveBG began', $(this));
        var $picture = $(this).find('.js-bg-img > picture');
        if ($picture.length) {
          var src = getCurrentResponsiveImage($picture);
          $picture.parent().attr('style', 'background-image: url(' + src + ');');
          //console.log('updateResponsiveBG ran');
        }
      });
    }, debounceDelay));

  }
};