slick-lightbox
Version:
A lightbox wrapper for Ken's amazing slick carousel. Credits go to [kenwheeler](https://github.com/kenwheeler) for doing the [hard work](https://github.com/kenwheeler/slick).
280 lines (242 loc) • 9.98 kB
text/coffeescript
###
Slick Lightbox jQuery plugin
http://mreq.github.io/slick-lightbox/
Copyright 2014-2016 mreq https://github.com/mreq
Released under the MIT license
Documentation generated by [CoffeeDoc](http://github.com/omarkhan/coffeedoc)
http://mreq.github.io/slick-lightbox/docs/
###
class SlickLightbox
###
The core class.
###
constructor: (element, ) ->
### Binds the plugin. ###
@$element = $(element)
= false
slickLightbox = this
@$element.on 'click.slickLightbox', .itemSelector, (e) ->
e.preventDefault()
$clickedItem = $(this)
$clickedItem.blur()
if typeof slickLightbox.options.shouldOpen is 'function'
return unless slickLightbox.options.shouldOpen(slickLightbox, $clickedItem, e)
$items = slickLightbox.filterOutSlickClones slickLightbox.$element.find(slickLightbox.options.itemSelector)
slickLightbox.init $items.index($clickedItem)
init: (index) ->
### Creates the lightbox, opens it, binds events and calls `slick`. Accepts `index` of the element, that triggered it (so that we know, on which slide to start slick). ###
# ()
= true
()
()
()
(index)
()
createModalItems: ->
### Creates individual slides to be used with slick. If `options.images` array is specified, it uses it's contents, otherwise loops through elements' `options.itemSelector`. ###
lazyPlaceholder = .lazyPlaceholder || 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
itemTemplate = (source, caption, lazy) ->
if lazy == true
imgSourceParams = """ data-lazy="#{ source }" src="#{ lazyPlaceholder }" """
else
imgSourceParams = """ src="#{ source }" """
"""
<div class="slick-lightbox-slick-item">
<div class="slick-lightbox-slick-item-inner">
<img class="slick-lightbox-slick-img" #{ imgSourceParams } />
#{ caption }
</div>
</div>"""
if .images
links = $.map .images, (img) ->
itemTemplate(img, .lazy)
else
$items = @$element.find( .itemSelector)
length = $items.length
createItem = (el, index) =>
info =
index: index
length: length
caption = (el, info)
src = (el)
itemTemplate(src, caption, .lazy)
links = $.map $items, createItem
links
createModal: ->
### Creates a `slick`-friendly modal. ###
links = ()
html = """
<div class="slick-lightbox slick-lightbox-hide-init#{ if @isIE then ' slick-lightbox-ie' else '' }" style="background: #{ @options.background };">
<div class="slick-lightbox-inner">
<div class="slick-lightbox-slick slick-caption-#{ @options.captionPosition }">#{ links.join('') }</div>
<div>
<div>
"""
@$modalElement = $(html)
@$parts = {}
@$parts['closeButton'] = $( .layouts.closeButton)
@$modalElement.find('.slick-lightbox-inner').append @$parts['closeButton']
$('body').append @$modalElement
initSlick: (index) ->
### Runs slick by default, using `options.slick` if provided. If `options.slick` is a function, it gets fired instead of us initializing slick. Merges in initialSlide option. ###
# We need to start with the `index`-th item.
additional = { initialSlide: index }
additional.lazyLoad = 'ondemand' if .lazy
if .slick?
if typeof .slick is 'function'
# TODO: support element's index
= .slick @$modalElement
else
= @$modalElement.find('.slick-lightbox-slick').slick $.extend({}, .slick, additional)
else
= @$modalElement.find('.slick-lightbox-slick').slick(additional)
@$modalElement.trigger 'init.slickLightbox'
open: ->
### Opens the lightbox. ###
() if .useHistoryApi
# Fire events
@$element.trigger 'show.slickLightbox'
setTimeout (=> @$element.trigger 'shown.slickLightbox'), ()
@$modalElement.removeClass('slick-lightbox-hide-init')
close: ->
### Closes the lightbox and destroys it, maintaining the original element bindings. ###
# Fire events
@$element.trigger 'hide.slickLightbox'
setTimeout (=> @$element.trigger 'hidden.slickLightbox'), ()
@$modalElement.addClass('slick-lightbox-hide')
()
bindEvents: ->
### Binds global events. ###
# Slides size needs to be 100%, which can't be achieved easily via CSS on floated elements.
resizeSlides = =>
h = @$modalElement.find('.slick-lightbox-inner').height()
@$modalElement.find('.slick-lightbox-slick-item').height h
# max-height on the image is buggy
@$modalElement.find('.slick-lightbox-slick-img, .slick-lightbox-slick-item-inner').css 'max-height', Math.round( .imageMaxHeight*h)
$(window).on 'orientationchange.slickLightbox resize.slickLightbox', resizeSlides
if .useHistoryApi
$(window).on 'popstate.slickLightbox', => ()
@$modalElement.on 'init.slickLightbox', resizeSlides
# Destroy event triggered by other instances
@$modalElement.on 'destroy.slickLightbox', => ()
# Destroy event from unslickLightbox
@$element.on 'destroy.slickLightbox', => true
# Close button
@$parts['closeButton'].on 'click.slickLightbox touchstart.slickLightbox', (e) =>
e.preventDefault()
()
# Optional bindings
if .closeOnEscape or .navigateByKeyboard
# Close on ESC key
$(document).on 'keydown.slickLightbox', (e) =>
code = if e.keyCode then e.keyCode else e.which
if .navigateByKeyboard
if code is 37
'left'
else if code is 39
'right'
if .closeOnEscape
() if code is 27
if .closeOnBackdropClick
@$modalElement.on 'click.slickLightbox touchstart.slickLightbox', '.slick-lightbox-slick-img', (e) ->
e.stopPropagation()
@$modalElement.on 'click.slickLightbox', '.slick-lightbox-slick-item', (e) =>
e.preventDefault()
()
slideSlick: (direction) ->
### Moves the slick prev or next. ###
if direction is 'left'
.slick 'slickPrev'
else
.slick 'slickNext'
detectIE: ->
### Detects usage of IE8 and lower. ###
= false
if /MSIE (\d+\.\d+);/.test(navigator.userAgent)
ieversion = new Number(RegExp.$1) # capture x.x portion and store as a number
if ieversion < 9
= true
getElementCaption: (el, info) ->
### Returns caption for each slide based on the type of `options.caption`. ###
return '' unless .caption
c = switch typeof .caption
when 'function'
.caption(el, info)
when 'string'
$(el).data( .caption)
return """<span class="slick-lightbox-slick-caption">#{ c }</span>"""
getElementSrc: (el) ->
### Returns src for each slide image based on the type of `options.src`. ###
return switch typeof .src
when 'function'
.src(el)
when 'string'
$(el).attr( .src)
else
el.href
unbindEvents: ->
### Unbinds global events. ###
$(window).off '.slickLightbox'
$(document).off '.slickLightbox'
@$modalElement.off '.slickLightbox'
destroy: (unbindAnchors = false) ->
### Destroys the lightbox and unbinds global events. If `true` is passed as an argument, unbinds the original element as well. ###
if
()
# Let transitions take effect
setTimeout (=>
@$modalElement.remove()
), .destroyTimeout
if unbindAnchors
@$element.off '.slickLightbox'
@$element.off '.slickLightbox', .itemSelector
destroyPrevious: ->
### Destroys lightboxes currently in DOM. ###
$('body').children('.slick-lightbox').trigger 'destroy.slickLightbox'
getTransitionDuration: ->
### Detects the transition duration to know when to remove stuff from DOM etc. ###
return if
duration = @$modalElement.css('transition-duration')
if typeof duration is 'undefined'
= 500
else
= if duration.indexOf('ms') > -1 then parseFloat(duration) else parseFloat(duration) * 1000
writeHistory: ->
### Writes an empty state to the history API if supported. ###
history?.pushState?(null, null, '')
filterOutSlickClones: ($items) ->
### Removes all slick clones from the set of elements. Only does so, if the target element is a slick slider. ###
return $items unless @$element.hasClass('slick-slider')
$items = $items.filter ->
$item = $(this)
not $item.hasClass('slick-cloned') and $item.parents('.slick-cloned').length is 0
# jQuery defaults
defaults =
background: 'rgba(0,0,0,.8)'
closeOnEscape: true
closeOnBackdropClick: true
destroyTimeout: 500
itemSelector: 'a'
navigateByKeyboard: true
src: false
caption: false
captionPosition: 'dynamic'
images: false
slick: {}
useHistoryApi: false
layouts:
closeButton: """<button type="button" class="slick-lightbox-close"></button>"""
shouldOpen: null
imageMaxHeight: 0.9
lazy: false
# jQuery methods
$.fn.slickLightbox = (options) ->
### Fires the plugin. ###
options = $.extend {}, defaults, options
$(this).each ->
this.slickLightbox = new SlickLightbox this, options
return this
$.fn.unslickLightbox = ->
### Removes everything. ###
$(this).trigger('destroy.slickLightbox').each ->
this.slickLightbox = null