Source: dynamic-image-gallery.js

/**
 * @function createImageGallery
 * @summary
 * Use this function to create an image gallery with images that load from a manifest after initial ad load.
 * @description
 * For full documentation, check out the:
 *   <a target="_blank" href="https://wiki.tremorvideodsp.com/pages/viewpage.action?pageId=70228045">Dynamic Image Gallery Wiki Page</a>
 *
 * This function returns an object with an imageArray property.  The array is initially empty,
 * but will be populated with each image specified in the input parameters opts.manifest and opts.src
 * after they are loaded.
 *
 * All contents of imageContainer will be automatically removed after the images are loaded, before the
 * complete event is emitted. After that, the only children of imageContainer are the movieClips of each image.
 *
 * Required Parameters:
 * opts.eventLabel is a string prepended to event names
 * opts.manifest is an array of objects, where each object must contain a key "src"
 * opts.imageContainer is a movie clip which will (eventually) contain all of the image movie clips once they have all loaded
 *
 * Returns:
 * {imageArray: array}
 *
 * Note:
 * * you can store other key on each item in the manifest array, such as a "caption", which may be
 * useful when you display your images
 * * the imageContainer will be emptied just before the complete event is emitted
 *
 * The following event names are emitted:
 * ```
 *   eventLabel + '-IMAGE_GALLERY_COMPLETE'
 *   eventLabel + '-IMAGE_GALLERY_ERROR'
 *   eventLabel + '-IMAGE_GALLERY_PROGRESS'
 *   eventLabel + '-IMAGE_GALLERY_FILE_LOAD'
 * ```
 * The COMPLETE event is called with these 2 arguments
 * ```
 *   (evt, imageArray)
 * ```
 * The other events only pass the single parameter evt.
 *
 * Sample Usage:
 * ```
 *  var myImages = window.$b.snippets.createImageGallery({
 *    eventLabel: 'KiaSedan',
 *    manifest: [{src: 'images/01.jpg'}, {src: 'images/02.jpg'}],
 *    imageContainer: this.container, (or whatever you named the instance of the movie clip)
 *  }).imageArray
 *  var completeFunction = function (evt, imageArray) {
 *    // Do stuff with imageArray like imageArray[0].visible = false, imageArray[1].visible = true
 *  }
 *  window.$b.on('KiaSedan-IMAGE_GALLERY_COMPLETE', completeFunction)
 * ```
 * @param opts {Object}
 * @param {string} opts.eventLabel a string prepended to the event names
 * @param opts.manifest {Array<{Object}>} Each object must have {src: "URL-or-file-path-of-image"}
 * @param opts.imageContainer {createjs.MovieClip} Movie Clip that will contain your images
 * @param opts.root {string=} useful if all images are hosted on the same external web site
 */

