Skip to content

Instantly share code, notes, and snippets.

@BASICjfisher
Last active August 29, 2015 14:14
Show Gist options
  • Save BASICjfisher/568f9f2871882c31d847 to your computer and use it in GitHub Desktop.
Save BASICjfisher/568f9f2871882c31d847 to your computer and use it in GitHub Desktop.
Native Virtual scroll
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Scroll Test</title>
<style>
* {
box-sizing: border-box;
-webkit-backface-visibility: hidden;
-webkit-transform-style: flat;
}
html, body {
margin: 0;
padding: 0;
font-family: Myriad Pro;
height: 100%;
position: relative;
}
.inner, .scroll {
height: 5000px;
background-color: #f9f9f9;
}
.viewport {
display: block;
position: fixed;
top: 0;
right: 0;
left: 0;
overflow: visible;
z-index: 2;
width: 100%;
height: 100%;
}
.stats {
padding: 10px;
position: fixed;
z-index: 100;
}
.container {
text-align: center;
height: 1000px;
font-size: 50px;
-webkit-transform: translateZ(0);
}
.square {
width: 100px;
height: 100px;
position: absolute;
z-index: 200;
top: 50%;
left: 50%;
margin: -50px 0 0 -50px;
background-color: red;
}
</style>
</head>
<body>
<div class="stats"></div>
<div class="scroll"></div>
<div class="viewport">
<div class="inner">
<div class="square"></div>
<div class="container">1</div>
<div class="container">2</div>
<div class="container">3</div>
<div class="container">4</div>
<div class="container">5</div>
</div>
</div>
<script>
window.scrollTo(0, 0);
var lastScrollY = 0, lastScrollX = 0, percent;
var ease = 0.075;
var ticking = false;
var totalHeight = document.body.scrollHeight;
var smoothY = 0;
var stats = document.querySelector('.stats');
var square = document.querySelector('.square');
var inner = document.querySelector('.inner');
function isElementInViewport (el) {
var rect = el.getBoundingClientRect();
return (
rect.top >= (0 - el.scrollHeight) &&
rect.left >= (0 - el.scrollWidth) &&
rect.bottom <= (window.innerHeight + el.scrollHeight || document.documentElement.clientHeight + el.scrollHeight) &&
rect.right <= (window.innerWidth + el.scrollWidth || document.documentElement.clientWidth + el.scrollWidth)
);
}
function render() {
smoothY += Math.ceil((lastScrollY - smoothY) * ease);
percent = totalHeight / lastScrollY;
percent = Math.ceil(360 * lastScrollY / (totalHeight - window.innerHeight));
var visible = isElementInViewport(square);
stats.innerHTML = 'x: ' + lastScrollX + ' y: ' + lastScrollY;
if( visible ) stats.innerHTML += '<br />The square is visible!';
// inner.style.backgroundColor = 'hsla(' + percent + ', 50%, 45%, 1)';
inner.style.webkitTransform = 'translate3d(0, ' + (-smoothY) + 'px, 0)';
if(smoothY == lastScrollY) ticking = false;
else requestAnimationFrame(render);
};
function handler(e) {
lastScrollY = window.scrollY;
lastScrollX = window.scrollX;
update();
};
function update() {
if( !ticking ) {
requestAnimationFrame(render);
ticking = true;
}
}
var touch = 'ontouchstart' in document;
if(!touch) {
window.addEventListener('scroll', handler);
} else {
// window.addEventListener('touchstart', handler);
window.addEventListener('touchend', handler);
window.addEventListener('touchmove', handler);
}
update();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment