d4nyll / smartscroll

jQuery plugin for scrolljacking and auto-hashing
https://d4nyll.github.io/smartscroll/
MIT License
257 stars 45 forks source link

Only need swipeUp & swipeDown event on Trackpads / mousewheels #34

Closed katerlouis closed 7 years ago

katerlouis commented 7 years ago

I am desperately looking for a way to detect a swipe on trackpads and "a single flick" on mousewheels. Unfortunately I can't find a way to extract these bits out of your code and don't see a way to only use these events from your library.

Of course I have EmitterEvents.js and lethargy.js installed aswell.

Could you please tell me a way to callback only on swipeUp / swipeDown without doing altering anything else?

d4nyll commented 7 years ago

I am not sure I understand your question properly - if you only want to add a callback to swipeUp and swipeDown, then only define an event listener for those events?

var ee = new EventEmitter();
var swipeUpListener = function () {
  console.log("Swiping Up");
}
var swipeDownListener = function () {
  console.log("Swiping Down");
}
$.smartscroll({
  ...
  eventEmitter: ee,
  bindSwipe: true
});
ee.addListener('swipeUp', swipeUpListener);
ee.addListener('swipeDown', swipeDownListener);

But if you only want a library to detect scroll intents, then lethargy should be sufficient.

katerlouis commented 7 years ago

Thanks for the quick answer, wow– I have a single page with 100%-height-panels and want to make custom transitions for each panel animated with GSAP. Therefore all I need is a detection for swipeUp / swipeDown–

I tried only using lethargy.js and fiddled around with the options and still get multiple events fired per swipe.

The snipped you just posted is what I am trying at the moment, but can't get smartscroll to work I guess? When initiating smartscroll I get the following error:

TypeError: undefined is not an object (evaluating 'g.position().top')

katerlouis commented 7 years ago

It would be great to only use lethargy.js; but I just don't understand how you did "the green dots" in the demo. Here is what I have with lethargy.js

1 and -1 are still fired a bazillion times.

    $(window).bind('mousewheel DOMMouseScroll wheel MozMousePixelScroll', function(e){
        e.preventDefault()
        e.stopPropagation();
        if(lethargy.check(e) !== false) {
            console.log(lethargy.check(e));

            if (lethargy.check(e) < 0) nextPanel();
            else if (lethargy.check(e) > 0) prevPanel();
        }
    });

(the lethargy demo doesn't fire intents on very subtle swipe downs, which I'd like to have)

katerlouis commented 7 years ago

Console from your demo. Are my trackpad settings crazy? To see if we're on the same page: lethargy should only produce single 1s and -1s, right?

image

d4nyll commented 7 years ago

Lethargy doesn't work for the first 15 events or so. This is because it must hold a cache of past events to determine whether the next event is likely to be an intent or not. If you see real carefully, the first 15 events would all be green, only when the initial 15-unit cache has been filled would lethargy work properly.

This is not normally an issue because a single scroll / swipe fires 10-20 events anyways, so the cache fills up quickly.

Regarding your console output, you're likely using a trackpad which has the following profile:

So it's unlike other trackpads which has a decay:

Lethargy works by detecting decay in the delta values of the scroll events. Since your trackpad has not decay, all lethargy can do is to throttle the firing of new events by 150 milliseconds.

You can wrap lethargy in your own debounce/throttle function. For example, if you know that the slide animations would take at least 1 second to complete, then debounce/throttle it for 1 second.

See The Difference Between Throttling and Debouncing for more information.

FYI, if you use a mouse wheel, you would get the following console output in the demo.

lethargy-mouse-wheel

katerlouis commented 7 years ago

Okay, thanks for the info; Back to topic ;) In fear of bugs I'd like to source the problem and use the swipe event in smartScroll;

But I get the following error going with your approach in post 2 of this issue

TypeError: undefined is not an object (evaluating 'g.position().top')
d4nyll commented 7 years ago

Regarding very subtle swipes, you can change the sensitivity variable in the code to something lower.

You can also play around with the stability, sensitivity, tolerance, delay variables. If you find one that works well for you, please do comment it here so others can benefit.

d4nyll commented 7 years ago

Did you set the sectionWrapperSelector option correctly? Or are you using the .section-wrapper class for your sections?

katerlouis commented 7 years ago

So far I'm not setting it at all; I don't want smartscroll to handle the sections and animations etc. for me– is there a way to only use the events?

d4nyll commented 7 years ago

If you just want to use the events, then you should only use Lethargy. Instead of just console.log the result as is done here https://github.com/d4nyll/lethargy/blob/master/index.html#L60, just your own functions (possibly throttling / debouncing them as well)