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.

327 lines
9.7 KiB

  1. /* ******************************
  2. Semantic Module: Carousel
  3. Author: Jack Lukic
  4. Notes: First Commit May 28, 2013
  5. A carousel alternates between
  6. several pieces of content in sequence.
  7. ****************************** */
  8. ;(function ( $, window, document, undefined ) {
  9. $.fn.carousel = function(parameters) {
  10. var
  11. $allModules = $(this),
  12. settings = $.extend(true, {}, $.fn.carousel.settings, parameters),
  13. eventNamespace = '.' + settings.namespace,
  14. moduleNamespace = 'module-' + settings.namespace,
  15. moduleSelector = $allModules.selector || '',
  16. time = new Date().getTime(),
  17. performance = [],
  18. query = arguments[0],
  19. methodInvoked = (typeof query == 'string'),
  20. queryArguments = [].slice.call(arguments, 1),
  21. invokedResponse
  22. ;
  23. $allModules
  24. .each(function() {
  25. var
  26. $module = $(this),
  27. $arrows = $(settings.selector.arrows),
  28. $leftArrow = $(settings.selector.leftArrow),
  29. $rightArrow = $(settings.selector.rightArrow),
  30. $content = $(settings.selector.content),
  31. $navigation = $(settings.selector.navigation),
  32. $navItem = $(settings.selector.navItem),
  33. selector = $module.selector || '',
  34. element = this,
  35. instance = $module.data('module-' + settings.namespace),
  36. className = settings.className,
  37. namespace = settings.namespace,
  38. errors = settings.errors,
  39. module
  40. ;
  41. module = {
  42. initialize: function() {
  43. module.openingAnimation();
  44. module.marquee.autoAdvance();
  45. $leftArrow
  46. .on('click', module.marquee.left)
  47. ;
  48. $rightArrow
  49. .on('click', module.marquee.right)
  50. ;
  51. $navItem
  52. .on('click', module.marquee.change)
  53. ;
  54. },
  55. destroy: function() {
  56. module.verbose('Destroying previous module for', $module);
  57. $module
  58. .off(eventNamespace)
  59. ;
  60. },
  61. left: function() {
  62. var
  63. $activeContent = $content.filter('.' + className.active),
  64. currentIndex = $content.index($activeContent),
  65. imageCount = $content.size(),
  66. newIndex = (currentIndex - 1 != -1)
  67. ? (currentIndex - 1)
  68. : (imageCount - 1)
  69. ;
  70. $navItem
  71. .eq(newIndex)
  72. .trigger('click')
  73. ;
  74. },
  75. right: function() {
  76. var
  77. $activeContent = $content.filter('.' + className.active),
  78. currentIndex = $content.index($activeContent),
  79. imageCount = $content.size(),
  80. newIndex = (currentIndex + 1 != imageCount)
  81. ? (currentIndex + 1)
  82. : 0
  83. ;
  84. $navItem
  85. .eq(newIndex)
  86. .trigger('click')
  87. ;
  88. },
  89. change: function() {
  90. var
  91. $selected = $(this),
  92. selectedIndex = $navItem.index($selected),
  93. $selectedImage = $content.eq(selectedIndex)
  94. ;
  95. module.marquee.autoAdvance();
  96. $selected
  97. .addClass('active')
  98. .siblings()
  99. .removeClass('active')
  100. ;
  101. $selectedImage
  102. .addClass('active animated fadeIn')
  103. .siblings('.' + className.active)
  104. .removeClass('animated fadeIn scaleIn')
  105. .animate({
  106. opacity: 0
  107. }, 500, function(){
  108. $(this)
  109. .removeClass('active')
  110. .removeAttr('style')
  111. ;
  112. })
  113. ;
  114. },
  115. autoAdvance: function() {
  116. clearInterval(module.timer);
  117. module.timer = setInterval(module.marquee.right, settings.duration);
  118. },
  119. setting: function(name, value) {
  120. if(value !== undefined) {
  121. if( $.isPlainObject(name) ) {
  122. module.verbose('Modifying settings object', name, value);
  123. $.extend(true, settings, name);
  124. }
  125. else {
  126. module.verbose('Modifying setting', name, value);
  127. settings[name] = value;
  128. }
  129. }
  130. else {
  131. return settings[name];
  132. }
  133. },
  134. internal: function(name, value) {
  135. if(value !== undefined) {
  136. if( $.isPlainObject(name) ) {
  137. module.verbose('Modifying internal property', name, value);
  138. $.extend(true, module, name);
  139. }
  140. else {
  141. module.verbose('Changing internal method to', value);
  142. module[name] = value;
  143. }
  144. }
  145. else {
  146. return module[name];
  147. }
  148. },
  149. debug: function() {
  150. if(settings.debug) {
  151. if(settings.performance) {
  152. module.performance.log(arguments);
  153. }
  154. else {
  155. module.debug = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  156. module.debug.apply(console, arguments);
  157. }
  158. }
  159. },
  160. verbose: function() {
  161. if(settings.verbose && settings.debug) {
  162. if(settings.performance) {
  163. module.performance.log(arguments);
  164. }
  165. else {
  166. module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  167. module.verbose.apply(console, arguments);
  168. }
  169. }
  170. },
  171. error: function() {
  172. module.error = Function.prototype.bind.call(console.error, console, settings.moduleName + ':');
  173. module.error.apply(console, arguments);
  174. },
  175. performance: {
  176. log: function(message) {
  177. var
  178. currentTime,
  179. executionTime,
  180. previousTime
  181. ;
  182. if(settings.performance) {
  183. currentTime = new Date().getTime();
  184. previousTime = time || currentTime;
  185. executionTime = currentTime - previousTime;
  186. time = currentTime;
  187. performance.push({
  188. 'Element' : element,
  189. 'Name' : message[0],
  190. 'Arguments' : message[1] || 'None',
  191. 'Execution Time' : executionTime
  192. });
  193. clearTimeout(module.performance.timer);
  194. module.performance.timer = setTimeout(module.performance.display, 100);
  195. }
  196. },
  197. display: function() {
  198. var
  199. title = settings.moduleName,
  200. caption = settings.moduleName + ': ' + moduleSelector + '(' + $allModules.size() + ' elements)',
  201. totalExecutionTime = 0
  202. ;
  203. if(moduleSelector) {
  204. title += ' Performance (' + moduleSelector + ')';
  205. }
  206. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  207. console.groupCollapsed(title);
  208. if(console.table) {
  209. $.each(performance, function(index, data) {
  210. totalExecutionTime += data['Execution Time'];
  211. });
  212. console.table(performance);
  213. }
  214. else {
  215. $.each(performance, function(index, data) {
  216. totalExecutionTime += data['Execution Time'];
  217. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  218. });
  219. }
  220. console.log('Total Execution Time:', totalExecutionTime +'ms');
  221. console.groupEnd();
  222. performance = [];
  223. time = false;
  224. }
  225. }
  226. },
  227. invoke: function(query, passedArguments, context) {
  228. var
  229. maxDepth,
  230. found
  231. ;
  232. passedArguments = passedArguments || queryArguments;
  233. context = element || context;
  234. if(typeof query == 'string' && instance !== undefined) {
  235. query = query.split(/[\. ]/);
  236. maxDepth = query.length - 1;
  237. $.each(query, function(depth, value) {
  238. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  239. instance = instance[value];
  240. return true;
  241. }
  242. else if( instance[value] !== undefined ) {
  243. found = instance[value];
  244. return true;
  245. }
  246. module.error(errors.method);
  247. return false;
  248. });
  249. }
  250. if ( $.isFunction( found ) ) {
  251. return found.apply(context, passedArguments);
  252. }
  253. return found || false;
  254. }
  255. };
  256. if(methodInvoked) {
  257. if(instance === undefined) {
  258. module.initialize();
  259. }
  260. module.invoke(query);
  261. }
  262. else {
  263. if(instance !== undefined) {
  264. module.destroy();
  265. }
  266. module.initialize();
  267. }
  268. })
  269. ;
  270. return (invokedResponse !== undefined)
  271. ? invokedResponse
  272. : this
  273. ;
  274. };
  275. $.fn.carousel.settings = {
  276. moduleName : 'Carousel',
  277. namespace : 'carousel',
  278. verbose : true,
  279. debug : true,
  280. performance : true,
  281. // delegated event context
  282. duration: 5000,
  283. errors : {
  284. method : 'The method you called is not defined.'
  285. },
  286. selector : {
  287. arrows : '.arrow',
  288. leftArrow : '.left.arrow',
  289. rightArrow : '.right.arrow',
  290. content : '.content',
  291. navigation : '.navigation',
  292. navItem : '.navigation .icon'
  293. },
  294. className : {
  295. active : 'active'
  296. }
  297. };
  298. })( jQuery, window , document );