GithubHelp home page GithubHelp logo

lucafalasco / scroll-snap Goto Github PK

View Code? Open in Web Editor NEW
750.0 7.0 30.0 1.08 MB

↯ Snap page when user stops scrolling, with a customizable configuration and a consistent cross browser behaviour

Home Page: http://lucafalasco.github.io/scroll-snap/

License: MIT License

JavaScript 3.23% TypeScript 81.58% HTML 7.22% CSS 7.97%
scrolling scroll snap scroll-events

scroll-snap's Introduction

scroll-snap


npm npm npm downloads

Snap page when user stops scrolling, basically implements CSS Scroll Snap, adding a customizable configuration and a consistent cross browser behaviour.

  • Works in all modern browsers
  • requestAnimationFrame for 60fps
  • Customizable settings (including easing functions)
  • No additional dependencies
  • No extra stylesheet

Installation

yarn add scroll-snap

You can also grab a pre-built version from unpkg

Usage

createScrollSnap(element, settings, [callback])

Arguments

element: HTMLElement

The HTML DOM Element to attach the scroll listener to.

settings: Settings

A configuration object consisting of one or more of the following keys:

snapDestinationX: string | number

Snap destination for x axis, should be a valid css value expressed as px | % | vw | vh

snapDestinationY: string | number

Snap destination for y axis, should be a valid css value expressed as px | % | vw | vh

timeout: number

Time in ms after which scrolling is considered finished
[default: 100]

duration: number

Duration in ms for the smooth snap
[default: 300]

threshold: number

Threshold to reach before scrolling to next/prev element, expressed as a percentage in the range [0, 1]
[default: 0.2]

snapStop: boolean

When true, the scroll container is not allowed to "pass over" the other snap positions
[default: false]

easing: (t: number) => number

Custom easing function
@param t: normalized time typically in the range [0, 1]
[default: easeInOutQuad]

For reference: https://gist.github.com/gre/1650294

callback: () => void [Optional]

Optional callback to execute once the animation ends.

Returns

An object including two handlers to manually attach and remove the scroll event listener

{
  // attaches the scroll event listener 
  bind: () => void 
  // removes the scroll event listener
  unbind: () => void 
}

Example

import createScrollSnap from 'scroll-snap'

const element = document.getElementById('container')

const { bind, unbind } = createScrollSnap(element, {
  snapDestinationX: '0%',
  snapDestinationY: '90%',
  timeout: 100,
  duration: 300,
  threshold: 0.2,
  snapStop: false,
  easing: easeInOutQuad,
}, () => console.log('element snapped'))

// remove the listener 
// unbind();

// re-instantiate the listener 
// bind();

Contributing

git clone https://github.com/lucafalasco/scroll-snap.git
cd scroll-snap
yarn install

Start the testing environment from playground/:

yarn start

Build lib for production:

yarn build

License

MIT

scroll-snap's People

Contributors

akhigbe-e avatar dasilvacontin avatar dependabot[bot] avatar fauzanrh avatar geecko86 avatar lucafalasco avatar renbaoshuo avatar tqwewe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

scroll-snap's Issues

add UMD version

In any case, I may consider adding a UMD format version for environments that do not support import.
That way it would also be easier to load scoll-snap without a bundler or module system. 👍

Originally posted by @lucafalasco in #7 (comment)

Is it possible to always stop to a snap point

Everything works great so far, I'm really liking the library.
I have a question though, specifically for touch devices. On a desktop, when scrolling, the scroll event takes about 100ms or less and it triggers only once, therefore the container scrolls only one page at a time. But on a touch device, the scroll event takes much more than 100ms, because of some kind of smoothness, therefore when I have the duration set to 100, the callback is fired more than once.
This can be tested on this demo, https://codesandbox.io/s/scroll-snap-react-eqxnx?file=/src/index.js
I am using latest Chrome, toggling a touch device.

new

[Enhancement] Support sections taller than the viewport

Cool little library! A great addition would be the option to have sections taller than the viewport. They could snap to the top and have free scrolling until you reach their end.

This is currently not possible with CSS snap points and would be a handy advantage compared to the native implementation...

Support Scroll Snap Stop

Is there any way to implement an equivalent of the css scroll-snap-stop property? I need to find a way to prevent scrolling past more than 1 element at a time.

Documentation incorrect

Thanks for developing this plug-in.

In trying to implement the example code, I found that the scrollSnapDestination value of '90% 0%' is incorrect (the snapping does not animate). Instead the value should be '0% 90%'.

Unexpected token export

Having this error while trying to simply import the package. The reason is most certainly that the output bundle uses export default syntax.

Scroll to active target element on window resize

Currently when you resize the window (such as closing the downloads toolbar on Chrome), no scrolling occurs with scroll-snap.

Is is possible to make scroll snap take action to scroll to the active element on window resize?

Scrolling quickly to the left will result in bouncing behavior between the first two columns.

First off, thanks so much for deploying this package to npm.

To recreate the issue, reduce the width of the top level container to 50%. Then, with the second column in view, scroll quickly to the left. You'll notice that the snap points will jump back and forth between columns until finally snapping to either the second or the first column.

What can be done to resolve this issue? I will be more than happy to create a pull request.

Thanks again!

Unable to use with react-scroll

