Giter VIP home page Giter VIP logo

Comments (6)

StevenStavrakis avatar StevenStavrakis commented on June 26, 2024

I've found a hacky fix. Many scroll-jacking libraries will provide a property on the smoothScroll object which gives the estimated scroll position. By adding some JS to create two divs, one a container the height and width of the view with overflow scroll, the other inside it made to be the height of the page content, and programmatically setting the containers scroll position with what the smooth scroll library provides on every frame (using requestAnimationFrame), I can then point the Rellax wrapper at that element and hide it behind everything.

There are still some issues I haven't figured out, mostly GSAP animations doing weird things, but it somewhat works.

It would be much, much easier if rellax had an option to just pass a scroll position to it instead.

from rellax.

cleuenberg avatar cleuenberg commented on June 26, 2024

Hi @StevenStavrakis , I am currently trying to "smooth" the horizontal scrolling with some libraries, but with no success. Could you please provide an example of your attempt? That would be really great! And yes, I would also like to see rellax handling this issue out-of-the-box.

from rellax.

StevenStavrakis avatar StevenStavrakis commented on June 26, 2024

@cleuenberg

I can't say I know how to work with it horizontally, but I imagine my solution can be made to work with whatever case is needed.

That being said, this was done for a full page smooth scroll. Outside that I can't guarantee it will work. I also found it doesn't play nice with gsap animations and I haven't found a solution for that yet.

For my solution I used ASScroll, Ash's Smooth Scroll Library. The ASScroll object provides a smoothScrollPos property on every frame which represents the simulated scroll position of the smooth-scroll container.

When initializing Rellax, you can give it a custom wrapper to look at and get the scroll position from. Since we are unable to feed a scroll position straight into the Rellax configuration, it occurred to me that the only way for them to work together would be to create two DOM elements, a container the size of the viewport, and a div the height of the document, and using ASScroll's requestAnimationFrame loop, manually update the new elements scroll position to match the smoothScrollPos property provided each frame. With that, you can configure Rellax to look at the newly created scrollcontainer to conduct its parallax.

The resulting code:

 import ASScroll from "https://cdn.skypack.dev/@ashthornton/[email protected]";
    
    // Initialize smooth scrolling on your desired container
    // This is your "actual" scroll container
    const smoothScroll = new ASScroll({element: '.smooth-scroll'});
    
    // Create a fake scroll container which Rellax will observe for scroll position
    const scrollTrackerContainer = document.createElement('div');
    scrollTrackerContainer.classList.add('scroll-tracker-container');
    
    // Make it fill the viewport (same as the actual scroll container)
    scrollTrackerContainer.style.width = "100vw";
    scrollTrackerContainer.style.height= "100vh";
    scrollTrackerContainer.style.position = "fixed";
    scrollTrackerContainer.style.top = "0";
    scrollTrackerContainer.style.left = "0";
    
    // Put it behind everything, make sure it can't be interacted with, and hide it
    scrollTrackerContainer.style.zIndex = "-1";
    scrollTrackerContainer.style.pointerEvents = "none";
    scrollTrackerContainer.style.visibility = "hidden";
    
    // Make sure it can scroll
    scrollTrackerContainer.style.overflowY = "scroll";
    
    // Add it to body (or wherever your actual scroll container is)
    document.body.appendChild(scrollTrackerContainer);
    
    // Create the inner element and append it to the scrollTrackerContainer
    const scrollTracker = document.createElement('div');
    scrollTracker.classList.add("scroll-tracker");
    scrollTrackerContainer.appendChild(scrollTracker);
    
    // Every frame, set the scroll position of the scrollTrackerContainer to be the value provided by
    // ASScroll
    smoothScroll.on('raf', ({ scrollPos, smoothScrollPos }) => {
        scrollTrackerContainer.scrollTop = Math.abs(smoothScrollPos);
    });
    
    // When the window loads, enable smoothScroll and set the inner scrollTracker element to the height of
    // your scroll container, in this case, the body
    window.addEventListener("load", () => {
        smoothScroll.enable()
        scrollTracker.style.height = document.body.clientHeight + "px";
    });

And now we can initialize Rellax

window.addEventListener("load", () => {
  let rellax = new Rellax('.rellax', {
    wrapper: '.scroll-tracker-container'
});  
});

Aside from the problems with gsap, which is something I need to solve or else this solution won't work for me, this seems to work great. I imagine with a bit of tinkering it could be made to work easily with any particular use case.

One last consideration:

This solution doesn't update the artificial scrollheight fractionally because, well, I don't know how to and I haven't looked into it. What this means is that there is a barely, barely noticeable jitter compared to the smooth scroll when scrolling since it's being updated as integers instead of floats.

from rellax.

licentiapoetica avatar licentiapoetica commented on June 26, 2024

I am experiencing a similar problem while using fullpage.js, it's not compatible, very sad

from rellax.

StevenStavrakis avatar StevenStavrakis commented on June 26, 2024

@ottersarecool

I've never used fullpage.js, however I think that the solution I provided above can be adapted to it. These scroll libraries usually take the native scroll and translate it into a "virtual" scroll. My method creates an invisible element for rellax to look at and re-applies the native scroll to it.

Looking at fullpage.js, I don't see a super easy way of doing it like I did in my solution, but so long as you can track the virtual scroll position it should work.

That being said, looking over the fullpage.js documentation, I cannot recommend using it. The features seem seriously limited for something that developer need to pay for.

Overall, I have begun moving away from libraries entirely and instead manually create solutions using GSAP. It has a much higher learning curve, but it allows me to come up with the best solutions on the fly. With it, you can create the smooth scrolling effect you are looking for, but also create the parallax effect from rellax, all without extra libraries. I have only been pleased by its efficacy since I started using it.

from rellax.

licentiapoetica avatar licentiapoetica commented on June 26, 2024

@ottersarecool

I've never used fullpage.js, however I think that the solution I provided above can be adapted to it. These scroll libraries usually take the native scroll and translate it into a "virtual" scroll. My method creates an invisible element for rellax to look at and re-applies the native scroll to it.

Looking at fullpage.js, I don't see a super easy way of doing it like I did in my solution, but so long as you can track the virtual scroll position it should work.

That being said, looking over the fullpage.js documentation, I cannot recommend using it. The features seem seriously limited for something that developer need to pay for.

Overall, I have begun moving away from libraries entirely and instead manually create solutions using GSAP. It has a much higher learning curve, but it allows me to come up with the best solutions on the fly. With it, you can create the smooth scrolling effect you are looking for, but also create the parallax effect from rellax, all without extra libraries. I have only been pleased by its efficacy since I started using it.

Yes I ended up doing my project without it in favor of rellax, was the better choice, but thank you for your answer!

from rellax.

Related Issues (20)

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.