jquery.fullscreenslides.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /*
  2. * Copyright Eike Send: http://eike.se/nd
  3. * License: MIT / GPLv2
  4. *
  5. * This is a jQuery plugin to generate full screen galleries.
  6. *
  7. * https://github.com/eikes/jquery.fullscreen.js
  8. */
  9. ;
  10. /*
  11. * It assumes that your images are wrapped in links like this:
  12. *
  13. * <a href="image-1-large.jpg" rel="gallery-1" title="woot">
  14. * <img src="image-1-small"/>
  15. * </a>
  16. * <a href="image-2-large.jpg" rel="gallery-1" title="woot">
  17. * <img src="image-2-small"/>
  18. * </a>
  19. * <a href="image-3-large.jpg" rel="gallery-1" title="woot">
  20. * <img src="image-3-small"/>
  21. * </a>
  22. *
  23. * You would then call it like this:
  24. *
  25. * <script src="http://code.jquery.com/jquery.js"></script>
  26. * <script src="fullscreenslides.js"></script>
  27. * <script>
  28. * $(function(){
  29. * $("img").fullscreenslides();
  30. *
  31. * // You can then use the container:
  32. * var $container = $('#fullscreenSlideshowContainer');
  33. *
  34. * // Bind to events:
  35. * $container
  36. * .bind("init", function() {
  37. *
  38. * // Do something like adding a logo and adding a UI
  39. * $container
  40. * .append('<div class="ui" id="fullscreen-close">&times;</div>')
  41. * .append('<div class="ui" id="fullscreen-loader"></div>')
  42. * .append('<div class="ui" id="fullscreen-prev">&larr;</div>')
  43. * .append('<div class="ui" id="fullscreen-next">&rarr;</div>');
  44. *
  45. * $('#fullscreen-prev').click(function(){
  46. * // You can trigger events as well:
  47. * $container.trigger("prevSlide");
  48. * });
  49. * $('#fullscreen-next').click(function(){
  50. * // You can trigger events as well:
  51. * $container.trigger("nextSlide");
  52. * });
  53. * $('#fullscreen-close').click(function(){
  54. * // You can trigger events as well:
  55. * $container.trigger("close");
  56. * });
  57. *
  58. * })
  59. * .bind("startLoading", function() {
  60. * // show spinner
  61. * })
  62. * .bind("stopLoading", function() {
  63. * // hide spinner
  64. * })
  65. * .bind("startOfSlide", function(event, slide) {
  66. * // show Caption, notice the slide element
  67. * })
  68. * .bind("stopLoading", function(event, slide) {
  69. * // hide caption
  70. * })
  71. *
  72. * });
  73. * </script>
  74. *
  75. */
  76. (function($){
  77. var $container;
  78. var attachEvents = function(){
  79. // deal with resizing the browser window and resize container
  80. $container.bind("updateSize orientationchange", function(event) {
  81. $container.height($(window).height());
  82. updateSlideSize();
  83. });
  84. // privat function to update the image size and position of a slide
  85. var updateSlideSize = function(slide) {
  86. if (slide === undefined) {
  87. var slide = $container.data("currentSlide");
  88. }
  89. if (slide && slide.$img) {
  90. var wh = $(window).height();
  91. var ww = $(window).width();
  92. // compare the window aspect ratio to the image aspect ratio
  93. // to use either maximum width or height
  94. if ((ww / wh) > (slide.$img.width() / slide.$img.height())) {
  95. slide.$img.css({
  96. "height" : wh + "px",
  97. "width" : "auto"
  98. });
  99. } else {
  100. slide.$img.css({
  101. "height" : "auto",
  102. "width" : ww + "px"
  103. });
  104. }
  105. // update margins to position in the center
  106. slide.$img.css({
  107. "margin-left" : "-" + (0.5 * slide.$img.width()) + "px",
  108. "margin-top" : "-" + (0.5 * slide.$img.height()) + "px"
  109. });
  110. }
  111. }
  112. $(window).bind("resize", function(){
  113. //todo: throttle
  114. $container.trigger("updateSize");
  115. });
  116. // Show individual slides
  117. var isLoading = false;
  118. $container.bind("showSlide", function(event, newSlide) {
  119. if (!isLoading) {
  120. var oldSlide = $container.data("currentSlide");
  121. // if it is not loaded yet then initialize the dom object and load it
  122. if (!("$img" in newSlide)) {
  123. isLoading = true;
  124. $container.trigger("startLoading");
  125. newSlide.$img = $('<img class="slide">')
  126. .css({
  127. "position" : "absolute",
  128. "left" : "50%",
  129. "top" : "50%"
  130. })
  131. .hide()
  132. // on load get the images dimensions and show it
  133. .load(function(){
  134. isLoading = false;
  135. $container.trigger("stopLoading");
  136. updateSlideSize(newSlide);
  137. changeSlide(oldSlide, newSlide);
  138. })
  139. .error(function(){
  140. isLoading = false;
  141. newSlide.error = true;
  142. $container
  143. .trigger("stopLoading")
  144. .trigger("error", newSlide);
  145. })
  146. .attr("src", newSlide.image);
  147. $container.append(newSlide.$img);
  148. } else {
  149. changeSlide(oldSlide, newSlide);
  150. }
  151. }
  152. });
  153. $container.bind("prevSlide nextSlide", function(event) {
  154. var nextID,
  155. slides = $container.data("slides"),
  156. currentSlide = $container.data("currentSlide"),
  157. currentID = currentSlide && currentSlide.id || 0;
  158. if (event.type == "nextSlide") {
  159. nextID = (currentID + 1) % slides.length;
  160. } else {
  161. nextID = (currentID - 1 + slides.length) % slides.length;
  162. }
  163. $container.trigger("showSlide", slides[nextID]);
  164. });
  165. // privat function to change between slides
  166. var changeSlide = function(oldSlide, newSlide) {
  167. if (oldSlide !== undefined) {
  168. $container.trigger("endOfSlide", oldSlide);
  169. oldSlide.$img.fadeOut();
  170. }
  171. if (newSlide.$img && !newSlide.error) {
  172. newSlide.$img.fadeIn(function(){
  173. $container.trigger("startOfSlide", newSlide);
  174. });
  175. } else {
  176. $container.trigger("startOfSlide", newSlide);
  177. }
  178. $container.data("currentSlide", newSlide);
  179. }
  180. // keyboard navigation
  181. var keyFunc = function(event) {
  182. if (event.keyCode == 27) { // ESC
  183. $container.trigger("close");
  184. }
  185. if (event.keyCode == 37) { // Left
  186. $container.trigger("prevSlide");
  187. }
  188. if (event.keyCode == 39) { // Right
  189. $container.trigger("nextSlide");
  190. }
  191. }
  192. // Close the viewer
  193. $container.bind("close", function (){
  194. var options = $container.data("options");
  195. var oldSlide = $container.data("currentSlide");
  196. oldSlide && oldSlide.$img && oldSlide.$img.hide();
  197. $container.trigger("endOfSlide", oldSlide);
  198. $(document).unbind("keydown", keyFunc);
  199. // Use the fancy new FullScreenAPI:
  200. if (options.useFullScreen) {
  201. if (document.cancelFullScreen) {
  202. document.cancelFullScreen();
  203. }
  204. if (document.mozCancelFullScreen) {
  205. $("html").css("overflow", "auto");
  206. $(document).scrollTop($container.data("mozScrollTop"));
  207. document.mozCancelFullScreen();
  208. }
  209. if (document.webkitCancelFullScreen) {
  210. document.webkitCancelFullScreen();
  211. }
  212. document.removeEventListener('fullscreenchange', changeFullScreenHandler);
  213. document.removeEventListener('mozfullscreenchange', changeFullScreenHandler);
  214. document.removeEventListener('webkitfullscreenchange', changeFullScreenHandler);
  215. } else {
  216. $container.data("hiddenElements").show();
  217. $(window).scrollTop($container.data("originalScrollTop"));
  218. }
  219. $container
  220. .removeData("currentSlide slides width height originalScrollTop hiddenElements")
  221. .hide();
  222. });
  223. // When ESC is pressed in full screen mode, the keypressed event is not
  224. // triggered, so this here catches the exit-fullscreen event:
  225. function changeFullScreenHandler(event) {
  226. if ($container.data("isFullScreen")) {
  227. $container.trigger("close");
  228. }
  229. $container.data("isFullScreen", true);
  230. }
  231. var firstrun = true;
  232. // Show a particular slide
  233. $container.bind("show", function(event, rel, slide){
  234. var options = $container.data("options");
  235. var slideshows = $container.data("slideshows");
  236. var slides = slideshows[rel];
  237. $container.data("slides", slides);
  238. $container.trigger("updateSize");
  239. $(document).bind("keydown", keyFunc);
  240. // Use the fancy new FullScreenAPI:
  241. if (options.useFullScreen) {
  242. con = $container[0];
  243. if (con.requestFullScreen) {
  244. con.requestFullScreen();
  245. document.addEventListener('fullscreenchange', changeFullScreenHandler);
  246. }
  247. if (con.mozRequestFullScreen) {
  248. con.mozRequestFullScreen();
  249. document.addEventListener('mozfullscreenchange', changeFullScreenHandler);
  250. $container.data("mozScrollTop", $(document).scrollTop());
  251. $("html").css("overflow", "hidden");
  252. }
  253. if (con.webkitRequestFullScreen) {
  254. con.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
  255. document.addEventListener('webkitfullscreenchange', changeFullScreenHandler);
  256. }
  257. $container.data("isFullScreen", false);
  258. }
  259. if (firstrun) {
  260. $container.trigger("init");
  261. firstrun = false;
  262. }
  263. if (!options.useFullScreen) {
  264. $container.data("hiddenElements", $('body > *').filter(function(){return $(this).css("display")!="none";}).hide());
  265. }
  266. if (!$container.data("originalScrollTop")) {
  267. $container.data("originalScrollTop", $(window).scrollTop());
  268. }
  269. $container.show();
  270. $container.trigger("showSlide", slide);
  271. });
  272. }
  273. $.fn.fullscreenslides = function(options) {
  274. $container = $('#fullscreenSlideshowContainer');
  275. if ($container.length == 0) {
  276. $container = $('<div id="fullscreenSlideshowContainer">').hide();
  277. $("body").append($container);
  278. attachEvents();
  279. }
  280. // initialize variables
  281. var options = $.extend({
  282. "bgColor" : "#000",
  283. "useFullScreen" : true,
  284. "startSlide" : 0
  285. }, options || {});
  286. // Check if fullScreenApi is available
  287. options.useFullScreen = options.useFullScreen && !!(
  288. $container[0].requestFullScreen ||
  289. $container[0].mozRequestFullScreen ||
  290. $container[0].webkitRequestFullScreen);
  291. $container.data("options", options);
  292. // Apply default styles
  293. $container.css({
  294. "position" : "absolute",
  295. "top" : "0px",
  296. "left" : "0px",
  297. "width" : "100%",
  298. "text-align" : "center",
  299. "background-color" : options.bgColor
  300. });
  301. var slideshows = {};
  302. // Store galleries
  303. this.each(function(){
  304. var link = $(this).parents("a")[0];
  305. if (!link.rel) link.setAttribute("rel", "__all__");
  306. var slide = {
  307. image: link.href,
  308. title: link.title,
  309. rel: link.rel
  310. };
  311. slide.data = $.extend({}, $(this).data(), $(link).data());
  312. slideshows[slide.rel] = slideshows[slide.rel] || [];
  313. slideshows[slide.rel].push(slide);
  314. slide.id = slideshows[slide.rel].length - 1;
  315. $(link).data("slide", slide);
  316. $(link).click(function(event){
  317. $container.trigger("show", [this.rel, $(this).data("slide")]);
  318. event.preventDefault();
  319. });
  320. });
  321. $container.data("slideshows", slideshows);
  322. }
  323. })(jQuery);