Hi I am using React.js I am trying snap then scroll, the scroll-snap is working very good but I am facing difficulty to use with react-scroll. I found another library react-use-scroll-snap which does support react-scroll. Thank you for listening

Weird behaviour on iphone

Hello,

I tested the same setup on android with google chrome and on ios 13 and 14 with both safari and google chrome.
On android the snapping is instant, while on ios there is a great amount of delay until the snapping kicks in.
Here is my setup:
const createScrollSnap = require('scroll-snap').default;
createScrollSnap(
element,
{
snapDestinationX: '0%',
snapDestinationY: '100%',
timeout: 0,
duration: 0,
threshold: 0.1,
easing: (t) => (t * t * t),
},
onSnap,
);

I tried different variations of this but it seemed to have no effect on the time it takes to snap.
Is this a ios problem and is there anything I can do?
Thank you

scroll-snap doesn't work in my current project without any error

Screenshot 2020-06-11 at 6 29 47 AM

I tried the example code, and when I console.log the function and dom, it shows correctly, but the snap function doesn't work like the example given.
It also doesn't show any error, just doesn't work when I scroll per each section.

Do I implement it in a wrong way? or do you have any idea / suggestion how to fix/ debug this issue?
Thanks in advance.

Breaks the scrollbar

Simply looking at the demo if you click the scrollbar, scroll down a bit and don't release your mouse for a while the scroll snapping kicks in and interrupts your flow. Basically this library breaks your scrollbar if your scrolling too slow - is this intentional or a limitation?

equivalent to scroll-snap-align: end? use case = small section on bottom

I am successfully using scroll-snap on a React project however I need to have a footer on bottom which can be scrolled to without scrolling backup automatically, as it happens now with my current setup, see example here => https://codesandbox.io/s/scroll-snap-react-forked-3rmqs?file=/src/index.js

When I was using CSS scroll-snap I was using scroll-snap-align: end; on the sections to avoid this problem but there is no such option in scroll-snap config. Any idea? Moving the footer out of the snap container is not an option as it needs to appear only when scrolled.

Isn't working with Next.JS

I'm trying to implement the scroll-snap in my Next.JS application, but can't make this to work.

My implementation looks like following:

import { useEffect } from 'react';
import ScrollSnap from 'scroll-snap';

export default function Home()
{
    useEffect(() => {
        console.log("Bind snap");
        const element = document.getElementById("home");
        const snapElement = new ScrollSnap(element, {
            snapDestinationY: '90%',
        });
        console.log(snapElement);
        snapElement.bind(snapCallback);
      }, []);

    const snapCallback = () => {
        console.log("Snapped");
    };

    return (
        <div id="home">
            <Head>
                <title>Homepage</title>
            </Head>
      
            <section className="container-fluid top-section">
                <div className="container">
                    <div className="row justify-content-center fullheight-section py-4">
                        <h3>Section 1</h1>
                    </div>
                </div>
            </section>

            <section className="container-fluid top-section">
                <div className="container">
                    <div className="row justify-content-center fullheight-section py-4">
                        <h3>Section 2</h1>
                    </div>
                </div>
            </section>

            <section className="container-fluid top-section">
                <div className="container">
                    <div className="row justify-content-center fullheight-section py-4">
                        <h3>Section 3</h1>
                    </div>
                </div>
            </section>

            <section className="container-fluid top-section">
                <div className="container">
                    <div className="row justify-content-center fullheight-section py-4">
                        <h3>Section 4</h1>
                    </div>
                </div>
            </section>
        </div>
    );
}

Also tried replacing the document.getElementById to an ref object, this way:

import { useEffect, createRef } from 'react';
import ScrollSnap from 'scroll-snap';

export default function Home()
{
    const mainRef = createRef();

    useEffect(() => {
        console.log("Bind snap");
        const element = mainRef.current;
        [...]
        console.log(snapElement);
        snapElement.bind(snapCallback);
      }, []);

      [...]

    return (
        <div id="home" ref={mainRef}>
            [...]
        </div>
    );
}

But, both ways are not working. The "Bind snap" message shows on console, as the snapElement object, but the "Snapped" message (from callback) never shows up.

Since my implementation follows the explained one in the readme, I think this is a bug related to Next.JS. Or, if I'm doing something stupid, can you tell me what I'm doing wrong please?

Set initial scroll position when creating new ScrollSnap

It would be nice to have an initial scroll position option for when creating new ScrollSnap(el, config).
Currently I'm trying to set the page scroll top to be a number that is not 0, but unfortunately ScrollSnap takes over and scrolls back up to the top instantly.

Perhaps a config option like:

initialScrollPosition: { x: 0, y: 800 }

or just setting the initial scroll position to the current position.

Avoid using position: relative/absolute

So using this script I have to set the container to have postition absolute or relative for the effect to work on my page. But doing this breaks a lot of other stuff which can't be fixed if it has a absolute/relative parent.
Codepen: https://codesandbox.io/s/scroll-snap-react-06hr6
I want the footer to stay at the bottom of "homepage" and even if you scroll the footer shouldn't move.

This worked perfectly fine before I added the container.

Can't use with a TypeScript project

Once the lib is imported to the project, I get a Could not find a declaration file for module 'scroll-snap'. , exporting a file with types would be super helpful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.