diff deck.js/extensions/menu/deck.menu.js @ 0:dd1c78c6398f

add having slides
author taiki <taiki@cr.ie.u-ryukyu.ac.jp>
date Mon, 25 Mar 2013 05:14:03 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/deck.js/extensions/menu/deck.menu.js	Mon Mar 25 05:14:03 2013 +0900
@@ -0,0 +1,187 @@
+/*!
+Deck JS - deck.menu
+Copyright (c) 2011 Caleb Troughton
+Dual licensed under the MIT license and GPL license.
+https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
+https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt
+*/
+
+/*
+This module adds the methods and key binding to show and hide a menu of all
+slides in the deck. The deck menu state is indicated by the presence of a class
+on the deck container.
+*/
+(function($, deck, undefined) {
+	var $d = $(document),
+	rootSlides; // Array of top level slides
+	
+	/*
+	Extends defaults/options.
+	
+	options.classes.menu
+		This class is added to the deck container when showing the slide menu.
+	
+	options.keys.menu
+		The numeric keycode used to toggle between showing and hiding the slide
+		menu.
+		
+	options.touch.doubletapWindow
+		Two consecutive touch events within this number of milliseconds will
+		be considered a double tap, and will toggle the menu on touch devices.
+	*/
+	$.extend(true, $[deck].defaults, {
+		classes: {
+			menu: 'deck-menu'
+		},
+		
+		keys: {
+			menu: 77 // m
+		},
+		
+		touch: {
+			doubletapWindow: 400
+		}
+	});
+
+	/*
+	jQuery.deck('showMenu')
+	
+	Shows the slide menu by adding the class specified by the menu class option
+	to the deck container.
+	*/
+	$[deck]('extend', 'showMenu', function() {
+		var $c = $[deck]('getContainer'),
+		opts = $[deck]('getOptions');
+		
+		if ($c.hasClass(opts.classes.menu)) return;
+		
+		// Hide through loading class to short-circuit transitions (perf)
+		$c.addClass([opts.classes.loading, opts.classes.menu].join(' '));
+		
+		/* Forced to do this in JS until CSS learns second-grade math. Save old
+		style value for restoration when menu is hidden. */
+		if (Modernizr.csstransforms) {
+			$.each(rootSlides, function(i, $slide) {
+				$slide.data('oldStyle', $slide.attr('style'));
+				$slide.css({
+					'position': 'absolute',
+					'left': ((i % 4) * 25) + '%',
+					'top': (Math.floor(i / 4) * 25) + '%'
+				});
+			});
+		}
+		
+		// Need to ensure the loading class renders first, then remove
+		window.setTimeout(function() {
+			$c.removeClass(opts.classes.loading)
+				.scrollTop($[deck]('getSlide').offset().top);
+		}, 0);
+	});
+
+	/*
+	jQuery.deck('hideMenu')
+	
+	Hides the slide menu by removing the class specified by the menu class
+	option from the deck container.
+	*/
+	$[deck]('extend', 'hideMenu', function() {
+		var $c = $[deck]('getContainer'),
+		opts = $[deck]('getOptions');
+		
+		if (!$c.hasClass(opts.classes.menu)) return;
+		
+		$c.removeClass(opts.classes.menu);
+		$c.addClass(opts.classes.loading);
+		
+		/* Restore old style value */
+		if (Modernizr.csstransforms) {
+			$.each(rootSlides, function(i, $slide) {
+				var oldStyle = $slide.data('oldStyle');
+
+				$slide.attr('style', oldStyle ? oldStyle : '');
+			});
+		}
+		
+		window.setTimeout(function() {
+			$c.removeClass(opts.classes.loading).scrollTop(0);
+		}, 0);
+	});
+
+	/*
+	jQuery.deck('toggleMenu')
+	
+	Toggles between showing and hiding the slide menu.
+	*/
+	$[deck]('extend', 'toggleMenu', function() {
+		$[deck]('getContainer').hasClass($[deck]('getOptions').classes.menu) ?
+		$[deck]('hideMenu') : $[deck]('showMenu');
+	});
+
+	$d.bind('deck.init', function() {
+		var opts = $[deck]('getOptions'),
+		touchEndTime = 0,
+		currentSlide,
+		slideTest = $.map([
+			opts.classes.before,
+			opts.classes.previous,
+			opts.classes.current,
+			opts.classes.next,
+			opts.classes.after
+		], function(el, i) {
+			return '.' + el;
+		}).join(', ');
+		
+		// Build top level slides array
+		rootSlides = [];
+		$.each($[deck]('getSlides'), function(i, $el) {
+			if (!$el.parentsUntil(opts.selectors.container, slideTest).length) {
+				rootSlides.push($el);
+			}
+		});
+		
+		// Bind key events
+		$d.unbind('keydown.deckmenu').bind('keydown.deckmenu', function(e) {
+			if (e.which === opts.keys.menu || $.inArray(e.which, opts.keys.menu) > -1) {
+				$[deck]('toggleMenu');
+				e.preventDefault();
+			}
+		});
+		
+		// Double tap to toggle slide menu for touch devices
+		$[deck]('getContainer').unbind('touchstart.deckmenu').bind('touchstart.deckmenu', function(e) {
+			currentSlide = $[deck]('getSlide');
+		})
+		.unbind('touchend.deckmenu').bind('touchend.deckmenu', function(e) {
+			var now = Date.now();
+			
+			// Ignore this touch event if it caused a nav change (swipe)
+			if (currentSlide !== $[deck]('getSlide')) return;
+			
+			if (now - touchEndTime < opts.touch.doubletapWindow) {
+				$[deck]('toggleMenu');
+				e.preventDefault();
+			}
+			touchEndTime = now;
+		});
+		
+		// Selecting slides from the menu
+		$.each($[deck]('getSlides'), function(i, $s) {
+			$s.unbind('click.deckmenu').bind('click.deckmenu', function(e) {
+				if (!$[deck]('getContainer').hasClass(opts.classes.menu)) return;
+
+				$[deck]('go', i);
+				$[deck]('hideMenu');
+				e.stopPropagation();
+				e.preventDefault();
+			});
+		});
+	})
+	.bind('deck.change', function(e, from, to) {
+		var container = $[deck]('getContainer');
+		
+		if (container.hasClass($[deck]('getOptions').classes.menu)) {
+			container.scrollTop($[deck]('getSlide', to).offset().top);
+		}
+	});
+})(jQuery, 'deck');
+