text: // File#: _2_image-zoom
  // Usage: codyhouse.co/license
  
  (function() {
    var ImageZoom = function(element, index) {
      this.element = element;
      this.lightBoxId = 'img-zoom-lightbox--'+index;
      this.imgPreview = this.element.getElementsByClassName('js-image-zoom__preview')[0];
      
      initImageZoomHtml(this); // init markup
      
      this.lightbox = document.getElementById(this.lightBoxId);
      this.imgEnlg = this.lightbox.getElementsByClassName('js-image-zoom__fw')[0];
      this.input = this.element.getElementsByClassName('js-image-zoom__input')[0];
      this.animate = this.element.getAttribute('data-morph') != 'off';
      
      initImageZoomEvents(this); //init events
    };
  
    function initImageZoomHtml(imageZoom) {
      // get zoomed image url
      var url = imageZoom.element.getAttribute('data-img');
      if(!url) url = imageZoom.imgPreview.getAttribute('src');
  
      var lightBox = document.createElement('div');
      Util.setAttributes(lightBox, {class: 'image-zoom__lightbox js-image-zoom__lightbox', id: imageZoom.lightBoxId, 'aria-hidden': 'true'});
      lightBox.innerHTML = '<img src="'+url+'" class="js-image-zoom__fw"></img>';
      document.body.appendChild(lightBox);
      
      var keyboardInput = '<input aria-hidden="true" type="checkbox" class="image-zoom__input js-image-zoom__input"></input>';
      imageZoom.element.insertAdjacentHTML('afterbegin', keyboardInput);
  
    };
  
    function initImageZoomEvents(imageZoom) {
      // toggle lightbox on click
      imageZoom.imgPreview.addEventListener('click', function(event){
        toggleFullWidth(imageZoom, true);
        imageZoom.input.checked = true;
      });
      imageZoom.lightbox.addEventListener('click', function(event){
        toggleFullWidth(imageZoom, false);
        imageZoom.input.checked = false;
      });
      // detect swipe down to close lightbox
      new SwipeContent(imageZoom.lightbox);
      imageZoom.lightbox.addEventListener('swipeDown', function(event){
        toggleFullWidth(imageZoom, false);
        imageZoom.input.checked = false;
      });
      // keyboard accessibility
      imageZoom.input.addEventListener('change', function(event){
        toggleFullWidth(imageZoom, imageZoom.input.checked);
      });
      imageZoom.input.addEventListener('keydown', function(event){
        if( (event.keyCode && event.keyCode == 13) || (event.key && event.key.toLowerCase() == 'enter') ) {
          imageZoom.input.checked = !imageZoom.input.checked;
          toggleFullWidth(imageZoom, imageZoom.input.checked);
        }
      });
    };
  
    function toggleFullWidth(imageZoom, bool) {
      if(animationSupported && imageZoom.animate) { // start expanding animation
        window.requestAnimationFrame(function(){
          animateZoomImage(imageZoom, bool);
        });
      } else { // show lightbox without animation
        Util.toggleClass(imageZoom.lightbox, 'image-zoom__lightbox--is-visible', bool);
      }
    };
  
    function animateZoomImage(imageZoom, bool) {
      // get img preview position and dimension for the morphing effect
      var rect = imageZoom.imgPreview.getBoundingClientRect(),
        finalWidth = imageZoom.lightbox.getBoundingClientRect().width;
      var init = (bool) ? [rect.top, rect.left, rect.width] : [0, 0, finalWidth],
        final = (bool) ? [-rect.top, -rect.left, parseFloat(finalWidth/rect.width)] : [rect.top + imageZoom.lightbox.scrollTop, rect.left, parseFloat(rect.width/finalWidth)];
      
      if(bool) {
        imageZoom.imgEnlg.setAttribute('style', 'top: '+init[0]+'px; left:'+init[1]+'px; width:'+init[2]+'px;');
      }
      
      // show modal
      Util.removeClass(imageZoom.lightbox, 'image-zoom__lightbox--no-transition');
      Util.addClass(imageZoom.lightbox, 'image-zoom__lightbox--is-visible');
  
      imageZoom.imgEnlg.addEventListener('transitionend', function cb(event){ // reset elements once animation is over
        if(!bool) Util.removeClass(imageZoom.lightbox, 'image-zoom__lightbox--is-visible');
        Util.addClass(imageZoom.lightbox, 'image-zoom__lightbox--no-transition');
        imageZoom.imgEnlg.removeAttribute('style');
        imageZoom.imgEnlg.removeEventListener('transitionend', cb);
      });
      
      // animate image and bg
      imageZoom.imgEnlg.style.transform = 'translateX('+final[1]+'px) translateY('+final[0]+'px) scale('+final[2]+')';
      Util.toggleClass(imageZoom.lightbox, 'image-zoom__lightbox--animate-bg', bool);
    };
  
    // init ImageZoom object
    var imageZoom = document.getElementsByClassName('js-image-zoom'),
      animationSupported = window.requestAnimationFrame && !Util.osHasReducedMotion();
    if( imageZoom.length > 0 ) {
      var imageZoomArray = [];
      for( var i = 0; i < imageZoom.length; i++) {
        imageZoomArray.push(new ImageZoom(imageZoom[i], i));
      }
  
      // close Zoom Image lightbox on Esc
      window.addEventListener('keydown', function(event){
        if((event.keyCode && event.keyCode == 27) || (event.key && event.key.toLowerCase() == 'esc')) {
          for( var i = 0; i < imageZoomArray.length; i++) {
            imageZoomArray[i].input.checked = false;
            if(Util.hasClass(imageZoomArray[i].lightbox, 'image-zoom__lightbox--is-visible')) toggleFullWidth(imageZoomArray[i], false);
          }
        }
      });
    }
  }());