(function($) { var $window = $(window); var $document = $(document); /* * Scrollspy. */ $document.on('flatdoc:ready', function() { $("h2, h3").scrollagent(function(cid, pid, currentElement, previousElement) { if (pid) { $("[href='#"+pid+"']").removeClass('active'); } if (cid) { $("[href='#"+cid+"']").addClass('active'); } }); }); /* * Anchor jump links. */ $document.on('flatdoc:ready', function() { $('.menu a').anchorjump(); }); /* * Title card. */ $(function() { var $card = $('.title-card'); if (!$card.length) return; var $header = $('.header'); var headerHeight = $header.length ? $header.outerHeight() : 0; $window .on('resize.title-card', function() { var windowWidth = $window.width(); if (windowWidth < 480) { $card.css('height', ''); } else { var height = $window.height(); $card.css('height', height - headerHeight); } }) .trigger('resize.title-card'); $card.fillsize('> img.bg'); }); /* * Sidebar stick. */ $(function() { var $sidebar = $('.menubar'); var elTop; $window .on('resize.sidestick', function() { $sidebar.removeClass('fixed'); elTop = $sidebar.offset().top; $window.trigger('scroll.sidestick'); }) .on('scroll.sidestick', function() { var scrollY = $window.scrollTop(); $sidebar.toggleClass('fixed', (scrollY >= elTop)); }) .trigger('resize.sidestick'); }); })(jQuery); /*! jQuery.scrollagent (c) 2012, Rico Sta. Cruz. MIT License. * https://github.com/rstacruz/jquery-stuff/tree/master/scrollagent */ // Call $(...).scrollagent() with a callback function. // // The callback will be called everytime the focus changes. // // Example: // // $("h2").scrollagent(function(cid, pid, currentElement, previousElement) { // if (pid) { // $("[href='#"+pid+"']").removeClass('active'); // } // if (cid) { // $("[href='#"+cid+"']").addClass('active'); // } // }); (function($) { $.fn.scrollagent = function(options, callback) { // Account for $.scrollspy(function) if (typeof callback === 'undefined') { callback = options; options = {}; } var $sections = $(this); var $parent = options.parent || $(window); // Find the top offsets of each section var offsets = []; $sections.each(function(i) { var offset = $(this).attr('data-anchor-offset') ? parseInt($(this).attr('data-anchor-offset'), 10) : (options.offset || 0); offsets.push({ top: $(this).offset().top + offset, id: $(this).attr('id'), index: i, el: this }); }); // State var current = null; var height = null; var range = null; // Save the height. Do this only whenever the window is resized so we don't // recalculate often. $(window).on('resize', function() { height = $parent.height(); range = $(document).height(); }); // Find the current active section every scroll tick. $parent.on('scroll', function() { var y = $parent.scrollTop(); y += height * (0.3 + 0.7 * Math.pow(y/range, 2)); var latest = null; for (var i in offsets) { if (offsets.hasOwnProperty(i)) { var offset = offsets[i]; if (offset.top < y) latest = offset; } } if (latest && (!current || (latest.index !== current.index))) { callback.call($sections, latest ? latest.id : null, current ? current.id : null, latest ? latest.el : null, current ? current.el : null); current = latest; } }); $(window).trigger('resize'); $parent.trigger('scroll'); return this; }; })(jQuery); /*! Anchorjump (c) 2012, Rico Sta. Cruz. MIT License. * http://github.com/rstacruz/jquery-stuff/tree/master/anchorjump */ // Makes anchor jumps happen with smooth scrolling. // // $("#menu a").anchorjump(); // $("#menu a").anchorjump({ offset: -30 }); // // // Via delegate: // $("#menu").anchorjump({ for: 'a', offset: -30 }); // // You may specify a parent. This makes it scroll down to the parent. // Great for tabbed views. // // $('#menu a').anchorjump({ parent: '.anchor' }); // // You can jump to a given area. // // $.anchorjump('#bank-deposit', options); (function($) { var defaults = { 'speed': 500, 'offset': 0, 'for': null, 'parent': null }; $.fn.anchorjump = function(options) { options = $.extend({}, defaults, options); if (options['for']) { this.on('click', options['for'], onClick); } else { this.on('click', onClick); } function onClick(e) { var $a = $(e.target).closest('a'); if (e.ctrlKey || e.metaKey || e.altKey || $a.attr('target')) return; e.preventDefault(); var href = $a.attr('href'); $.anchorjump(href, options); } }; // Jump to a given area. $.anchorjump = function(href, options) { options = $.extend({}, defaults, options); var top = 0; if (href != '#') { var $area = $(href); // Find the parent if (options.parent) { var $parent = $area.closest(options.parent); if ($parent.length) { $area = $parent; } } if (!$area.length) { return; } // Determine the pixel offset; use the default if not available var offset = $area.attr('data-anchor-offset') ? parseInt($area.attr('data-anchor-offset'), 10) : options.offset; top = Math.max(0, $area.offset().top + offset); } $('html, body').animate({ scrollTop: top }, options.speed); $('body').trigger('anchor', href); // Add the location hash via pushState. if (window.history.pushState) { window.history.pushState({ href: href }, "", href); } }; })(jQuery); /*! fillsize (c) 2012, Rico Sta. Cruz. MIT License. * http://github.com/rstacruz/jquery-stuff/tree/master/fillsize */ // Makes an element fill up its container. // // $(".container").fillsize("> img"); // // This binds a listener on window resizing to automatically scale down the // child (`> img` in this example) just so that enough of it will be visible in // the viewport of the container. // // This assumes that the container has `position: relative` (or any 'position', // really), and `overflow: hidden`. (function($) { $.fn.fillsize = function(selector) { var $parent = this; var $img; function resize() { if (!$img) $img = $parent.find(selector); $img.each(function() { if (!this.complete) return; var $img = $(this); var parent = { height: $parent.innerHeight(), width: $parent.innerWidth() }; var imageRatio = $img.width() / $img.height(); var containerRatio = parent.width / parent.height; var css = { position: 'absolute', left: 0, top: 0, right: 'auto', bottom: 'auto' }; // If image is wider than the container if (imageRatio > containerRatio) { css.left = Math.round((parent.width - imageRatio * parent.height) / 2) + 'px'; css.width = 'auto'; css.height = '100%'; } // If the container is wider than the image else { css.top = Math.round((parent.height - (parent.width / $img.width() * $img.height())) / 2) + 'px'; css.height = 'auto'; css.width = '100%'; } $img.css(css); }); } // Make it happen on window resize. $(window).resize(resize); // Allow manual invocation by doing `.trigger('fillsize')` on the container. $(document).on('fillsize', $parent.selector, resize); // Resize on first load (or immediately if called after). $(function() { // If the child is an image, fill it up when image's real dimensions are // first determined. Needs to be .bind() because the load event will // bubble up. $(selector, $parent).bind('load', function() { setTimeout(resize, 25); }); resize(); }); return this; }; })(jQuery);