Comments (6)
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.
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.
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.
I am experiencing a similar problem while using fullpage.js, it's not compatible, very sad
from rellax.
@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.
@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)
- parallax effect seems to break with changing window size of page. HOT 1
- Angular, Can't bind to 'data-rellax-percentage' since it isn't a known property of 'div'
- Feature request: speed as a function HOT 1
- Blazor incompatibility? HOT 1
- When applied to an svg element gets flipped?
- Start the animation before Rellax Item enters Viewport HOT 5
- Parallax for relative positioned element HOT 2
- Custom angle
- Efficiency Problem
- Callbacks and doing things with them HOT 1
- How to make rellax positions "predictable"? HOT 1
- Horizontal scroll-axis-x data-rellax-max-x and data-rellax-min-x number is not working. HOT 1
- Problem when used on the same page as JS accordion HOT 1
- Choppiness on Chrome
- USE WITH IONIC
- es6 version?
- x
- Positioning issues with long pages
- Positioning issues with long pages, translate values differ on page by page basis
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rellax.