xPanel is waypoint shortcut used to create paralax effect while scrolling panels which you can see on this page.
A Pen by Damian Drygiel on CodePen.
| <div id="group-one" class="colorful"> | |
| <article> | |
| <h1>Scroll down</h1> | |
| <p> | |
| Lorem ipsum dolor sit amet, consectetur adipiscing elit fusce vel sapien elit in malesuada semper mi, | |
| id sollicitudin urna fermentum ut fusce varius nisl ac ipsum gravida vel pretium tellus. | |
| </p> | |
| </article> | |
| <article> | |
| <h1>Dolor sit amet</h1> | |
| <p> | |
| Lorem ipsum dolor sit amet, consectetur adipiscing elit fusce vel sapien elit in malesuada semper mi, | |
| id sollicitudin urna fermentum ut fusce varius nisl ac ipsum gravida vel pretium tellus. | |
| </p> | |
| </article> | |
| <article> | |
| <h1>Consectetur</h1> | |
| <p> | |
| Lorem ipsum dolor sit amet, consectetur adipiscing elit fusce vel sapien elit in malesuada semper mi, | |
| id sollicitudin urna fermentum ut fusce varius nisl ac ipsum gravida vel pretium tellus. | |
| Lorem ipsum dolor sit amet, consectetur adipiscing elit fusce vel sapien elit in malesuada semper mi, | |
| id sollicitudin urna fermentum ut fusce varius nisl ac ipsum gravida vel pretium tellus. | |
| </p> | |
| </article> | |
| <article> | |
| <h1>Scroll Up</h1> | |
| <p> | |
| Lorem ipsum dolor sit amet, consectetur adipiscing elit fusce vel sapien elit in malesuada semper mi, | |
| id sollicitudin urna fermentum ut fusce varius nisl ac ipsum gravida vel pretium tellus. | |
| </p> | |
| <br /> | |
| <a href="https://github.com/drygiel/xPanel" data-text="More examples on github" class="nice-link">More examples on github</a> | |
| <br /> | |
| <br /> | |
| <input type="checkbox" id="colorful" checked /> | |
| <label for="colorful" >Colorful</label> | |
| </article> | |
| </div> | |
| <a href="https://github.com/drygiel" target="_blank"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png" alt="Fork me on GitHub"></a> |
| (function ($) { | |
| $.xpanel = function (obj, opt) { | |
| var self = this, | |
| $container = $(obj), | |
| viewportHeight, | |
| panels = $container.children(), | |
| scrollingDirection = 'down', | |
| lastScrollPos = 0; | |
| self.options = $.extend({}, $.fn.waypoint.defaults, $.xpanel.defaultOptions, opt); | |
| //_________________ Refresh | |
| var refresh = function () { | |
| viewportHeight = $.waypoints('viewportHeight'); | |
| var scaled = viewportHeight * Math.max(self.options.minHeightScale, 1); | |
| panels.css({ 'min-height': scaled }); | |
| $container.find('.dummy').each(function () { | |
| $(this).css({ 'min-height': scaled, 'height': $(this).prev().outerHeight() }); | |
| }); | |
| } | |
| //_________________ Clear | |
| var clear = function () { | |
| panels.removeClass('in').removeClass('out').css({ 'top': '', 'bottom': '' }); | |
| } | |
| //_________________ Change options | |
| self.changeOptions = function (opt) { | |
| if (opt === 'destroy') { | |
| self.destroy(); | |
| return; | |
| } | |
| else if (opt === 'refresh') { | |
| refresh(); | |
| $.waypoints('refresh'); | |
| return; | |
| } | |
| for (var name in opt) { | |
| if (!(name in $.xpanel.defaultOptions)) continue; // Is option unknown? | |
| var value = opt[name]; | |
| if (self.options[name] == value) continue; // Nothing changed? | |
| switch (name) { | |
| case 'shadow': | |
| case 'reverse': | |
| case 'dim': | |
| $container.toggleClass(name); | |
| break; | |
| case 'minHeightScale': | |
| if (!!value) | |
| refresh(); | |
| break; | |
| } | |
| self.options[name] = value; | |
| } | |
| } | |
| //_________________ Window scroll handler | |
| var scrollHandler = function () { | |
| var scrollPos = $(window).scrollTop(); | |
| if (self.options.fixJumpyScrolling) { | |
| if (scrollPos > lastScrollPos) { | |
| if (scrollingDirection != 'down') { | |
| scrollingDirection = 'down'; | |
| onScrollingDirectionChanged(scrollingDirection); | |
| } | |
| } | |
| else { | |
| if (scrollingDirection != 'up') { | |
| scrollingDirection = 'up'; | |
| onScrollingDirectionChanged(scrollingDirection); | |
| } | |
| } | |
| } | |
| lastScrollPos = scrollPos; | |
| }; | |
| //_________________ On scrolling direction changed | |
| var onScrollingDirectionChanged = function (newDirection) { | |
| panels.filter('.out').animate({ | |
| 'top': 0, | |
| 'bottom': 0 | |
| }, 200); | |
| } | |
| //_________________ Initialization | |
| self.init = function () { | |
| $container.data('xpanel', self); | |
| $(window).bind('scroll', scrollHandler); | |
| $container.addClass('xpanel'); | |
| if (self.options.reverse) $container.addClass('reverse'); | |
| if (self.options.shadow) $container.addClass('shadow'); | |
| if (self.options.dim) $container.addClass('dim'); | |
| panels.last().siblings().after('<div class="dummy" />'); | |
| $(window).bind('resize', refresh); | |
| refresh(); | |
| // Top hits | |
| panels.waypoint(function (direction) { | |
| var panel = $(this); | |
| clear(); | |
| if (scrollingDirection === 'up' && direction === 'up') { | |
| $container.removeClass('scroll-down').addClass('scroll-up'); | |
| if (self.options.whenScrollUp && panel.prev().length) { | |
| if (self.options.fixJumpyScrolling) { | |
| var diff = panel.offset().top - $(window).scrollTop(); | |
| panel.css('top', diff) | |
| } | |
| panel.addClass('out'); | |
| panel.prev().prev().addClass('in'); | |
| } | |
| } | |
| else { | |
| $container.removeClass('scroll-up').addClass('scroll-down'); | |
| } | |
| }); | |
| // Bottom hits | |
| panels.waypoint(function (direction) { | |
| var panel = $(this); | |
| clear(); | |
| if (scrollingDirection === 'down' && direction === 'down') { | |
| $container.removeClass('scroll-up').addClass('scroll-down'); | |
| if (self.options.whenScrollDown && panel.next().length) { | |
| if (self.options.fixJumpyScrolling) { | |
| var diff = $(window).scrollTop() + viewportHeight - panel.next().next().offset().top; | |
| panel.css('bottom', diff); | |
| } | |
| panel.addClass('out'); | |
| panel.next().next().addClass('in'); | |
| } | |
| } | |
| else { | |
| $container.removeClass('scroll-down').addClass('scroll-up'); | |
| } | |
| }, { offset: function () { return -($(this).outerHeight() - viewportHeight); } }); | |
| return this; | |
| } | |
| //_________________ Destroy | |
| self.destroy = function () { | |
| $(window).unbind('resize', refresh); | |
| $(window).unbind('scroll', scrollHandler); | |
| $container.removeClass('xpanel') | |
| .removeClass('reverse') | |
| .removeClass('dim'); | |
| $container.find('.dummy').remove(); | |
| clear(); | |
| panels.each(function () { | |
| $(this).css('min-height', '') | |
| .waypoint('destroy'); | |
| }); | |
| $container.removeData('xpanel'); | |
| } | |
| self.init(); | |
| } | |
| //_________________ Default options | |
| $.xpanel.defaultOptions = { | |
| minHeightScale: 1.15, | |
| fixJumpyScrolling: true, | |
| reverse: true, | |
| shadow: true, | |
| dim: true, | |
| whenScrollDown: true, | |
| whenScrollUp: true, | |
| }; | |
| //_________________ Extend waypoints | |
| return $.waypoints('extendFn', 'xpanel', function (opt) { | |
| if (this.length) | |
| this.each(function () { | |
| var xpanel = $(this).data('xpanel'); | |
| if (xpanel instanceof $.xpanel) | |
| xpanel.changeOptions(opt); | |
| else | |
| new $.xpanel(this, opt); | |
| }); | |
| return this; | |
| }); | |
| })(jQuery); | |
| //-------------------------------------------------- | |
| $('#colorful').click(function () { | |
| $('#group-one').toggleClass('colorful'); | |
| }); | |
| $('#group-one').waypoint('xpanel', { | |
| minHeightScale: 1.05, | |
| reverse: false, | |
| shadow: false, | |
| dim: true, | |
| whenScrollDown: true, | |
| whenScrollUp: true, | |
| }); |
| .xpanel { | |
| @speed: .8s; | |
| @dim-color: rgba(33, 33, 33, 0.4); | |
| @zIdxLow: 100; | |
| @zIdxMid: 200; | |
| @zIdxHigh: 300; | |
| .dummy { | |
| display: none; | |
| } | |
| > * { | |
| -moz-box-sizing: border-box; | |
| -webkit-box-sizing: border-box; | |
| box-sizing: border-box; | |
| z-index: @zIdxLow; | |
| background: #FFF; | |
| width: 100%; | |
| } | |
| &.shadow { | |
| &:not(.reverse) { | |
| .in, .out { | |
| -webkit-box-shadow: 0 2px 20px #252525; | |
| box-shadow: 0 2px 20px #252525; | |
| } | |
| } | |
| &.reverse { | |
| .in, .out { | |
| -webkit-box-shadow: 0 -2px 20px #252525; | |
| box-shadow: 0 -2px 20px #252525; | |
| } | |
| } | |
| } | |
| &.dim { | |
| > *:before { | |
| content: ''; | |
| position: absolute; | |
| left: 0; | |
| top: 0; | |
| width: 0; | |
| height: 0; | |
| background-color: transparent; | |
| pointer-events: none; | |
| } | |
| &.scroll-down:not(.reverse) .in:before, | |
| &.scroll-up.reverse .in:before { | |
| width: 100%; | |
| height: 100%; | |
| background-color: @dim-color; | |
| -moz-animation: xpanel-lighten @speed forwards; | |
| -o-animation: xpanel-lighten @speed forwards; | |
| -webkit-animation: xpanel-lighten @speed forwards; | |
| animation: xpanel-lighten @speed forwards; | |
| } | |
| &.scroll-down.reverse .out:before, | |
| &.scroll-up:not(.reverse) .out:before { | |
| width: 100%; | |
| height: 100%; | |
| background-color: @dim-color; | |
| -moz-transition: background-color @speed ease; | |
| -o-transition: background-color @speed ease; | |
| -webkit-transition: background-color @speed ease; | |
| transition: background-color @speed ease; | |
| } | |
| } | |
| &:not(.reverse) { | |
| &.scroll-down { | |
| .out { | |
| position: relative; | |
| z-index: @zIdxHigh; | |
| bottom: 0 !important; | |
| + .dummy { | |
| display: block; | |
| } | |
| } | |
| .in { | |
| position: fixed; | |
| left: 0; | |
| top: 0; | |
| z-index: @zIdxMid; | |
| } | |
| } | |
| &.scroll-up { | |
| .in { | |
| position: relative; | |
| z-index: @zIdxHigh; | |
| + .dummy { | |
| display: block; | |
| } | |
| } | |
| .out { | |
| position: fixed; | |
| left: 0; | |
| top: 0; | |
| z-index: @zIdxMid; | |
| } | |
| } | |
| } | |
| &.reverse { | |
| &.scroll-down { | |
| .out { | |
| position: fixed; | |
| left: 0; | |
| bottom: 0; | |
| top: auto !important; | |
| z-index: @zIdxMid; | |
| + .dummy { | |
| display: block; | |
| } | |
| } | |
| .in { | |
| position: relative; | |
| z-index: @zIdxHigh; | |
| } | |
| } | |
| &.scroll-up { | |
| .in { | |
| position: fixed; | |
| left: 0; | |
| bottom: 0; | |
| top: auto !important; | |
| z-index: @zIdxMid; | |
| + .dummy { | |
| display: block; | |
| } | |
| } | |
| .out { | |
| position: relative; | |
| z-index: @zIdxHigh; | |
| } | |
| } | |
| } | |
| } | |
| @-moz-keyframes xpanel-lighten { | |
| 100% { | |
| background-color: transparent; | |
| } | |
| } | |
| @-webkit-keyframes xpanel-lighten { | |
| 100% { | |
| background-color: transparent; | |
| } | |
| } | |
| @keyframes xpanel-lighten { | |
| 100% { | |
| background-color: transparent; | |
| } | |
| } | |
| // ----------------------------------- LAYOUT | |
| @import url('http://fonts.googleapis.com/css?family=Lato:300,700'); | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| } | |
| body, | |
| html { | |
| color: #2C2C2C; | |
| font: 300 100% 'Lato', sans-serif; | |
| } | |
| article { | |
| font-size: 1.3em; | |
| min-height: 700px; | |
| padding: 20% 20px; | |
| font-weight: 200; | |
| text-align: center; | |
| background-color: white; | |
| .colorful & { | |
| &:nth-of-type(1) { | |
| background-color: #A8DA5E; | |
| } | |
| &:nth-of-type(2) { | |
| background-color: #FFF581; | |
| } | |
| &:nth-of-type(3) { | |
| background-color: #2AEEE6; | |
| } | |
| &:nth-of-type(4) { | |
| background-color: #313131; | |
| color: #3FC9C3; | |
| } | |
| article:nth-of-type(5) { | |
| background-color: white; | |
| } | |
| } | |
| } | |
| article > div { | |
| display: inline-block; | |
| text-align: left; | |
| max-width: 60%; | |
| } | |
| article h1 { | |
| font-size: 3em; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| margin-bottom: 50px; | |
| } | |
| p { | |
| line-height: 200%; | |
| max-width: 50%; | |
| text-align: left; | |
| margin: auto; | |
| } | |
| a { | |
| text-decoration: none; | |
| text-transform: uppercase; | |
| } | |
| /*___________________________________ LINK ___________________________________ */ | |
| // More info here: http://codepen.io/drygiel/pen/hkgGq | |
| a.nice-link { | |
| @color: #0092CA; | |
| @hover-color: lighten(spin(saturate(@color, 50%), -8), 8%); | |
| position: relative; | |
| color: @color; | |
| h1 &:after { | |
| border-bottom: 1px solid @hover-color; // Underline | |
| } | |
| &:after { | |
| text-align: justify; | |
| display: inline-block; | |
| content: attr(data-text); | |
| position: absolute; | |
| left: 0; | |
| top: 0; | |
| white-space: nowrap; | |
| overflow: hidden; | |
| color: @hover-color; | |
| min-height: 100%; | |
| width: 0; | |
| max-width: 100%; // 'cause of IE bug | |
| //background: #313131; | |
| -moz-transition: .3s; | |
| -o-transition: .3s; | |
| -webkit-transition: .3s; | |
| transition: .3s; | |
| } | |
| &:hover { | |
| color: @color; // To override default hover color | |
| &:after { | |
| width: 100%; | |
| } | |
| } | |
| } |
xPanel is waypoint shortcut used to create paralax effect while scrolling panels which you can see on this page.
A Pen by Damian Drygiel on CodePen.