简体   繁体   中英

Add bounce effect to scroll

I am trying to create a smooth scrolling experience **with* a bounce effect when the user over-scrolls, ie scrolls too much to the bottom or top. This answer answers how to scroll smoothly, but I'm also trying to bounce when it scrolls out of bounds. Something like this:

Note. Although this gif shows for mobile, I want to implement that for all browsers, desktop and mobil.

在此输入图像描述

I tried adding the following code to the interval:

// 50 = Padding
if (tgt.scrollTop < 50 || tgt.scrollTop > tgt.scrollHeight - tgt.offsetHeight - 50) {
    pos = Math.bounce(step++, start, change, steps);
} else {
    pos = Math.easeOut(step++, start, change, steps);
}

But it doesn't give the desired effect. It doesn't bounce at the correct scrolling time, and the bounce isn't real looking, it's not big enough.

(I'm looking for something like this effect , but I want to create it myself, and understand the code.)

How can I create a bouncing effect when the scroll goes to the top or bottom?

I don't want answers with a link to a complex library because I want to create it myself. And I want vanilla JavaScript.

JSFiddle

 console.clear(); /* Smooth scroll */ Math.easeOut = function(t, b, c, d) { t /= d; return -c * t * (t - 2) + b; }; // Out Back Quartic Math.bounce = function(t, b, c, d) { var ts = (t /= d) * t; var tc = ts * t; return b + c * (4 * tc + -9 * ts + 6 * t); }; (function() { // do not mess global space var interval, // scroll is being eased mult = 0, // how fast do we scroll dir = 0, // 1 = scroll down, -1 = scroll up steps = 50, // how many steps in animation length = 30; // how long to animate function MouseWheelHandler(e) { e.preventDefault(); // prevent default browser scroll clearInterval(interval); // cancel previous animation ++mult; // we are going to scroll faster var delta = -Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))); if (dir != delta) { // scroll direction changed mult = 1; // start slowly dir = delta; } for (var tgt = e.target; tgt != document.documentElement; tgt = tgt.parentNode) { var oldScroll = tgt.scrollTop; tgt.scrollTop += delta; if (oldScroll != tgt.scrollTop) break; } var start = tgt.scrollTop; var end = start + length * mult * delta; // where to end the scroll var change = end - start; // base change in one step var step = 0; // current step interval = setInterval(function() { var pos; // 50 = Padding if (tgt.scrollTop < 50 || tgt.scrollTop > tgt.scrollHeight - tgt.offsetHeight - 50) { pos = Math.bounce(step++, start, change, steps); } else { pos = Math.easeOut(step++, start, change, steps); } tgt.scrollTop = pos; if (step >= steps) { // scroll finished without speed up - stop by easing out mult = 0; clearInterval(interval); } }, 10); } var myP = document.getElementById('myP'); myP.addEventListener("mousewheel", MouseWheelHandler, false); // window.addEventListener("DOMMouseScroll", MouseWheelHandler, false); })(); 
 p { height: 300px; overflow: auto; background-color: orange; padding: 50px 0; } 
 <p id="myP">Lorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempusLorem ipsum dolor sit amet consectetuer laoreet faucibus id ut et. Consequat Ut tellus enim ante nulla molestie vitae sem interdum turpis. Fames ridiculus cursus pellentesque Vestibulum justo sem lorem neque accumsan nulla. Lacinia Suspendisse vitae libero sem et laoreet risus Sed condimentum Cras. Nunc massa mauris tempor dolor pulvinar justo neque dui ipsum vitae. Lacinia dui scelerisque Sed convallis nonummy orci Vestibulum orci tempus</p> 

Well, I'm the author of smooth-scrollbar :)

Actually, this question may be much more complex than you've ever imagined. Now I'll show you a basic implement of overscroll bouncing. Demo

We're 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 to create a render loop that applies transform style into .content :

function render() {
    content.style.transform = `translate3d(...)`;

    requestAnimationFrame(render);
}

render();

And now, let's initialize two variables for state recording:

let offset = 0;     // final position
let rendered = 0;   // rendered part

Then, applying momentum scrolling with a damping factor:

const damping = 0.8;

function render() {
    ...
    const dis = offset - rendered;

    // throw away float part
    const next = offset - (dis * damping | 0);

    content.style.transform = `translate3d(0, ${-next}px, 0)`;
    rendered = next;
    ...
}

By now, we can scroll to the offset we want, but what about the springback?

The magic is reducing offset while rendering, therefore the change of offset will be like a normal curve - from 0 to highest then falling back to 0:

function render() {
    ...
    offset = offset / 2 | 0;
    ...
}

Now the render function is like this:

function render() {
    const dis = offset - rendered;

    // throw away float part
    const next = offset - (dis * damping | 0);

    content.style.transform = `translate3d(0, ${-next}px, 0)`;

    rendered = next;
    offset = offset / 2 | 0;

    requestAnimationFrame(render);
}

Hmmm, it looks much nicer now! The last thing is to handle input events(wheel, touch...), here's 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;
    });
});

Okay, now we got a basic bouncing model. You can check full code on Codepen: http://codepen.io/idiotWu/pen/EgNdXK .

However, there are still dozens of issues to be fixed. For example, since we're not able to detect whether user left the trackpad(like touchend event), we can't perform springback like the native one - scrolling back when users moved away from their trackpad. And as a result, you may suffer from shaking when over scrolling.

To avoid shaking, you can set a flag to prevent movement from increasing as what I have tried . The major idea is to ignore wheel events when it's scrolling back.

===========

As for mobile devices, you can write you 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 reducing. It would be a bit hard to play with so many states.

FYI: smooth-scrollbar/touch.js

Here is a quick try with Jquery - works with the mousewheel; the vital points:

  • Capture the 'up' mousewheel event
  • Increase margin-top of element and use transition to animate
  • Set max value to offset and a time to reset

Check this snippet:

 $(function() { var more = 20; $('body').on('mousewheel', function(e) { if (e.originalEvent.wheelDelta / 120 > 0) { var st = $(window).scrollTop(); if (st == 0 && more < 160) { $('div').css({ 'margin-top': more + 'px' }); more += 20 } else { $('div').css({ 'margin-top': '0' }); more = 0; } setTimeout(function() { $('div').css({ 'margin-top': '0' }); more = 0; }, 500) } }) }); 
 body { background: #f6f6f6; height: 1000px; padding-top: 50px; } div { width: 80%; margin: 0 auto; background: white; height: 400px; transition: .3s margin linear; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div></div> 


Or JsfiddleDemo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM