Custom Modal / Lightbox

by ritcheyer

HTML

<div class="container gallery-container">
    <h2 class="section-title">Section Title</h2>
    <section class="media-nav">
        <h4 class="section-title">Group 1</h4>
        <ul class="filmstrip-container">
            <li class="image-container">
                <a href="http://placehold.it/2560x1440&amp;text=Grp+1+Img+1" class="image-link" data-group="group-1">
                    <img src="http://placehold.it/256x144&amp;text=Grp+1+Img+1" class="thumb-image">
                </a>
            </li>
            <li class="image-container">
                <a href="http://placehold.it/2560x1440&amp;text=Grp+1+Img+2" class="image-link" data-group="group-1">
                    <img src="http://placehold.it/256x144&amp;text=Grp+1+Img+2" class="thumb-image">
                </a>
            </li>
            <li class="image-container">
                <a href="http://placehold.it/2560x1440&amp;text=Grp+1+Img+3" class="image-link" data-group="group-1">
                    <img src="http://placehold.it/256x144&amp;text=Grp+1+Img+3" class="thumb-image">
                </a>
            </li>
        </ul>
    </section>
    <section class="media-nav">
        <h4 class="section-title">Group 2</h4>
        <ul class="filmstrip-container">
            <li class="image-container">
                <a href="http://placehold.it/2560x1440&amp;text=Grp+2+Img+1" class="image-link" data-group="group-2">
                    <img src="http://placehold.it/256x144&amp;text=Grp+2+Img+1" class="thumb-image">
                </a>
            </li>
            <li class="image-container">
                <a href="http://placehold.it/2560x1440&amp;text=Grp+2+Img+2" class="image-link" data-group="group-2">
                    <img src="http://placehold.it/256x144&amp;text=Grp+2+Img+2" class="thumb-image">
                </a>
            </li>
            <li class="image-container">
                <a href="http://placehold.it/2560x1440&amp;text=Grp+2+Img+3" class="image-link"...

CSS

/* ------------------------------------------------------------
SAMPLE MARKUP
---------------------------------------------------------------
<div class="image-modal">
    <div class="modal-screen">
        <span class="icon-close">X</span>
        <div class="hero">
            <img src="" alt="" class="hero-image">
        </div>
    </div>

    <!-- optional and only if there are multiple set up -->
    <div class="modal-thumbs">
        <ol class="thumb-wrap">
            <li class="thumb-item">
                <a href="" class="thumb-link">
                    <img src="" class="thumb-image">
                </a>
            </li>
        </ol>
    </div>
</div>
------------------------------------------------------------ */
.hidden {
  display: none; }

.fade-in {
  -moz-transition: opacity 0.5s ease-in-out;
  -o-transition: opacity 0.5s ease-in-out;
  -webkit-transition: opacity 0.5s ease-in-out;
  transition: opacity 0.5s ease-in-out;
  opacity: 1; }

.fade-out {
  -moz-transition: opacity 0.5s ease-in-out;
  -o-transition: opacity 0.5s ease-in-out;
  -webkit-transition: opacity 0.5s ease-in-out;
  transition: opacity 0.5s ease-in-out;
  opacity: 0; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0; }

.modal-theatre {
  -moz-transform: scale(0.75);
  -ms-transform: scale(0.75);
  -webkit-transform: scale(0.75);
  transform: scale(0.75);
  -moz-transition-duration: 300ms;
  -o-transition-duration: 300ms;
  -webkit-transition-duration: 300ms;
  transition-duration: 300ms;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  top: 0;
  opacity: 0;
  background-color: #fff;
  z-index: -1; }
  .modal-theatre .thumb-image {
    float: left;
    max-width: 80px; }

.open-curtains {
  -moz-transform: scale(1);
  -ms-transform: scale(1);
  -webkit-transform: scale(1);
  transform: scale(1);
  -moz-transition-duration: 400ms;
  -o-transition-duration: 400ms;
 ...

JavaScript

/* ------------------------------------------------------------
Features
    1. Keyboard navigation
        - left/right
        - escape to close
    2. cover full screen with white backdrop
    3. theatre image full screen / edge-to-edge while maintaining aspect ratio
    4. switching between thumbnails by clicking or keyboard navigation

------------------------------------------------------------ */

// --- set up OBJ Object
var OBJ = OBJ || {};

// --- set up keys available
OBJ.Keys = {
    UP: 38,
    DOWN: 40,
    LEFT: 37,
    RIGHT: 39,
    ESCAPE: 27,
    SPACE: 32,
    BACKSPACE: 8,
    DELETE: 46,
    END: 35,
    HOME: 36,
    PAGEDOWN: 34,
    PAGEUP: 33,
    RETURN: 13,
    TAB: 9
};
(function($) {
    $.fn.nextWrap = function() {
        var $next = this.next();
        return ($next.length === 0) ? this.siblings().first() : $next;
    };

    $.fn.prevWrap = function() {
        var $prev = this.prev();
        return ($prev.length === 0) ? this.siblings().last() : $prev;
    };

    $.fn.preload = function() {
        this.each(function(){
            $('<img/>')[0].src = this;
        });
    }

    $(document).ready(function(){

        // --- set up variables
        var $theatre     = $('.modal-theatre'),
            $gallery     = $('.gallery-container'),
            $theatreImage = $theatre.find('.theatre-image');

        var handleImageClick = function(e){
            e.preventDefault();

            var $this = $(this),
                theatreImgSrc = $this.attr('href'),
                thumbsContainer = $this.closest('.theatre-thumbs'),
                allThumbs = thumbsContainer.children();

            switchActiveThumb($this.parent());

            setTheatreImage(theatreImgSrc);
        };

        var handleKeyPress = function(e) {

            var activeThumb = $theatre.find('.thumb-active'),
                prevThumb   = activeThumb.prevWrap(),
                nextThumb   = activeThumb.nextWrap();

            if(e.keyCode ===...