jquery.gallery.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /**
  2. * jquery.gallery.js
  3. * http://www.codrops.com
  4. *
  5. * Copyright 2011, Pedro Botelho / Codrops
  6. * Free to use under the MIT license.
  7. *
  8. * Date: Mon Jan 30 2012
  9. */
  10. (function( $, undefined ) {
  11. /*
  12. * Gallery object.
  13. */
  14. $.Gallery = function( options, element ) {
  15. this.$el = $( element );
  16. this._init( options );
  17. };
  18. $.Gallery.defaults = {
  19. current : 0, // index of current item
  20. autoplay : false,// slideshow on / off
  21. interval : 2000 // time between transitions
  22. };
  23. $.Gallery.prototype = {
  24. _init : function( options ) {
  25. this.options = $.extend( true, {}, $.Gallery.defaults, options );
  26. // support for 3d / 2d transforms and transitions
  27. this.support3d = Modernizr.csstransforms3d;
  28. this.support2d = Modernizr.csstransforms;
  29. this.supportTrans = Modernizr.csstransitions;
  30. this.$wrapper = this.$el.find('.dg-wrapper');
  31. this.$items = this.$wrapper.children();
  32. this.itemsCount = this.$items.length;
  33. this.$nav = this.$el.find('nav');
  34. this.$navPrev = this.$nav.find('.dg-prev');
  35. this.$navNext = this.$nav.find('.dg-next');
  36. // minimum of 3 items
  37. if( this.itemsCount < 3 ) {
  38. this.$nav.remove();
  39. return false;
  40. }
  41. this.current = this.options.current;
  42. this.isAnim = false;
  43. this.$items.css({
  44. 'opacity' : 0,
  45. 'visibility': 'hidden'
  46. });
  47. this._validate();
  48. this._layout();
  49. // load the events
  50. this._loadEvents();
  51. // slideshow
  52. if( this.options.autoplay ) {
  53. this._startSlideshow();
  54. }
  55. },
  56. _validate : function() {
  57. if( this.options.current < 0 || this.options.current > this.itemsCount - 1 ) {
  58. this.current = 0;
  59. }
  60. },
  61. _layout : function() {
  62. // current, left and right items
  63. this._setItems();
  64. // current item is not changed
  65. // left and right one are rotated and translated
  66. var leftCSS, rightCSS, currentCSS;
  67. if( this.support3d && this.supportTrans ) {
  68. leftCSS = {
  69. '-webkit-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  70. '-moz-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  71. '-o-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  72. '-ms-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  73. 'transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)'
  74. };
  75. rightCSS = {
  76. '-webkit-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  77. '-moz-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  78. '-o-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  79. '-ms-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  80. 'transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)'
  81. };
  82. leftCSS.opacity = 1;
  83. leftCSS.visibility = 'visible';
  84. rightCSS.opacity = 1;
  85. rightCSS.visibility = 'visible';
  86. }
  87. else if( this.support2d && this.supportTrans ) {
  88. leftCSS = {
  89. '-webkit-transform' : 'translate(-350px) scale(0.8)',
  90. '-moz-transform' : 'translate(-350px) scale(0.8)',
  91. '-o-transform' : 'translate(-350px) scale(0.8)',
  92. '-ms-transform' : 'translate(-350px) scale(0.8)',
  93. 'transform' : 'translate(-350px) scale(0.8)'
  94. };
  95. rightCSS = {
  96. '-webkit-transform' : 'translate(350px) scale(0.8)',
  97. '-moz-transform' : 'translate(350px) scale(0.8)',
  98. '-o-transform' : 'translate(350px) scale(0.8)',
  99. '-ms-transform' : 'translate(350px) scale(0.8)',
  100. 'transform' : 'translate(350px) scale(0.8)'
  101. };
  102. currentCSS = {
  103. 'z-index' : 999
  104. };
  105. leftCSS.opacity = 1;
  106. leftCSS.visibility = 'visible';
  107. rightCSS.opacity = 1;
  108. rightCSS.visibility = 'visible';
  109. }
  110. this.$leftItm.css( leftCSS || {} );
  111. this.$rightItm.css( rightCSS || {} );
  112. this.$currentItm.css( currentCSS || {} ).css({
  113. 'opacity' : 1,
  114. 'visibility': 'visible'
  115. }).addClass('dg-center');
  116. },
  117. _setItems : function() {
  118. this.$items.removeClass('dg-center');
  119. this.$currentItm = this.$items.eq( this.current );
  120. this.$leftItm = ( this.current === 0 ) ? this.$items.eq( this.itemsCount - 1 ) : this.$items.eq( this.current - 1 );
  121. this.$rightItm = ( this.current === this.itemsCount - 1 ) ? this.$items.eq( 0 ) : this.$items.eq( this.current + 1 );
  122. if( !this.support3d && this.support2d && this.supportTrans ) {
  123. this.$items.css( 'z-index', 1 );
  124. this.$currentItm.css( 'z-index', 999 );
  125. }
  126. // next & previous items
  127. if( this.itemsCount > 3 ) {
  128. // next item
  129. this.$nextItm = ( this.$rightItm.index() === this.itemsCount - 1 ) ? this.$items.eq( 0 ) : this.$rightItm.next();
  130. this.$nextItm.css( this._getCoordinates('outright') );
  131. // previous item
  132. this.$prevItm = ( this.$leftItm.index() === 0 ) ? this.$items.eq( this.itemsCount - 1 ) : this.$leftItm.prev();
  133. this.$prevItm.css( this._getCoordinates('outleft') );
  134. }
  135. },
  136. _loadEvents : function() {
  137. var _self = this;
  138. this.$navPrev.on( 'click.gallery', function( event ) {
  139. if( _self.options.autoplay ) {
  140. clearTimeout( _self.slideshow );
  141. _self.options.autoplay = false;
  142. }
  143. _self._navigate('prev');
  144. return false;
  145. });
  146. this.$navNext.on( 'click.gallery', function( event ) {
  147. if( _self.options.autoplay ) {
  148. clearTimeout( _self.slideshow );
  149. _self.options.autoplay = false;
  150. }
  151. _self._navigate('next');
  152. return false;
  153. });
  154. this.$wrapper.on( 'webkitTransitionEnd.gallery transitionend.gallery OTransitionEnd.gallery', function( event ) {
  155. _self.$currentItm.addClass('dg-center');
  156. _self.$items.removeClass('dg-transition');
  157. _self.isAnim = false;
  158. });
  159. },
  160. _getCoordinates : function( position ) {
  161. if( this.support3d && this.supportTrans ) {
  162. switch( position ) {
  163. case 'outleft':
  164. return {
  165. '-webkit-transform' : 'translateX(-450px) translateZ(-300px) rotateY(45deg)',
  166. '-moz-transform' : 'translateX(-450px) translateZ(-300px) rotateY(45deg)',
  167. '-o-transform' : 'translateX(-450px) translateZ(-300px) rotateY(45deg)',
  168. '-ms-transform' : 'translateX(-450px) translateZ(-300px) rotateY(45deg)',
  169. 'transform' : 'translateX(-450px) translateZ(-300px) rotateY(45deg)',
  170. 'opacity' : 0,
  171. 'visibility' : 'hidden'
  172. };
  173. break;
  174. case 'outright':
  175. return {
  176. '-webkit-transform' : 'translateX(450px) translateZ(-300px) rotateY(-45deg)',
  177. '-moz-transform' : 'translateX(450px) translateZ(-300px) rotateY(-45deg)',
  178. '-o-transform' : 'translateX(450px) translateZ(-300px) rotateY(-45deg)',
  179. '-ms-transform' : 'translateX(450px) translateZ(-300px) rotateY(-45deg)',
  180. 'transform' : 'translateX(450px) translateZ(-300px) rotateY(-45deg)',
  181. 'opacity' : 0,
  182. 'visibility' : 'hidden'
  183. };
  184. break;
  185. case 'left':
  186. return {
  187. '-webkit-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  188. '-moz-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  189. '-o-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  190. '-ms-transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  191. 'transform' : 'translateX(-350px) translateZ(-200px) rotateY(45deg)',
  192. 'opacity' : 1,
  193. 'visibility' : 'visible'
  194. };
  195. break;
  196. case 'right':
  197. return {
  198. '-webkit-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  199. '-moz-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  200. '-o-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  201. '-ms-transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  202. 'transform' : 'translateX(350px) translateZ(-200px) rotateY(-45deg)',
  203. 'opacity' : 1,
  204. 'visibility' : 'visible'
  205. };
  206. break;
  207. case 'center':
  208. return {
  209. '-webkit-transform' : 'translateX(0px) translateZ(0px) rotateY(0deg)',
  210. '-moz-transform' : 'translateX(0px) translateZ(0px) rotateY(0deg)',
  211. '-o-transform' : 'translateX(0px) translateZ(0px) rotateY(0deg)',
  212. '-ms-transform' : 'translateX(0px) translateZ(0px) rotateY(0deg)',
  213. 'transform' : 'translateX(0px) translateZ(0px) rotateY(0deg)',
  214. 'opacity' : 1,
  215. 'visibility' : 'visible'
  216. };
  217. break;
  218. };
  219. }
  220. else if( this.support2d && this.supportTrans ) {
  221. switch( position ) {
  222. case 'outleft':
  223. return {
  224. '-webkit-transform' : 'translate(-450px) scale(0.7)',
  225. '-moz-transform' : 'translate(-450px) scale(0.7)',
  226. '-o-transform' : 'translate(-450px) scale(0.7)',
  227. '-ms-transform' : 'translate(-450px) scale(0.7)',
  228. 'transform' : 'translate(-450px) scale(0.7)',
  229. 'opacity' : 0,
  230. 'visibility' : 'hidden'
  231. };
  232. break;
  233. case 'outright':
  234. return {
  235. '-webkit-transform' : 'translate(450px) scale(0.7)',
  236. '-moz-transform' : 'translate(450px) scale(0.7)',
  237. '-o-transform' : 'translate(450px) scale(0.7)',
  238. '-ms-transform' : 'translate(450px) scale(0.7)',
  239. 'transform' : 'translate(450px) scale(0.7)',
  240. 'opacity' : 0,
  241. 'visibility' : 'hidden'
  242. };
  243. break;
  244. case 'left':
  245. return {
  246. '-webkit-transform' : 'translate(-350px) scale(0.8)',
  247. '-moz-transform' : 'translate(-350px) scale(0.8)',
  248. '-o-transform' : 'translate(-350px) scale(0.8)',
  249. '-ms-transform' : 'translate(-350px) scale(0.8)',
  250. 'transform' : 'translate(-350px) scale(0.8)',
  251. 'opacity' : 1,
  252. 'visibility' : 'visible'
  253. };
  254. break;
  255. case 'right':
  256. return {
  257. '-webkit-transform' : 'translate(350px) scale(0.8)',
  258. '-moz-transform' : 'translate(350px) scale(0.8)',
  259. '-o-transform' : 'translate(350px) scale(0.8)',
  260. '-ms-transform' : 'translate(350px) scale(0.8)',
  261. 'transform' : 'translate(350px) scale(0.8)',
  262. 'opacity' : 1,
  263. 'visibility' : 'visible'
  264. };
  265. break;
  266. case 'center':
  267. return {
  268. '-webkit-transform' : 'translate(0px) scale(1)',
  269. '-moz-transform' : 'translate(0px) scale(1)',
  270. '-o-transform' : 'translate(0px) scale(1)',
  271. '-ms-transform' : 'translate(0px) scale(1)',
  272. 'transform' : 'translate(0px) scale(1)',
  273. 'opacity' : 1,
  274. 'visibility' : 'visible'
  275. };
  276. break;
  277. };
  278. }
  279. else {
  280. switch( position ) {
  281. case 'outleft' :
  282. case 'outright' :
  283. case 'left' :
  284. case 'right' :
  285. return {
  286. 'opacity' : 0,
  287. 'visibility' : 'hidden'
  288. };
  289. break;
  290. case 'center' :
  291. return {
  292. 'opacity' : 1,
  293. 'visibility' : 'visible'
  294. };
  295. break;
  296. };
  297. }
  298. },
  299. _navigate : function( dir ) {
  300. if( this.supportTrans && this.isAnim )
  301. return false;
  302. this.isAnim = true;
  303. switch( dir ) {
  304. case 'next' :
  305. this.current = this.$rightItm.index();
  306. // current item moves left
  307. this.$currentItm.addClass('dg-transition').css( this._getCoordinates('left') );
  308. // right item moves to the center
  309. this.$rightItm.addClass('dg-transition').css( this._getCoordinates('center') );
  310. // next item moves to the right
  311. if( this.$nextItm ) {
  312. // left item moves out
  313. this.$leftItm.addClass('dg-transition').css( this._getCoordinates('outleft') );
  314. this.$nextItm.addClass('dg-transition').css( this._getCoordinates('right') );
  315. }
  316. else {
  317. // left item moves right
  318. this.$leftItm.addClass('dg-transition').css( this._getCoordinates('right') );
  319. }
  320. break;
  321. case 'prev' :
  322. this.current = this.$leftItm.index();
  323. // current item moves right
  324. this.$currentItm.addClass('dg-transition').css( this._getCoordinates('right') );
  325. // left item moves to the center
  326. this.$leftItm.addClass('dg-transition').css( this._getCoordinates('center') );
  327. // prev item moves to the left
  328. if( this.$prevItm ) {
  329. // right item moves out
  330. this.$rightItm.addClass('dg-transition').css( this._getCoordinates('outright') );
  331. this.$prevItm.addClass('dg-transition').css( this._getCoordinates('left') );
  332. }
  333. else {
  334. // right item moves left
  335. this.$rightItm.addClass('dg-transition').css( this._getCoordinates('left') );
  336. }
  337. break;
  338. };
  339. this._setItems();
  340. if( !this.supportTrans )
  341. this.$currentItm.addClass('dg-center');
  342. },
  343. _startSlideshow : function() {
  344. var _self = this;
  345. this.slideshow = setTimeout( function() {
  346. _self._navigate( 'next' );
  347. if( _self.options.autoplay ) {
  348. _self._startSlideshow();
  349. }
  350. }, this.options.interval );
  351. },
  352. destroy : function() {
  353. this.$navPrev.off('.gallery');
  354. this.$navNext.off('.gallery');
  355. this.$wrapper.off('.gallery');
  356. }
  357. };
  358. var logError = function( message ) {
  359. if ( this.console ) {
  360. console.error( message );
  361. }
  362. };
  363. $.fn.gallery = function( options ) {
  364. if ( typeof options === 'string' ) {
  365. var args = Array.prototype.slice.call( arguments, 1 );
  366. this.each(function() {
  367. var instance = $.data( this, 'gallery' );
  368. if ( !instance ) {
  369. logError( "cannot call methods on gallery prior to initialization; " +
  370. "attempted to call method '" + options + "'" );
  371. return;
  372. }
  373. if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
  374. logError( "no such method '" + options + "' for gallery instance" );
  375. return;
  376. }
  377. instance[ options ].apply( instance, args );
  378. });
  379. }
  380. else {
  381. this.each(function() {
  382. var instance = $.data( this, 'gallery' );
  383. if ( !instance ) {
  384. $.data( this, 'gallery', new $.Gallery( options, this ) );
  385. }
  386. });
  387. }
  388. return this;
  389. };
  390. })( jQuery );