The original lightbox script, finally on github. http://lokeshdhakar.com/projects/lightbox2/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

354 lines
11KB

  1. ###
  2. Lightbox v2.51
  3. by Lokesh Dhakar - http://www.lokeshdhakar.com
  4. For more information, visit:
  5. http://lokeshdhakar.com/projects/lightbox2/
  6. Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
  7. - free for use in both personal and commercial projects
  8. - attribution requires leaving author name, author link, and the license info intact
  9. Thanks
  10. - Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), and Thomas Fuchs(mir.aculo.us) for ideas, libs, and snippets.
  11. - Artemy Tregubenko (arty.name) for cleanup and help in updating to latest proto-aculous in v2.05.
  12. Table of Contents
  13. =================
  14. LightboxOptions
  15. Lightbox
  16. - constructor
  17. - init
  18. - enable
  19. - build
  20. - start
  21. - changeImage
  22. - sizeContainer
  23. - showImage
  24. - updateNav
  25. - updateDetails
  26. - preloadNeigbhoringImages
  27. - enableKeyboardNav
  28. - disableKeyboardNav
  29. - keyboardAction
  30. - end
  31. options = new LightboxOptions()
  32. lightbox = new Lightbox options
  33. ###
  34. # Use local alias
  35. $ = jQuery
  36. class LightboxOptions
  37. constructor: ->
  38. @fadeDuration = 500
  39. @fileLoadingImage = 'img/loading.gif'
  40. @fileCloseImage = 'img/close.png'
  41. @labelImage = "Image" # Change to localize to non-english language
  42. @labelOf = "of"
  43. @resizeDuration = 700
  44. @showImageNumberLabel = true
  45. @wrapAround = false
  46. class Lightbox
  47. constructor: (@options) ->
  48. @album = []
  49. @currentImageIndex = undefined
  50. @init()
  51. init: ->
  52. @enable()
  53. @build()
  54. # Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes
  55. # that contain 'lightbox'. When these are clicked, start lightbox.
  56. enable: ->
  57. $('body').on 'click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', (e) =>
  58. @start $(e.currentTarget)
  59. false
  60. # Build html for the lightbox and the overlay.
  61. # Attach event handlers to the new DOM elements. click click click
  62. build: ->
  63. $("<div id='lightboxOverlay'></div><div id='lightbox'><div class='lb-outerContainer'><div class='lb-container'><img class='lb-image' src='' ><div class='lb-nav'><a class='lb-prev' href='' ></a><a class='lb-next' href='' ></a></div><div class='lb-loader'><a class='lb-cancel'><img src='" + @options.fileLoadingImage + "'></a></div></div></div><div class='lb-dataContainer'><div class='lb-data'><div class='lb-details'><span class='lb-caption'></span><span class='lb-number'></span></div><div class='lb-closeContainer'><a class='lb-close'><img src='" + @options.fileCloseImage + "'></a></div></div></div></div>").appendTo($('body'));
  64. # Attach event handlers to the newly minted DOM elements
  65. $('#lightboxOverlay')
  66. .hide()
  67. .on 'click', () =>
  68. @end()
  69. return false
  70. $lightbox = $('#lightbox')
  71. $lightbox
  72. .hide()
  73. .on 'click', (e) =>
  74. if $(e.target).attr('id') == 'lightbox' then @end()
  75. return false
  76. $lightbox.find('.lb-outerContainer').on 'click', (e) =>
  77. if $(e.target).attr('id') == 'lightbox' then @end()
  78. return false
  79. $lightbox.find('.lb-prev').on 'click', () =>
  80. if @currentImageIndex == 0
  81. @changeImage @album.length - 1
  82. else
  83. @changeImage @currentImageIndex - 1
  84. return false
  85. $lightbox.find('.lb-next').on 'click', () =>
  86. if @currentImageIndex == @album.length - 1
  87. @changeImage 0
  88. else
  89. @changeImage @currentImageIndex + 1
  90. return false
  91. $lightbox.find('.lb-loader, .lb-close').on 'click', () =>
  92. @end()
  93. return false
  94. return
  95. # Show overlay and lightbox. If the image is part of a set, add siblings to album array.
  96. start: ($link) ->
  97. $(window).on "resize", @sizeOverlay
  98. $('select, object, embed').css visibility: "hidden"
  99. $('#lightboxOverlay')
  100. .width( $(document).width())
  101. .height( $(document).height() )
  102. .fadeIn( @options.fadeDuration )
  103. @album = []
  104. imageNumber = 0
  105. # Supporting both data-lightbox attribute and rel attribute implementations
  106. dataLightboxValue = $link.attr 'data-lightbox'
  107. if dataLightboxValue
  108. for a, i in $( $link.prop("tagName") + '[data-lightbox="' + dataLightboxValue + '"]')
  109. @album.push link: $(a).attr('href'), title: $(a).attr('title')
  110. if $(a).attr('href') == $link.attr('href')
  111. imageNumber = i
  112. else
  113. if $link.attr('rel') == 'lightbox'
  114. # If image is not part of a set
  115. @album.push link: $link.attr('href'), title: $link.attr('title')
  116. else
  117. # Image is part of a set
  118. for a, i in $( $link.prop("tagName") + '[rel="' + $link.attr('rel') + '"]')
  119. @album.push link: $(a).attr('href'), title: $(a).attr('title')
  120. if $(a).attr('href') == $link.attr('href')
  121. imageNumber = i
  122. # Position lightbox
  123. $window = $(window)
  124. top = $window.scrollTop() + $window.height()/10
  125. left = $window.scrollLeft()
  126. $lightbox = $('#lightbox')
  127. $lightbox
  128. .css
  129. top: top + 'px'
  130. left: left + 'px'
  131. .fadeIn( @options.fadeDuration)
  132. @changeImage(imageNumber)
  133. return
  134. # Hide most UI elements in preparation for the animated resizing of the lightbox.
  135. changeImage: (imageNumber) ->
  136. @disableKeyboardNav()
  137. $lightbox = $('#lightbox')
  138. $image = $lightbox.find('.lb-image')
  139. @sizeOverlay()
  140. $('#lightboxOverlay').fadeIn( @options.fadeDuration )
  141. $('.lb-loader').fadeIn 'slow'
  142. $lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide()
  143. $lightbox.find('.lb-outerContainer').addClass 'animating'
  144. # When image to show is preloaded, we send the width and height to sizeContainer()
  145. preloader = new Image()
  146. preloader.onload = () =>
  147. $image.attr 'src', @album[imageNumber].link
  148. # Bug fix by Andy Scott
  149. $image.width = preloader.width
  150. $image.height = preloader.height
  151. # End of bug fix
  152. @sizeContainer preloader.width, preloader.height
  153. preloader.src = @album[imageNumber].link
  154. @currentImageIndex = imageNumber
  155. return
  156. # Stretch overlay to fit the document
  157. sizeOverlay: () ->
  158. $('#lightboxOverlay')
  159. .width( $(document).width())
  160. .height( $(document).height() )
  161. # Animate the size of the lightbox to fit the image we are showing
  162. sizeContainer: (imageWidth, imageHeight) ->
  163. $lightbox = $('#lightbox')
  164. $outerContainer = $lightbox.find('.lb-outerContainer')
  165. oldWidth = $outerContainer.outerWidth()
  166. oldHeight = $outerContainer.outerHeight()
  167. $container = $lightbox.find('.lb-container')
  168. containerTopPadding = parseInt $container.css('padding-top'), 10
  169. containerRightPadding = parseInt $container.css('padding-right'), 10
  170. containerBottomPadding = parseInt $container.css('padding-bottom'), 10
  171. containerLeftPadding = parseInt $container.css('padding-left'), 10
  172. newWidth = imageWidth + containerLeftPadding + containerRightPadding
  173. newHeight = imageHeight + containerTopPadding + containerBottomPadding
  174. # Animate just the width, just the height, or both, depending on what is different
  175. if newWidth != oldWidth && newHeight != oldHeight
  176. $outerContainer.animate
  177. width: newWidth,
  178. height: newHeight
  179. , @options.resizeDuration, 'swing'
  180. else if newWidth != oldWidth
  181. $outerContainer.animate
  182. width: newWidth
  183. , @options.resizeDuration, 'swing'
  184. else if newHeight != oldHeight
  185. $outerContainer.animate
  186. height: newHeight
  187. , @options.resizeDuration, 'swing'
  188. # Wait for resize animation to finsh before showing the image
  189. setTimeout =>
  190. $lightbox.find('.lb-dataContainer').width(newWidth)
  191. $lightbox.find('.lb-prevLink').height(newHeight)
  192. $lightbox.find('.lb-nextLink').height(newHeight)
  193. @showImage()
  194. return
  195. , @options.resizeDuration
  196. return
  197. # Display the image and it's details and begin preload neighboring images.
  198. showImage: ->
  199. $lightbox = $('#lightbox')
  200. $lightbox.find('.lb-loader').hide()
  201. $lightbox.find('.lb-image').fadeIn 'slow'
  202. @updateNav()
  203. @updateDetails()
  204. @preloadNeighboringImages()
  205. @enableKeyboardNav()
  206. return
  207. # Display previous and next navigation if appropriate.
  208. updateNav: ->
  209. $lightbox = $('#lightbox')
  210. $lightbox.find('.lb-nav').show()
  211. if @album.length > 1
  212. if @options.wrapAround
  213. $lightbox.find('.lb-prev, .lb-next').show()
  214. else
  215. if @currentImageIndex > 0 then $lightbox.find('.lb-prev').show()
  216. if @currentImageIndex < @album.length - 1 then $lightbox.find('.lb-next').show()
  217. return
  218. # Display caption, image number, and closing button.
  219. updateDetails: ->
  220. $lightbox = $('#lightbox')
  221. if typeof @album[@currentImageIndex].title != 'undefined' && @album[@currentImageIndex].title != ""
  222. $lightbox.find('.lb-caption')
  223. .html( @album[@currentImageIndex].title)
  224. .fadeIn('fast')
  225. if @album.length > 1 && @options.showImageNumberLabel
  226. $lightbox.find('.lb-number')
  227. .text( @options.labelImage + ' ' + (@currentImageIndex + 1) + ' ' + @options.labelOf + ' ' + @album.length)
  228. .fadeIn('fast')
  229. else
  230. $lightbox.find('.lb-number').hide()
  231. $lightbox.find('.lb-outerContainer').removeClass 'animating'
  232. $lightbox.find('.lb-dataContainer')
  233. .fadeIn @resizeDuration, () =>
  234. @sizeOverlay()
  235. return
  236. # Preload previous and next images in set.
  237. preloadNeighboringImages: ->
  238. if @album.length > @currentImageIndex + 1
  239. preloadNext = new Image()
  240. preloadNext.src = @album[@currentImageIndex + 1].link
  241. if @currentImageIndex > 0
  242. preloadPrev = new Image()
  243. preloadPrev.src = @album[@currentImageIndex - 1].link
  244. return
  245. enableKeyboardNav: ->
  246. $(document).on 'keyup.keyboard', $.proxy( @keyboardAction, this)
  247. return
  248. disableKeyboardNav: ->
  249. $(document).off '.keyboard'
  250. return
  251. keyboardAction: (event) ->
  252. KEYCODE_ESC = 27
  253. KEYCODE_LEFTARROW = 37
  254. KEYCODE_RIGHTARROW = 39
  255. keycode = event.keyCode
  256. key = String.fromCharCode(keycode).toLowerCase()
  257. if keycode == KEYCODE_ESC || key.match(/x|o|c/)
  258. @end()
  259. else if key == 'p' || keycode == KEYCODE_LEFTARROW
  260. if @currentImageIndex != 0
  261. @changeImage @currentImageIndex - 1
  262. else if key == 'n' || keycode == KEYCODE_RIGHTARROW
  263. if @currentImageIndex != @album.length - 1
  264. @changeImage @currentImageIndex + 1
  265. return
  266. # Closing time. :-(
  267. end: ->
  268. @disableKeyboardNav()
  269. $(window).off "resize", @sizeOverlay
  270. $('#lightbox').fadeOut @options.fadeDuration
  271. $('#lightboxOverlay').fadeOut @options.fadeDuration
  272. $('select, object, embed').css visibility: "visible"
  273. $ ->
  274. options = new LightboxOptions()
  275. lightbox = new Lightbox options