Skip to content

A TypeScript module that allows having both scroll snapping and normal scrolling between sections in your website

License

Notifications You must be signed in to change notification settings

Syrian-Open-Source/custom-snap

Repository files navigation

Custom Snap - Snap and normal scrolling at once

npm version License: MIT

A TypeScript module that lets you have both scroll snapping and native scrolling functionality in different sections of your website.

Demo link: https://syrian-open-source.github.io/custom-snap/

Features

  • Lightweight and simple (0 dependencies)
  • Works with both fullpage sections (100vh) and variable height sections.
  • You can customize the snap scrolling's duration and easing presets
  • You can have as many normal scroll sections as you want.

Installation

npm install custom-snap

Example usage

HTML structure

<div id="container">
	<div id="a" class="section"></div>
	<div id="b" class="section"></div>
	<div id="c" class="section long-content"></div>
	<div id="d" class="section"></div>
	<div id="e" class="section long-content"></div>
	<div id="f" class="section"></div>
</div>

CSS

/* Height values are arbitrary. You can choose any height you want */
.section {
	height: 100vh;
}

.long-content {
	height: 200vh;
}

JS

import { CustomSnap } from "custom-snap";

const scrollInstance = new CustomSnap({
	containerID: "container",
	normalScrollElementIDs: ["c", "e"],
	afterSnap: (id, section) => {},
	beforeSnap: (id, section) => {},
});

scrollInstance.register();

In this example, sections with ids c and d will have normal scrolling, while all other children of #container will have snap scrolling.

Important!: You have to specify an ID on every child of the container.

Indexing

Section a has index 0, b has index 1, and so on... Section f has index 5.

This is useful in case you want to scroll programmatically using the scrollToSectionByIndex method.

Options

Key Description Type Default value
containerID ID of the wrapping container string none
hideScrollbar Whether to hide the browser's scrollbar or not boolean false
normalScrollElementIDs IDs of the sections to which scroll snapping doesn't apply string[] []
snapDuration The duration that scroll snapping takes in milliseconds number 1000 (ms)
easingPreset The transition timing function that gets applied to snapping EasingPreset easeInOutQuad
afterSnap A function that gets called after snap scrolling is performed OnEventCallback () => {}
beforeSnap A function that gets called just before snap scrolling is performed OnEventCallback () => {}

Instance methods

/**
 * Sets a new easing preset for snap scrolling
 */
setEasingPreset(easingPreset: EasingPreset): void

/**
 * Sets a new duration for snap scrolling
 */
setSnapDuration(duration = 1000): void

/**
 * Returns the scroll's direction
 */
getScrollDirection(): ScrollDirection

/**
 * Hides the browser's scrollbar using CSS
 */
hideScrollbar(): void

/**
 * Shows the browser's scrollbar
 */
showScrollbar(): void

/**
 * Scrolls to a specific section over a period of time.
 */
scrollToSectionByIndex(index: number, duration = 1000): void

/**
 * Registers the snap scroll event listener.
 * Note that without invoking this function, all scrolling
 * would be considered normal.
 */
register(): void

/**
 * Removes the currently bound scroll event listener.
 * After unregistering, all scrolling would be considered normal.
 */
unregister(): void

Types

type EasingPreset = "easeInOutQuad" | "easeInCubic" | "inOutQuintic";
type ScrollDirection = "top-to-bottom" | "bottom-to-top" | "";

interface OnEventCallback {
	(id?: number, section?: HTMLElement | null): void;
}

Inspiration

Credits

About Syrian Open Source

The Syrian Open Source platform is the first platform on GitHub dedicated to bringing Syrian developers from different cultures and experiences together, to work on projects in different languages, tasks, and versions, and works to attract Syrian developers to contribute more under one platform to open source software, work on it, and issue it with high quality and advanced engineering features, which It stimulates the dissemination of the open-source concept in the Syrian software community, and also contributes to raising the efficiency of developers by working on distributed systems and teams.