idiotWu / smooth-scrollbar

Customizable, Extendable, and High-Performance JavaScript-Based Scrollbar Solution.

Home Page:https://idiotwu.github.io/smooth-scrollbar/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Idea/v9] Slow down scrolling on hitting Upper and Lower Page End

idiotWu opened this issue · comments

Discussed in #398

Originally posted by blitzve0 October 31, 2021
Currently when we keep scrolling and reach the end of the page or top of the page, the page abruptly stops on hitting the end. If the scroller would slow down and smooth out when hitting the edges the experience would be much more impressive

//& Edge Damping Plugin for Smooth Scrollbar
import Scrollbar from "smooth-scrollbar";

class EdgeDamping extends Scrollbar.ScrollbarPlugin {
  transformDelta(delta, fromEvent) {
    const dirX = delta.x > 0 ? 1 : -1;
    const dirY = delta.y > 0 ? 1 : -1;

    if (dirX === this.lockX || dirY === this.lockY) {
      return { x: 0, y: 0 };
    } else {
      this.lockX = null;
      this.lockY = null;
    }

    return delta;
  }

  onRender(Data2d) {
    const { x, y } = Data2d;

    //@ Scroll Up
    if (y < 0 && !this.lockY && Math.abs(y) >= this.scrollbar.scrollTop) {
      this.scrollbar.setMomentum(0, -this.scrollbar.scrollTop);
      this.lockY = -1;
    }

    //@ Scroll Left
    if (x < 0 && !this.lockX && Math.abs(x) >= this.scrollbar.scrollLeft) {
      this.scrollbar.setMomentum(-this.scrollbar.scrollLeft, 0);
      this.lockX = -1;
    }

    //@ Scroll Right
    if (
      x > 0 &&
      !this.lockX &&
      Math.abs(x) >= this.scrollbar.limit.x - this.scrollbar.scrollLeft
    ) {
      this.scrollbar.setMomentum(
        this.scrollbar.limit.x - this.scrollbar.scrollLeft,
        0
      );
      this.lockX = 1;
    }

    //@ Scroll Down
    if (
      y > 0 &&
      !this.lockY &&
      Math.abs(y) >= this.scrollbar.limit.y - this.scrollbar.scrollTop
    ) {
      this.scrollbar.setMomentum(
        0,
        this.scrollbar.limit.y - this.scrollbar.scrollTop
      );
      this.lockY = 1;
    }

    if (y === 0) this.lockY = null;
    if (x === 0) this.lockX = null;
  }
}
//& Register Plugin name and Export Class
EdgeDamping.pluginName = "EdgeDamping";
export default EdgeDamping;

Just use this Plugin

@idiotWu It would be nice if the plugin was included in the official package.
I wouldn't need to copy it to every project :)

The plugin works great on all projects (over 20+) that i have implemented.
Since 2018 version, I have slightly modified it:

/*!
 * SmoothScrollbar Soft Scroll Plugin
 *
 * @version 1.1.0
 * @author Artem Dordzhiev (Draft)
 */

import Scrollbar from "smooth-scrollbar";

export default class SoftScrollPlugin extends Scrollbar.ScrollbarPlugin {
    static pluginName = 'SoftScroll';

    transformDelta(delta, fromEvent) {
        const dirX = delta.x > 0 ? 1 : -1;
        const dirY = delta.y > 0 ? 1 : -1;

        dirX === this.lockX ? delta.x = 0 : this.lockX = 0;
        dirY === this.lockY ? delta.y = 0 : this.lockY = 0;

        return delta;
    }

    onRender(Data2d) {
        const {x, y} = Data2d;

        // Up
        if (y < 0 && !this.lockY && Math.abs(y) >= this.scrollbar.scrollTop) {
            this.scrollbar.setMomentum(0, -this.scrollbar.scrollTop);
            this.lockY = -1;
        }

        // Left
        if (x < 0 && !this.lockX && Math.abs(x) >= this.scrollbar.scrollLeft) {
            this.scrollbar.setMomentum(-this.scrollbar.scrollLeft, 0);
            this.lockX = -1;
        }

        // Right
        if (x > 0 && !this.lockX && Math.abs(x) >= (this.scrollbar.limit.x - this.scrollbar.scrollLeft)) {
            this.scrollbar.setMomentum((this.scrollbar.limit.x - this.scrollbar.scrollLeft), 0);
            this.lockX = 1;
        }

        // Down
        if (y > 0 && !this.lockY && Math.abs(y) >= (this.scrollbar.limit.y - this.scrollbar.scrollTop)) {
            this.scrollbar.setMomentum(0, (this.scrollbar.limit.y - this.scrollbar.scrollTop));
            this.lockY = 1;
        }

        if (y === 0) this.lockY = 0;
        if (x === 0) this.lockX = 0;
    }
}