npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

scroll-utility

v4.0.2

Published

A simple to use scroll utility package for centering elements, and smooth animations

Downloads

136

Readme

scroll-utility

npm
Travis Maintainability Greenkeeper badge Gitter

Table of Contents

Features

  • Smooth scroll inside any element in any direction
  • Center elements
  • Extremely precise
  • Handle multiple scroll animation at the time
  • High performance
  • Detect onScroll events and differentiate between user and utility scroll
  • React to elements position changes
  • Customize easing function used to animate the scroll
  • Typescript support

Installation

It can be installed from npm,

$ npm install --save scroll-utility

or from a cdn at jsdelivr

<script src="https://cdn.jsdelivr.net/npm/scroll-utility@4"></script>

when downloading from a cdn the package will be globally exported as ScrollUtility

Usage

Basic Scroll

import { Scroll } from "scroll-utility"
// const Scroll = ScrollUtility.Scroll // if using from a cdn

const scrollManager = new Scroll()

scrollManager.scrollTo(50) // scroll to position = 50px
scrollManager.scrollTo(50, 1000) // scroll in 1000ms
scrollManager.scrollTo.element("#some-element") // scroll to "#some-element"
scrollManager.scrollTo.element("#some-element", 0.5) // scroll to "#some-element" and center it
scrollManager.scrollTo.element("#some-element", 1, 1000) // scroll to "#some-element" and place it at the bottom of the screen in 1000ms
scrollManager.scrollTo.scrollSize(0) // scroll to the top of the page
scrollManager.scrollTo.scrollSize(1) // scroll to the bottom
scrollManager.scrollTo.scrollSize(0.5, 1000) // scroll to the middle in 1000ms
scrollManager.scrollTo.size(0) // scroll to top (1st 'screen')
scrollManager.scrollTo.size(1) // scroll to the 2nd screen
scrollManager.scrollTo.size(2, 999) // scroll to the 3rd screen in 999ms

scrollManager.scrollBy(50) // scroll by 50px
scrollManager.scrollBy(50, 1000) // scroll by 50px in 1000ms
scrollManager.scrollBy.element("#some-element") // scroll by "#some-element"'s size
scrollManager.scrollBy.element("#some-element", 0.5) // scroll by half of the size of "#some-element"
scrollManager.scrollBy.element("#some-element", 1, 1000) // scroll by "#some-element"' size in 1000ms
scrollManager.scrollBy.element("#some-element", 0) // this don't do any scroll
scrollManager.scrollBy.scrollSize(0.1) // scroll by 10% of the scroll size
scrollManager.scrollBy.size(1) // scroll a screen down
scrollManager.scrollBy.size(-1) // scroll a screen up
scrollManager.scrollBy.size(0.5, 1000) // scroll half a screen down

That's just a quick reference cheat sheet of how to use scroll-utility, if you want to learn more keep reading :)

Creating a scroll manager

import { Scroll } from "scroll-utility"

const scrollManager = new Scroll({
  element: window, // default scroll container is window
  horizontal: false, // default direction vertical
  onScroll: null, // no onScroll callback by default
  duration: 0, // default duration to 0, 'instant' scroll
  easing: defaultEasingFunction, // default easing function is inOutCubic
})

const scrollManagerWithOutOptions = new Scroll() // same as above

scroll wrapper

The element option when creating a 'scrollManager' indicates the element in which the scroll will take place, by default the window

const documentElement = document.querySelector("html")!

let scrollManager = new Scroll() // create a scrollManager for the window
scrollManager = new Scroll({ element: window }) //same as above
scrollManager = new Scroll({ element: "html" }) //same as above
scrollManager = new Scroll({ element: documentElement }) //same as above
scrollManager = new Scroll({ element: document.documentElement }) //same as above

scrollManager = new Scroll({ element: "#some-element" }) // create a scrollManager for the "#some-element"
scrollManager = new Scroll({ element: document.getElementById("some-element") }) // same as above

direction

The horizontal option indicates the direction when scrolling, by default vertical

let scrollManager = new Scroll() // create a scrollManager with vertical scroll (default behavior)
scrollManager = new Scroll({ horizontal: false }) // same as above
scrollManager = new Scroll({ horizontal: true }) // create a scrollManager with horizontal scroll

onScroll callback

let scrollManager = new Scroll() // no callback by default :)
scrollManager = new Scroll({
  onScroll: external => {
    console.log("scrolled!")
    if (external) {
      // external === true if the scroll was triggered by other means (the user with the mouse or other js running in the browser)
    }
  },
})

// can be changed later:
scrollManager.onScroll = () => console.log("new onScroll callback") // callback changed
scrollManager.onScroll = null // go back to default config :)

default duration

The duration option indicates the default duration of the scroll animations in milliseconds, by default 0

let scrollManager = new Scroll() // default duration is 0ms (instant scroll)
scrollManager = new Scroll({ duration: 350 }) // 350ms scroll duration

// can be changed later:
scrollManager.duration = 1000 // 1 second scroll duration

easing

The easing option indicates the default animation of the scroll, which is by default inOutQuad

