jquery.vegas.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. // ----------------------------------------------------------------------------
  2. // Vegas – Fullscreen Backgrounds and Slideshows with jQuery.
  3. // Licensed under the MIT license.
  4. // http://vegas.jaysalvat.com/
  5. // ----------------------------------------------------------------------------
  6. // Copyright (C) 2013 Jay Salvat
  7. // http://jaysalvat.com/
  8. // ----------------------------------------------------------------------------
  9. (function($) {
  10. var $background = $('<img />').addClass('vegas-background'),
  11. $overlay = $('<div />').addClass('vegas-overlay'),
  12. $loading = $('<div />').addClass('vegas-loading'),
  13. $current = $(),
  14. paused = null,
  15. backgrounds = [],
  16. step = 0,
  17. delay = 5000,
  18. walk = function() {},
  19. timer,
  20. isIPhone = (navigator.userAgent.match(/iPod|iPhone/i)),
  21. IPhoneHeightOffset = 76,
  22. methods = {
  23. // Init plugin
  24. init : function(settings) {
  25. var options = {
  26. src: getBackground(),
  27. align: 'center',
  28. valign: 'center',
  29. fade: 0,
  30. loading: true,
  31. load: function() {},
  32. complete: function() {}
  33. };
  34. $.extend(options, $.vegas.defaults.background, settings);
  35. if (options.loading) {
  36. loading();
  37. }
  38. var $new = $background.clone();
  39. $new.css({
  40. 'position': 'fixed',
  41. 'left': '0px',
  42. 'top': '0px'
  43. })
  44. .bind('load', function() {
  45. if ($new == $current) {
  46. return;
  47. }
  48. $(window).bind('load resize.vegas', function(e) {
  49. resize($new, options);
  50. });
  51. if ($current.is('img')) {
  52. $current.stop();
  53. $new.hide()
  54. .insertAfter($current)
  55. .fadeIn(options.fade, function() {
  56. $('.vegas-background')
  57. .not(this)
  58. .remove();
  59. $('body').trigger('vegascomplete', [this, step - 1]);
  60. options.complete.apply($new, [step - 1]);
  61. });
  62. } else {
  63. $new.hide()
  64. .prependTo('body')
  65. .fadeIn(options.fade, function() {
  66. $('body').trigger('vegascomplete', [this, step - 1]);
  67. options.complete.apply(this, [step - 1]);
  68. });
  69. }
  70. $current = $new;
  71. resize($current, options);
  72. if (options.loading) {
  73. loaded();
  74. }
  75. $('body').trigger('vegasload', [$current.get(0), step - 1]);
  76. options.load.apply($current.get(0), [step - 1]);
  77. if (step) {
  78. $('body').trigger('vegaswalk', [$current.get(0), step - 1]);
  79. options.walk.apply($current.get(0), [step - 1]);
  80. }
  81. })
  82. .attr('src', options.src);
  83. return $.vegas;
  84. },
  85. // Destroy background and/or overlay
  86. destroy: function(what) {
  87. if (!what || what == 'background') {
  88. $('.vegas-background, .vegas-loading').remove();
  89. $(window).unbind('*.vegas');
  90. $current = $();
  91. }
  92. if (!what || what == 'overlay') {
  93. $('.vegas-overlay').remove();
  94. }
  95. clearInterval(timer);
  96. return $.vegas;
  97. },
  98. // Display the pattern overlay
  99. overlay: function(settings) {
  100. var options = {
  101. src: null,
  102. opacity: null
  103. };
  104. $.extend(options, $.vegas.defaults.overlay, settings);
  105. $overlay.remove();
  106. $overlay
  107. .css({
  108. 'margin': '0',
  109. 'padding': '0',
  110. 'position': 'fixed',
  111. 'left': '0px',
  112. 'top': '0px',
  113. 'width': '100%',
  114. 'height': '100%'
  115. });
  116. if (options.src === false) {
  117. $overlay.css('backgroundImage', 'none');
  118. }
  119. if (options.src) {
  120. $overlay.css('backgroundImage', 'url(' + options.src + ')');
  121. }
  122. if (options.opacity) {
  123. $overlay.css('opacity', options.opacity);
  124. }
  125. $overlay.prependTo('body');
  126. return $.vegas;
  127. },
  128. // Start/restart slideshow
  129. slideshow: function(settings, keepPause) {
  130. var options = {
  131. step: step,
  132. delay: delay,
  133. preload: false,
  134. loading: true,
  135. backgrounds: backgrounds,
  136. walk: walk
  137. };
  138. $.extend(options, $.vegas.defaults.slideshow, settings);
  139. if (options.backgrounds != backgrounds) {
  140. if (!settings.step) {
  141. options.step = 0;
  142. }
  143. if (!settings.walk) {
  144. options.walk = function() {};
  145. }
  146. if (options.preload) {
  147. $.vegas('preload', options.backgrounds);
  148. }
  149. }
  150. backgrounds = options.backgrounds;
  151. delay = options.delay;
  152. step = options.step;
  153. walk = options.walk;
  154. clearInterval(timer);
  155. if (!backgrounds.length) {
  156. return $.vegas;
  157. }
  158. var doSlideshow = function() {
  159. if (step < 0) {
  160. step = backgrounds.length - 1;
  161. }
  162. if (step >= backgrounds.length || !backgrounds[step - 1]) {
  163. step = 0;
  164. }
  165. var settings = backgrounds[step++];
  166. settings.walk = options.walk;
  167. settings.loading = options.loading;
  168. if (typeof(settings.fade) == 'undefined') {
  169. settings.fade = options.fade;
  170. }
  171. if (settings.fade > options.delay) {
  172. settings.fade = options.delay;
  173. }
  174. $.vegas(settings);
  175. };
  176. doSlideshow();
  177. if (!keepPause) {
  178. paused = false;
  179. $('body').trigger('vegasstart', [$current.get(0), step - 1]);
  180. }
  181. if (!paused) {
  182. timer = setInterval(doSlideshow, options.delay);
  183. }
  184. return $.vegas;
  185. },
  186. // Jump to the next background in the current slideshow
  187. next: function() {
  188. var from = step;
  189. if (step) {
  190. $.vegas('slideshow', { step: step }, true);
  191. $('body').trigger('vegasnext', [$current.get(0), step - 1, from - 1]);
  192. }
  193. return $.vegas;
  194. },
  195. // Jump to the previous background in the current slideshow
  196. previous: function() {
  197. var from = step;
  198. if (step) {
  199. $.vegas('slideshow', { step: step - 2 }, true);
  200. $('body').trigger('vegasprevious', [$current.get(0), step - 1, from - 1]);
  201. }
  202. return $.vegas;
  203. },
  204. // Jump to a specific background in the current slideshow
  205. jump: function(s) {
  206. var from = step;
  207. if (step) {
  208. $.vegas('slideshow', { step: s }, true);
  209. $('body').trigger('vegasjump', [$current.get(0), step - 1, from - 1]);
  210. }
  211. return $.vegas;
  212. },
  213. // Stop slideshow
  214. stop: function() {
  215. var from = step;
  216. step = 0;
  217. paused = null;
  218. clearInterval(timer);
  219. $('body').trigger('vegasstop', [$current.get(0), from - 1]);
  220. return $.vegas;
  221. },
  222. // Pause slideShow
  223. pause: function() {
  224. paused = true;
  225. clearInterval(timer);
  226. $('body').trigger('vegaspause', [$current.get(0), step - 1]);
  227. return $.vegas;
  228. },
  229. // Get some useful values or objects
  230. get: function(what) {
  231. if (what === null || what == 'background') {
  232. return $current.get(0);
  233. }
  234. if (what == 'overlay') {
  235. return $overlay.get(0);
  236. }
  237. if (what == 'step') {
  238. return step - 1;
  239. }
  240. if (what == 'paused') {
  241. return paused;
  242. }
  243. },
  244. // Preload an array of backgrounds
  245. preload: function(backgrounds) {
  246. var cache = [];
  247. for(var i in backgrounds) {
  248. if (backgrounds[i].src) {
  249. var cacheImage = document.createElement('img');
  250. cacheImage.src = backgrounds[i].src;
  251. cache.push(cacheImage);
  252. }
  253. }
  254. return $.vegas;
  255. }
  256. };
  257. // Resize the background
  258. function resize($img, settings) {
  259. var options = {
  260. align: 'center',
  261. valign: 'center'
  262. };
  263. $.extend(options, settings);
  264. if($img.height() === 0) {
  265. $img.load(function(){
  266. resize($(this), settings);
  267. });
  268. return;
  269. }
  270. var vp = getViewportSize(),
  271. ww = vp.width,
  272. wh = vp.height,
  273. iw = $img.width(),
  274. ih = $img.height(),
  275. rw = wh / ww,
  276. ri = ih / iw,
  277. newWidth, newHeight,
  278. newLeft, newTop,
  279. properties;
  280. if (rw > ri) {
  281. newWidth = wh / ri;
  282. newHeight = wh;
  283. } else {
  284. newWidth = ww;
  285. newHeight = ww * ri;
  286. }
  287. properties = {
  288. 'width': newWidth + 'px',
  289. 'height': newHeight + 'px',
  290. 'top': 'auto',
  291. 'bottom': 'auto',
  292. 'left': 'auto',
  293. 'right': 'auto'
  294. };
  295. if (!isNaN(parseInt(options.valign, 10))) {
  296. properties.top = (0 - (newHeight - wh) / 100 * parseInt(options.valign, 10)) + 'px';
  297. } else if (options.valign == 'top') {
  298. properties.top = 0;
  299. } else if (options.valign == 'bottom') {
  300. properties.bottom = 0;
  301. } else {
  302. properties.top = (wh - newHeight) / 2;
  303. }
  304. if (!isNaN(parseInt(options.align, 10))) {
  305. properties.left = (0 - (newWidth - ww) / 100 * parseInt(options.align, 10)) + 'px';
  306. } else if (options.align == 'left') {
  307. properties.left = 0;
  308. } else if (options.align == 'right') {
  309. properties.right = 0;
  310. } else {
  311. properties.left = (ww - newWidth) / 2 ;
  312. }
  313. $img.css(properties);
  314. }
  315. // Display the loading indicator
  316. function loading() {
  317. $loading.prependTo('body').fadeIn();
  318. }
  319. // Hide the loading indicator
  320. function loaded() {
  321. $loading.fadeOut('fast', function() {
  322. $(this).remove();
  323. });
  324. }
  325. // Get the background image from the body
  326. function getBackground() {
  327. if ($('body').css('backgroundImage')) {
  328. return $('body').css('backgroundImage').replace(/url\("?(.*?)"?\)/i, '$1');
  329. }
  330. }
  331. // Get the real viewport size
  332. function getViewportSize(){
  333. var elmt = window,
  334. prop = 'inner';
  335. if (!('innerWidth' in window)){
  336. elmt = document.documentElement || document.body;
  337. prop = 'client';
  338. }
  339. return {
  340. width: elmt[prop + "Width"],
  341. height: isIPhone ? elmt[prop + "Height"] + IPhoneHeightOffset : elmt[prop + "Height"]
  342. };
  343. }
  344. // The plugin
  345. $.vegas = function(method) {
  346. if (methods[method]) {
  347. return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
  348. } else if (typeof method === 'object' || !method) {
  349. return methods.init.apply(this, arguments);
  350. } else {
  351. $.error('Method ' + method + ' does not exist');
  352. }
  353. };
  354. // Global parameters
  355. $.vegas.defaults = {
  356. background: {
  357. // src: string
  358. // align: string/int
  359. // valign: string/int
  360. // fade: int
  361. // loading bool
  362. // load: function
  363. // complete: function
  364. },
  365. slideshow: {
  366. // fade: null
  367. // step: int
  368. // delay: int
  369. // backgrounds: array
  370. // loading bool
  371. // preload: bool
  372. // walk: function
  373. },
  374. overlay: {
  375. // src: string
  376. // opacity: float
  377. }
  378. };
  379. })(jQuery);