function createImageGallery (opts) {
  if (!opts.eventLabel || typeof opts.eventLabel !== 'string') {
    console.error('You must provide a (string) label for the event prefix.')
    return
  }

  var eventLabel = opts.eventLabel
  var completeEvent = eventLabel + '-IMAGE_GALLERY_COMPLETE'
  var errorEvent = eventLabel + '-IMAGE_GALLERY_ERROR'
  var progressEvent = eventLabel + '-IMAGE_GALLERY_PROGRESS'
  var fileLoadEvent = eventLabel + '-IMAGE_GALLERY_FILE_LOAD'
  var message
  if ((typeof opts !== 'object') || (!(opts.manifest instanceof Array))) {
    message = 'createImageGallery must be passed an object with a key of "manifest" which contains an array of objects'
    console.log(errorEvent, message)
    window.$b.emit(errorEvent, message)
    return
  }

  if (!(opts.imageContainer instanceof window.createjs.MovieClip)) {
    message = 'You must provide an imageContainer (movie clip) to hold all of your images once they are loaded'
    console.log(errorEvent, message)
    window.$b.emit(errorEvent, message)
    return
  }

  // This will be the main object that will store all of the sub-properties of your gallery
  var imageGallery = {}

  imageGallery.manifest = opts.manifest
  imageGallery.imageContainer = opts.imageContainer

  // Optional Param (only used if you want the snippet to automatically control your progress bar)
  imageGallery.progressBar = opts.progressBar || null

  // imageGallery.imageArray will contain all images once they are fully loaded.
  imageGallery.imageArray = []

  var manifest = imageGallery.manifest
  var imageContainer = imageGallery.imageContainer
  var progressBar = imageGallery.progressBar
  var imageArray = imageGallery.imageArray

  // Checks if blink is available and if it does attaches the baseUrl
  var baseUrl = ''
  if (typeof window.$b === 'object') {
    baseUrl = window.$b.baseUrl
  }

  var root = opts.root === '' ? '' : opts.root || baseUrl || ''

  // Handle Individual File Loaded
  // ==========================================================================================
  imageGallery.handleFileLoad = function (evt) {
    var item = evt.item
    var type = item.type
    if (type === createjs.LoadQueue.IMAGE) {
      var bmp = new createjs.Bitmap(evt.result)
      var mc = new createjs.MovieClip('single', 0, false, null)
      mc.addChild(bmp)

      // If you need to add additional custom parameters to your images, you can add them to that particular image object in the manifest.
      // The contents of the manifest for that image are copied over to the image movie clip when it is created.
      mc.manifestItem = item

      imageGallery.imageArray.push(mc)

      window.$b.emit(fileLoadEvent, evt)
    }
  } // END - imageGallery.handleFileLoad
  // ===========================================================================================

  // Handle Progress (Update Progress)
  // ==========================================================================================
  imageGallery.handleProgress = function (evt) {
    // If progressBar is provided scale it on the x-axis
    if (progressBar) {
      progressBar.scaleX = evt.progress
    }
    window.$b.emit(progressEvent, evt)
  } // END - imageGallery.handleProgress

  // Handle Error
  // ==========================================================================================
  imageGallery.handleError = function (evt) {
    window.$b.emit(errorEvent, evt)
  } // END - imageGallery.handleError
  // ==========================================================================================

  // Handle All Files Loaded (Complete) and Initialize Gallery
  // ==========================================================================================
  imageGallery.handleComplete = function (evt) {
    // Remove all existing child elements of the imageContainer.
    // This removes the shape that exist inside the imageContainer, the one used for setting its size.
    var children = imageContainer.children
    while (children.length) {
      imageContainer.removeChildAt(0)
    }

    var containerAspectRatio = imageContainer.nominalBounds.width / imageContainer.nominalBounds.height
    var containerCenter = {
      x: imageContainer.nominalBounds.x + imageContainer.nominalBounds.width / 2,
      y: imageContainer.nominalBounds.y + imageContainer.nominalBounds.height / 2
    }

    // Adds new image movie clips to the imageContainer
    for (var j = imageArray.length - 1; j >= 0; j--) {
      var addImg = imageContainer.addChild(imageArray[j])

      // Gets New MovieClip Width & Height
      var ImgWidth = addImg.getBounds().width
      var ImgHeight = addImg.getBounds().height
      var imageAspectRatio = ImgWidth / ImgHeight

      // Scales New MovieClips to fit Parent Container
      var scale
      if (imageAspectRatio < containerAspectRatio) {
        scale = imageContainer.nominalBounds.height / ImgHeight
      } else {
        scale = imageContainer.nominalBounds.width / ImgWidth
      }
      addImg.scaleX = scale
      addImg.scaleY = scale

      // Set Registration Point of New Image to Center (After Scaling is Complete)
      addImg.regX = (ImgWidth / 2)
      addImg.regY = (ImgHeight / 2)

      addImg.x = containerCenter.x
      addImg.y = containerCenter.y

      // This stores the centered x/y of each image so it can be used later
      addImg.center = {
        x: addImg.x,
        y: addImg.y
      }
    } // END - for (var j = 0; j < imageArray.length; j++)

    window.$b.emit(completeEvent, evt, imageArray)
  }

  imageGallery.queue = new createjs.LoadQueue(true, root)
  imageGallery.queue.on('error', imageGallery.handleError, this)
  imageGallery.queue.on('fileload', imageGallery.handleFileLoad, this)
  imageGallery.queue.on('complete', imageGallery.handleComplete, this)
  imageGallery.queue.on('progress', imageGallery.handleProgress, this)
  imageGallery.queue.loadManifest(manifest)

  return imageGallery
}

window.$b = window.$b || {}
window.$b.snippets = window.$b.snippets || {}
var snippets = window.$b.snippets
snippets.createImageGallery = createImageGallery