alvarotrigo / fullPage.js

fullPage plugin by Alvaro Trigo. Create full screen pages fast and simple
http://alvarotrigo.com/fullPage/
GNU General Public License v3.0
35.28k stars 7.29k forks source link

Delay when reach bottom of slimScroll slide #286

Closed stevenacres closed 10 years ago

stevenacres commented 10 years ago

Hello! Your plugin is fantastic, thus its popularity. Thanks for taking the time to develop it and work with other developers in their implementation!

I've tried toying with it, but I can't seem to get it to work. When on a slide that has slimScroll enabled and the user scrolls to the bottom, the second the scrollbar reaches the bottom it goes to the next slide. Is there a way to delay the input from the mouse, much like how it works with each section? Or, in my case, I'm trying to have it, once reach the bottom of the slimScroll, to trigger the next slide to load.

My staging page can be seen here: http://stevenacr.es/v10/#design/1

For instance, when you get to the bottom of "1", it will move to the right to "2."

alvarotrigo commented 10 years ago

Thanks I'm glad you find it useful.

Answering your question. no, I'm afraid there's no way to do it by using any of the plugin options. Scrolling vertically will always scroll the site vertically.

alvarotrigo commented 10 years ago

About your "delay" or "resistance", there was an old topic about it here in which we concluded that it was quite difficult to accomplish cross platform.

stevenacres commented 10 years ago

What I had tried doing was setting a timeout on the action to the next slide, when it registers that it has hit the bottom. Is there no way to accomplish this? Thanks for the quick reply.

Secondly, the slides are linked to as "1", "2", etc. Is there a way to set those to custom ID's and link to them, as with on the first slide is with the grid of images? I tried using data-index to point to each project's ID but that never seemed to work.

alvarotrigo commented 10 years ago

@stevenacres adding a timeout wouldn't solve the problem as the site will keep scrolling anyway. It is just a way to delay the action, which might even result weird for the user.

About your second point, you have more info in the documentation: https://github.com/alvarotrigo/fullPage.js#using-anchor-links

stevenacres commented 10 years ago

I mean more of a timeout before it starts registering scroll events, before it removes the tracking from the slimScroll.

I see in the documentation it references the menu function. For my site, there's already a menu, then on the second slide ("design") there is a grid. Would I have to create a separate menu indexing function, or could I just use data-anchor="firstproject", but then what would the HTML for the actual link be? I tried using a few different things, such as data-anchor and data-index on the li, but that didn't do anything.

I've updated the staging, the first two images on the grid #design use toSlide with data-anchor="project1" and project2 respectively, but neither does anything.

alvarotrigo commented 10 years ago

I don' t think adding a timeout would do it. You can try it if you want or suggest a pull request if you make it work. With a laptop trackpad you could easily be creating around 50 timeouts which might conflict between each others. I might give it a try another day if I have time.

About your second question, quoting the documentation for the "menu" option:

This won't generate a menu but will just add the active class to the element in the given menu with the corresponding anchor links.

You need to add the option "menu" in your initialization with your menu element. Then fullpage will add the class active where it corresponds according to the data-anchor attribute.

alvarotrigo commented 10 years ago

Sorry I might have misunderstood you, I believe you are confusing slides with sections. Sections are vertical, slides horizontal.

The menu option only works for the sections. But the documentation about it talk about slides. My mistake, I will commit a change now.

stevenacres commented 10 years ago

Ah I was about to ask.

Yes, is there a way to directly link to a slide, not a section, without using the menu function, as I already have a menu in the top left. I have a grid of links on slide 1 of the second section, that link to slides 2-10, for instance. Is there a way to link to each one without using /1 /2 /3, as in give each a unique name?

alvarotrigo commented 10 years ago

About the unique name, as I said before, just read this: https://github.com/alvarotrigo/fullPage.js#using-anchor-links

Just use data-anchor and a normal <a href link with the custom anchor.

stevenacres commented 10 years ago

I'm not sure that functionality works. The documentation on that is pretty limited, so I tried a whole lot of things.

If you see here: http://stevenacr.es/v10/#design, the first (top left) item has a link when you hover, the href is project1 and it has a class of toSlide (I tried it without the class and also tried setting it to #project1. The first slide after this has data-anchor="project1", but nothing happens.

alvarotrigo commented 10 years ago

You shouldn't be using toSlide, that's another way to do it as pointed out in the documentation.

You should do it by using anchor links.

But your link should look like: http://stevenacr.es/v10/#design/project1 Not like http://stevenacr.es/v10/project1

It is just a normal link to a normal URL. Go to the URL you want to link, copy the URL and paste it in your <a href. Nothing out of normal.

stevenacres commented 10 years ago

Oh excellent, it has to be the full URL. I'd give an example of that in the documentation, it's very helpful! Thank you for working with me on this.

alvarotrigo commented 10 years ago

It doesn't have to be the full URL... just that you forgot to add the #design. It is a normal link, nothing to explain.

stevenacres commented 10 years ago

Perfect.

