添加弹跳效果以滚动

时间:2016-09-13 21:07:07

标签: javascript css

我正在尝试创建一个平滑的滚动体验**,当用户过度滚动时会产生*反弹效果,即滚动太多到底部或顶部。 This answer回答如何平滑滚动,但我也试图在滚出界限时反弹。像这样:

请注意。虽然这个gif显示的是移动设备,但我希望为所有浏览器,桌面设备和移动设备实现这一功能。

enter image description here

我尝试将以下代码添加到区间:

// 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);
}

但它没有产生预期的效果。它没有在正确的滚动时间反弹,并且反弹不是真实的,它不够大。

(我正在寻找像this effect这样的东西,但我想自己创建它,并理解代码。)

当滚动到达顶部或底部时,如何创建弹跳效果?

我不想要链接到复杂库的答案,因为我想自己创建它。我想要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>

2 个答案:

答案 0 :(得分:5)

好吧,我是smooth-scrollbar的作者:)

实际上,这个问题可能比你想象的要复杂得多。现在我将向您展示过度弹跳的基本实现。 Demo

我们将使用CSS 3d变换来模拟弹跳效果,因此DOM结构将是:

<article class="container">
    <section class="content">
        your content...
    </section>
</article>

要做的第一件事是创建一个渲染循环,将变换样式应用到.content

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

    requestAnimationFrame(render);
}

render();

现在,让我们初始化两个状态记录变量:

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

然后,使用阻尼因子应用动量滚动:

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;
    ...
}

到现在为止,我们可以滚动到我们想要的偏移量,但是回弹呢?

渲染时神奇正在减少offset,因此offset的变化将像正常曲线一样 - 从0到最高然后再回落到0:

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

现在render函数是这样的:

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);
}
嗯,现在看起来好多了!最后一件事是处理输入事件(wheel,touch ...),这里是一个简单的轮子事件片段:

// 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;
    });
});

好的,现在我们得到了一个基本的弹跳模型。您可以在Codepen上查看完整代码:http://codepen.io/idiotWu/pen/EgNdXK

然而,仍有数十个问题需要解决。例如,由于我们无法检测用户是否离开了触控板(如touchend事件),因此我们无法像本机一样执行回弹 - 当用户离开触控板时向后滚动。因此,滚动时可能会发生震动。

为避免晃动,您可以设置一个标记以防止移动增加为what I have tried。主要思想是在滚动回来时忽略滚轮事件。

===========

对于移动设备,您可以为触摸事件编写自己的处理程序。但请记住,在释放手指之前不应向后滚动,因此您可能需要另一个标记来阻止offset缩小。与这么多州一起玩会有点困难。

仅供参考:smooth-scrollbar/touch.js

答案 1 :(得分:3)

使用 Jquery 进行快速尝试 - 使用鼠标滚轮;关键点:

  • 捕捉'向上'鼠标滚轮事件
  • 增加margin-top元素并使用transition制作动画
  • 将最大值设置为偏移量和重置时间

检查此代码段:

$(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>

JsfiddleDemo