import { Scroll, defaultEasingFunction } from "scroll-utility"

let scrollManager = new Scroll() // inOutCubic animation by default
scrollManager = new Scroll({ easing: defaultEasingFunction }) // same as above

// can also be changed later:
scrollManager.easing = (currentStep, offsetValue, distance, totalSteps) => {
  // some linear function (I think is linear)
  return distance * (currentStep / totalSteps) + offsetValue
}

Here are some more easing functions

Scrolling

scrollBy

scrollBy will accept a value (the number of px to scroll down), a duration (to override the default duration), and a easing function (to override the default one).
If the value in negative it will scroll up

scrollManager.scrollBy(50) // scroll 50px down
scrollManager.scrollBy(-50) // scroll 50px up
scrollManager.scrollBy(50, 1000) // scroll by 50px in 1000ms
scrollManager.scrollBy(50, 1000, customEasingFunction) // it can also be specified an easing function just for that scroll animation

scrollBy element

The 1st parameter of scrollBy.element is the element whose size will be used to scroll, the rest of parameters same as plane scrollBy

scrollManager.scrollBy.element("#some-element") // scroll by "#some-element"'s size
scrollManager.scrollBy.element("#some-element", 0.5) // scroll by half of the size of "#some-element"
scrollManager.scrollBy.element("#some-element", -1, 1000) // scroll by "#some-element"' size up in 1000ms
scrollManager.scrollBy.element("#some-element", 1, 1000, customEasingFunction) // scroll by "#some-element"' size in 1000ms with a customEasingFunction

scrollBy size

Here the size is the size of the scroll container, and the value passed is a modifier, been 1 the full size, 0.5 half, and a negative value will mean the scroll will be up instead of down (or left instead of right)

scrollManager.scrollBy.size(1) // scroll a screen down
scrollManager.scrollBy.size(-1) // scroll a screen up
scrollManager.scrollBy.size(0.5, 1000) // scroll half a screen down

See size

scrollBy scrollSize

scrollManager.scrollBy.scrollSize(0.1) // scroll by 10% of the scroll size

See scrollSize

scrollTo

scrollTo will accept a value (the position to scroll to), a duration (to override the default duration), and a easing function (to override the default one).

scrollManager.scrollTo(50) // scroll to position = 50px
scrollManager.scrollTo(50, 1000) // scroll in 1000ms

scrollTo element

The 1st parameter of scrollTo.element is the element whose position will be used to scroll, the rest of parameters same as plane scrollTo

For the value used to center the element, it matches the same criteria used in getRelativeElementPosition

scrollManager.scrollTo.element("#some-element") // scroll to "#some-element"
scrollManager.scrollTo.element("#some-element", 0.5) // scroll to "#some-element" and center it
scrollManager.scrollTo.element("#some-element", 1, 1000) // scroll to "#some-element" and place it at the bottom of the screen in 1000ms

scrollTo size

Pretty much the same as scrollBy.size, except it scrolls to instead of by.

scrollManager.scrollTo.size(0) // scroll to top (1st 'screen')
scrollManager.scrollTo.size(1) // scroll to the 2nd screen
scrollManager.scrollTo.size(2, 999) // scroll to the 3rd screen in 999ms

See size

scrollTo scrollSize

Same as scrollBy.scrollSize, except it scrolls to instead of by.

scrollManager.scrollTo.scrollSize(0) // scroll to the top of the page
scrollManager.scrollTo.scrollSize(1) // scroll to the bottom
scrollManager.scrollTo.scrollSize(0.5, 1000) // scroll to the middle in 1000ms

See scrollSize

Computed values

scrollPosition

const scrollManager = new Scroll()

scrollManager.scrollPosition // current position of the scroll (direction depends of the default value passed in the constructor)

size

const scrollManager = new Scroll()

scrollManager.size // the size of the element (excluding its borders and scrollbar's size)

scrollSize

const scrollManager = new Scroll()

scrollManager.scrollSize // the total scroll you can do, (scrollHeight - height (or width depending on the direction))

relativeElementPosition

const relativePosition = new Scroll().getRelativeElementPosition("#some-elemet")

if (relativePosition < -1) {
  /// element is out of view
}
if (relativePosition > -1 && relativePosition < 0) {
  // element bottom is partially visible
}
if (relativePosition > 0 && relativePosition < 1) {
  // element is fully visible
  if (relativePosition === 0.5) {
    // ...element is centered in view
  }
}
if (relativePosition > 1 && relativePosition < 2) {
  // element top is partially visible
}
if (relativePosition > 2) {
  // element is out of view
}

Browser Compatibility

Test are made using automate testing with Browserstack for open source.

Why?

There are a lot of packages about smooth scrolling, so, what's the difference?

Well, the main idea is to be able to stack multiple scroll animations together, and with high precision. That is not an extra feature, that's what this package does, you can trigger multiple animations to several places, and it will be as precise as it can be.

License

MIT

Support

This project is free and open-source, so if you think this project can help you or anyone else, you should star it in github Also feel free to open an issue if you have any idea, question, or you've found a bug. Any feedback is good support