What I have discovered, is under the MouseWheelHandler function in the plugin, under the scrolling down section, once it reaches the bottom (if(isScrolled('bottom', scrollable)){) I have changed moveSectionDown to removeMouseWheelHandler(); activeSection.find('.controlArrow.next:visible').trigger('click'); setTimeout(function() {addMouseWheelHandler();}, 1000); thus when it reaches the bottom, it arrests mouse movement, goes to the next section, and then resumes scrolling.

I'm not sure how efficient it really is, though. I might just have jQuerry append a "continue to next slide" button at the end of every slide...

alvarotrigo commented 10 years ago

You might also want to do it when there's no scrollbar in case of using big screens. But then you have to decide when or how are you going to scroll up o down to another section.

stevenacres commented 10 years ago

I have solved the delay problem, good sir!

You have to set var threshold = 0 at the beginning of function MouseWheelHandler, then every time you scroll up (at the top) or down (at the bottom) the below script adds to the threshold. Once the threshold has been met, it will continue the normal function of the script. Just have to work this into touch-screens. You can read more about my inspiration here: http://www.hugeinc.com/ideas/perspective/scroll-jacking-on-hugeinc

Also, note that when it's at the bottom of scroll, e.wheelDelta should be < 0.

else {
    if(scrollable.length > 0){
        //is the scrollbar at the start of the scroll?
        if(isScrolled('top', scrollable)){
            threshold++;
            if (threshold >= 4) {
                $.fn.fullpage.moveSectionUp();
                threshold = 0; //reset threshold
            }
            return false;
        }else{
            threshold=0; //reset threshold
            return true; //normal scroll
        }
    }else{
    $.fn.fullpage.moveSectionUp();
    }
}
`
alvarotrigo commented 10 years ago

That won't solve the problem for laptop trackpads or Apple devices such as the magic mouse or any Apple laptop.

That's a similar solution to what I proposed here.

stevenacres commented 10 years ago

Ah yes I figured this out last night when testing with a laptop. Too bad. At least it will work for a few cases, and doesn't change anything for laptop users.

stevenacres commented 10 years ago

So here's where I'm working on that, with someone else's recommendation on stackoverflow. I don't have a trackpad at the moment but I'll test it later.

        var threshold = 0;
        var timeStamp = new Date().getTime();
        function MouseWheelHandler(e) {
        var timeNow = new Date().getTime();
            if(options.autoScrolling){
                // cross-browser wheel delta
                e = window.event || e;
                var delta = Math.max(-1, Math.min(1,
                        (e.wheelDelta || -e.detail)));
                var scrollable;
                var activeSection = $('.section.active');

                if (!isMoving) { //if theres any #

                    //if there are landscape slides, we check if the scrolling bar is in the current one or not
                    if(activeSection.find('.slides').length){
                        scrollable= activeSection.find('.slide.active').find('.scrollable');
                    }else{
                        scrollable = activeSection.find('.scrollable');
                    }
                    //scrolling down?
                    if (delta < 0) {
                        if(scrollable.length > 0 ){
                            //is the scrollbar at the end of the scroll?
                            if(isScrolled('bottom', scrollable)){
                                if (timeNow - timeStamp < 50) {
                                    timeStamp = timeNow;
                                    return;
                                } else {
                                    timeStamp = timeNow;
                                    threshold--;
                                    console.log(threshold);
                                }
                                if (threshold < -2) {
                                    $.fn.fullpage.moveSectionDown();
                                    threshold = 0;
                                }
                                return;
                            }else{
                                threshold=0;
                                return true; //normal scroll
                            }
                        }else{
                            $.fn.fullpage.moveSectionDown();
                        }
                    }

                    //scrolling up?
                    else {
                        if(scrollable.length > 0){
                            //is the scrollbar at the start of the scroll?
                            if(isScrolled('top', scrollable)){
                                if (timeNow - timeStamp < 50) {
                                    timeStamp = timeNow;
                                    return;
                                } else {
                                    timeStamp = timeNow;
                                    threshold++;
                                    console.log(threshold);
                                }
                                if (threshold > 2) {
                                    $.fn.fullpage.moveSectionUp();
                                    threshold = 0;
                                }
                                return;

                            }else{
                                threshold=0;
                                return true; //normal scroll
                            }
                        }else{
                            $.fn.fullpage.moveSectionUp();
                        }
                    }
                }

                return false;
            }
        }

So the scroll will only update threshold every 50ms. The only issue is that (from my tests with a Wacom, not a trackpad) when it reaches the bottom, it doesn't continue polling. You have to scroll once, twice, then it'll trigger moveSectionUp.

alvarotrigo commented 10 years ago

I can not see where are you defining timeNow.

stevenacres commented 10 years ago

Ah sorry, edited above.

alvarotrigo commented 10 years ago

The only issue is that (from my tests with a Wacom, not a trackpad) when it reaches the bottom, it doesn't continue polling. You have to scroll once, twice, then it'll trigger moveSectionUp.

That's what it is suppose to do. Isn't it? Making you to scroll twice before detecting the scrolling.

stevenacres commented 10 years ago

I think so, I need to test how it is on a trackpad first to see if it works correctly. I was hoping if you continued scrolling down (pulling up with the pen on a wacom) it would continue updating threshold until it reached the point, instead of having to swipe a few times. But that is less of a concern, than the user reaching the bottom and unexpectedly going to the next section. Glad it works now!

alvarotrigo commented 10 years ago

Maybe you just need to reduce the miliseconds to less than 50.

stevenacres commented 10 years ago

Huh. There must be a certain input time for that, if it's at 30ms it works, at 35ms it doesn't quite work. I'll have to test on a trackpad and see where that nets out.

alvarotrigo commented 10 years ago

It all depends how fast you slide down and how many times the even is fired (which is much bigger in trackpads), instead of 1-3 times, maybe 60 in one single scroll.

ghost commented 10 years ago

@stevenacres : Does the code you have posted above work without producing errors? I copied and replaced that function in the latest version 1.8, and its producing a javascript error, or is there another piece I need to add? Sorry, kinda rusty with javascript.

stevenacres commented 10 years ago

There shouldn't be any errors. I updated it with that full section from what I have now, I might have left some out for brevity.