Well, I'm the author of a smooth scrollbar :)
Actually, this question can be much more complicated than you ever imagined. Now I will show you the basic leap tool. Demo
We are going to use CSS 3d transform to simulate the bouncing effect, so the DOM structure will be:
<article class="container"> <section class="content"> your content... </section> </article>
The first thing to do is create a render loop that applies the transform style to .content :
function render() { content.style.transform = `translate3d(...)`; requestAnimationFrame(render); } render();
And now, let initialize two variables to record the state:
let offset = 0; // final position let rendered = 0; // rendered part
Then, by applying a pulse scroll with a damping factor:
const damping = 0.8; function render() { ... const dis = offset - rendered;
Now we can scroll to the desired offset, but what about an elastic return?
The magic reduces offset when rendering, so changing the offset will be like a normal curve - from 0 to the highest, and then returning to 0:
function render() { ... offset = offset / 2 | 0; ... }
The render function now looks like this:
function render() { const dis = offset - rendered;
Hmmm, now it looks much better! The last thing you need to handle input events (wheel, touch ...), here is a simple snippet for wheel events:
// wheel events handler [ 'wheel', 'mousewheel' ].forEach(name => { container.addEventListener(name, evt => { const { y } = getDelta(evt); const nextScroll = container.scrollTop + y; // check if scrolling onto very edge if (nextScroll > 0 && nextScroll < container.scrollHeight - container.clientHeight ) { return; } evt.preventDefault(); offset += y; }); });
Ok, now we have a basic bouncing model. You can check the full code on Codepen: http://codepen.io/idiotWu/pen/EgNdXK .
However, there are many more problems that need to be addressed. For example, since we cannot determine whether the user has left the trackpad (for example, the touchend event), we will not be able to perform resilient, like native, scrolling backward when users move away from their trackpad. And as a result, you may suffer from shaking while scrolling.
To avoid shaking, you can set a flag to prevent an increase in movement, like what I tried . The basic idea is to ignore wheel events when scrolling backward.
============
For mobile devices, you can write your own handlers for touch events. But keep in mind that it should not scroll back until you release your fingers, so you may need another flag to keep offset from decreasing. It would be a little difficult to play with many states.
FYI: smooth-scrollbar / touch.js