diff options
Diffstat (limited to 'deck.js/extensions/menu')
-rw-r--r-- | deck.js/extensions/menu/deck.menu.css | 47 | ||||
-rw-r--r-- | deck.js/extensions/menu/deck.menu.js | 187 | ||||
-rwxr-xr-x | deck.js/extensions/menu/deck.menu.scss | 58 |
3 files changed, 292 insertions, 0 deletions
diff --git a/deck.js/extensions/menu/deck.menu.css b/deck.js/extensions/menu/deck.menu.css new file mode 100644 index 0000000..c664a3f --- /dev/null +++ b/deck.js/extensions/menu/deck.menu.css @@ -0,0 +1,47 @@ +.deck-menu .slide { + background: #eee; + position: relative; + left: 0; + top: 0; + visibility: visible; + cursor: pointer; +} +.no-csstransforms .deck-menu > .slide { + float: left; + width: 22%; + height: 22%; + min-height: 0; + margin: 1%; + font-size: 0.22em; + overflow: hidden; + padding: 0 0.5%; +} +.csstransforms .deck-menu > .slide { + -webkit-transform: scale(0.22) !important; + -moz-transform: scale(0.22) !important; + -o-transform: scale(0.22) !important; + -ms-transform: scale(0.22) !important; + transform: scale(0.22) !important; + -webkit-transform-origin: 0 0; + -moz-transform-origin: 0 0; + -o-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + height: 100%; + overflow: hidden; + padding: 0 48px; + margin: 12px; +} +.deck-menu iframe, .deck-menu img, .deck-menu video { + max-width: 100%; +} +.deck-menu .deck-current, .no-touch .deck-menu .slide:hover { + background: #ddf; +} +.deck-menu.deck-container:hover .deck-prev-link, .deck-menu.deck-container:hover .deck-next-link { + display: none; +} diff --git a/deck.js/extensions/menu/deck.menu.js b/deck.js/extensions/menu/deck.menu.js new file mode 100644 index 0000000..743cf77 --- /dev/null +++ b/deck.js/extensions/menu/deck.menu.js @@ -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'); + diff --git a/deck.js/extensions/menu/deck.menu.scss b/deck.js/extensions/menu/deck.menu.scss new file mode 100755 index 0000000..0bd576d --- /dev/null +++ b/deck.js/extensions/menu/deck.menu.scss @@ -0,0 +1,58 @@ +.deck-menu { + .slide { + background:#eee; + position:relative; + left:0; + top:0; + visibility:visible; + cursor:pointer; + } + + > .slide { + .no-csstransforms & { + float:left; + width:22%; + height:22%; + min-height:0; + margin:1%; + font-size:0.22em; + overflow:hidden; + padding:0 0.5%; + } + + .csstransforms & { + -webkit-transform:scale(.22) !important; + -moz-transform:scale(.22) !important; + -o-transform:scale(.22) !important; + -ms-transform:scale(.22) !important; + transform:scale(.22) !important; + -webkit-transform-origin:0 0; + -moz-transform-origin:0 0; + -o-transform-origin:0 0; + -ms-transform-origin:0 0; + transform-origin:0 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width:100%; + height:100%; + overflow:hidden; + padding:0 48px; + margin:12px; + } + } + + iframe, img, video { + max-width:100%; + } + + .deck-current, .no-touch & .slide:hover { + background:#ddf; + } + + &.deck-container:hover { + .deck-prev-link, .deck-next-link { + display:none; + } + } +}
\ No newline at end of file |