Skip to content

Instantly share code, notes, and snippets.

@robertberry-zz
Last active January 3, 2017 13:29
Show Gist options
  • Save robertberry-zz/fd88e0d1dc60782466bf0256ad76983d to your computer and use it in GitHub Desktop.
Save robertberry-zz/fd88e0d1dc60782466bf0256ad76983d to your computer and use it in GitHub Desktop.
<!doctype html>
<html>
<head>
<style type="text/css">
body {
background-color: #f0f0f0;
}
.Page {
left: 50%;
position: relative;
margin-left: -600px;
width: 1200px;
}
.Sidebar {
float: left;
min-width: 317px;
}
.Sidebar--right {
float: right;
}
.Content {
padding: 0 10px;
box-sizing: border-box;
margin-left: 327px;
width: 544px;
}
.Module {
background-color: white;
border: 1px solid #ccc;
border-radius: 3px;
color: white;
font: 12px Arial, Verdana, sans-serif;
margin-bottom: 10px;
min-height: 300px;
padding: 10px;
/* must be set for when is fixed */
width: 295px;
}
.Module:last-of-type {
margin-bottom: 0;
}
.Timeline {
background-color: white;
border: 1px solid #ccc;
border-radius: 3px;
}
.Tweet {
border-bottom: 1px solid #ccc;
min-height: 200px;
}
.colour1 {
background-color: #C8BFC7;
}
.colour2 {
background-color: #7A9B76;
}
.colour3 {
background-color: #8A7E72;
}
.colour4 {
background-color: #5A2328;
}
.colour5 {
background-color: #C2EFB3;
}
.colour6 {
background-color: #97ABB1;
}
.colour7 {
background-color: #746F72;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div class="Page">
<div class="Sidebar">
<div class="js-anchoredSidebar">
<div class="Module colour1">
<h1>Trends</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.</p>
</div>
<div class="Module colour2">
<h1>My Moments</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.</p>
</div>
<div class="Module colour3">
<h1>Highlights</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.</p>
</div>
<div class="Module colour4">
<h1>Periscopes</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.</p>
</div>
</div>
</div>
<div class="Content">
<div class="Timeline">
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
<div class="Tweet"></div>
</div>
</div>
<!--div class="Sidebar Sidebar--right">
<div class="js-anchoredSidebarRight">
<div class="Module colour5">
<h1>Who To Follow</h1>
</div>
<div class="Module colour6">
<h1>Live Video</h1>
</div>
<div class="Module colour7">
<h1>Footer</h1>
</div>
</div>
</div-->
</div>
<script type="text/javascript">
var STATIC = 0;
var TOP_ANCHOR = 1;
var BOTTOM_ANCHOR = 2;
var SIDEBAR_TOP_OFFSET = 8;
var BOTTOM_OFFSET = 45;
var $window = $(window);
var $document = $(document);
function AnchoredSidebar($element) {
this.$element = $element;
// actually if there's enough room in viewport for entire sidebar it should be top anchored
this.state = STATIC;
this.staticPosition = 0;
}
AnchoredSidebar.prototype.updateDOM = function() {
var top = 0;
if (this.state === TOP_ANCHOR) {
top = SIDEBAR_TOP_OFFSET;
} else if (this.state === BOTTOM_ANCHOR) {
top = $window.height() - this.$element.height() - BOTTOM_OFFSET;
} else if (this.state === STATIC && this.staticPosition) {
top = this.staticPosition;
}
this.$element.css({
position: this.state === STATIC ? 'absolute' : 'fixed',
transform: 'translateY(' + top + 'px)'
});
};
AnchoredSidebar.prototype.updateSidebar = function() {
var scrollTop = Math.max(0, this.scrollTop);
var scrollVelocity = scrollTop - this.lastScrollTop;
if (scrollVelocity < 0) {
scrollVelocity = Math.min(scrollVelocity, -10);
} else if (scrollVelocity > 0) {
scrollVelocity = Math.max(scrollVelocity, 10);
}
if (scrollTop === this.lastScrollTop) {
return;
}
if (this.state === STATIC) {
var top = this.staticPosition;
// offsets
if (scrollTop + scrollVelocity <= top - SIDEBAR_TOP_OFFSET) {
this.state = TOP_ANCHOR;
} else if (scrollTop + $window.height() + scrollVelocity >= top + this.$element.outerHeight() + BOTTOM_OFFSET) {
this.state = BOTTOM_ANCHOR;
}
} else if (this.state === TOP_ANCHOR) {
if (scrollTop > this.lastScrollTop) {
this.staticPosition = scrollTop + SIDEBAR_TOP_OFFSET; //- SIDEBAR_TOP_OFFSET;
this.state = STATIC;
}
} else if (this.state == BOTTOM_ANCHOR) {
if (scrollTop < this.lastScrollTop) {
this.staticPosition = scrollTop + $window.height() - this.$element.outerHeight() - BOTTOM_OFFSET;
this.state = STATIC;
}
}
this.updateDOM();
this.lastScrollTop = scrollTop;
};
AnchoredSidebar.prototype.onRequestAnimationFrame = function() {
this.updateSidebar();
this.enqueueRaf();
};
AnchoredSidebar.prototype.enqueueRaf = function() {
this.rafRef = requestAnimationFrame(this.boundOnRequestAnimationFrame);
};
AnchoredSidebar.prototype.recordScrollTop = function() {
this.scrollTop = $document.scrollTop();
};
AnchoredSidebar.prototype.attach = function() {
this.recordScrollTop();
this.lastScrollTop = this.scrollTop;
$document.on('scroll', this.recordScrollTop.bind(this));
this.boundOnRequestAnimationFrame = this.onRequestAnimationFrame.bind(this);
this.enqueueRaf();
};
new AnchoredSidebar($('.js-anchoredSidebar')).attach();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment