scale according to scroll position
by rodneyrehm
HTML
<header> <h1>foo bar baz</h1> </header>
<p style="height:0; padding-bottom: 10000px; margin-bottom: -10000px">scrollbars</p>
<p style="margin-top: 100px">scroll down and watch the header become smaller</p>
<p style="margin-top: 100px">scroll down and watch the header become smaller</p>
<p style="margin-top: 100px">scroll down and watch the header become smaller</p>
<p style="margin-top: 100px">scroll down and watch the header become smaller</p>
<p id="offset">0px</p>
<!--
define the scroll range you want to resize within
(scroll.min, scroll.max)
define the minimum size to shrink to
use font-size as the one property to set,
so each "em"-specified element inherits the new size
use transitions to make things smoother
-->
CSS
header {
position: fixed;
top:0; right:0; left: 0;
background: #333;
padding: 0;
font-size: 20px;
}
header > h1 {
color: #EEE;
padding: 0.5em;
font-size: 2em;
/* making things smoother */
-webkit-transition: font-size linear 0.5s,
padding linear 0.5s;
-moz-transition: font-size linear 0.5s,
padding linear 0.5s;
transition: font-size linear 0.5s,
padding linear 0.5s;
}
#offset {
position: fixed;
bottom: 0; left: 0;
}
JavaScript
var $header = $('body > header'),
$offset = $('#offset'),
$document = $(document),
scroll = {
min: 100,
max: 200
},
current = null,
size = {
min: 10,
max: parseInt($header.css('font-size') || "0", 10)
};
// make sure min < max
if (size.min > size.max) {
var t = size.min;
size.min = size.max;
size.max = t;
delete t;
}
// calculate ranges
size.range = size.max - size.min;
scroll.range = scroll.max - scroll.min;
// bind scroll handler
$(window).on('scroll', function(e) {
// get current scroll offset
var so = $document.scrollTop(),
// reversed percentage scrolled withing scroll.range
p = 1 - (so - scroll.min) / scroll.range,
s;
// respect boundaries
if (so < scroll.min) {
p = 1;
$offset.text(so +"px (below bounds)");
} else if (so > scroll.max) {
p = 0;
$offset.text(so +"px (above bounds)");
} else {
$offset.text(so +"px (within bounds)");
}
// calculate font-size according to scroll offset
s = Math.round(size.min + p * size.range);
// abort if that's our current value, no need to access DOM
if (s == current) {
return;
}
// update font-size
current = s;
$header.css('font-size', s);
});