Closed ahmetsali closed 11 months ago
Update: I tried to achieve this with this code, it works but it has really poor performance, not usable.
const html = document.documentElement;
// typically for <body> and <html>
function isOverflowHidden(el) {
var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y');
return (overflow === 'hidden');
}
lenis.on('scroll', ({ scroll, limit, velocity, direction, progress }) => {
if (isOverflowHidden(html)) {
lenis.stop();
} else {
lenis.start();
}
})
Hi, i agree that's would be ideal, however there is currently no performant way to do this.
Two notes here,
overflow: clip
as well@ahmetsali @SiddharthSham, i gave it a shot, you can test with version 1.0.18-0. It works better than i initially thought, it just doens't trigger if you check/uncheck overflow property from devtool. I'm gonna wait for some feedbacks before include it in the codebase because getComputedStyle can be hazadous sometimes.
https://github.com/studio-freight/lenis/tree/observe-overflow
One note regarding perf, getComputedStyle
does not need to be triggered on each call to check()
since the value returned by getComputedStyle
is a reference to a live object which will automatically update.
While I was curious to see how this would work, I'm not sure if this will always be the best approach. I understand using overflow: hidden
does not work perfectly across different platforms and also causes a layout shift by showing/hiding the scrollbar.
For this reason, I generally use the position: fixed
hack which is a bit more work but works better imo. Some reference work here, by body-scroll-lock package.
Perhaps this could be a plugin/extension which doesn't add weight to the core lenis lib? That way we can choose to include this behaviour only if required. 🤔
1.0.18-1 should be more robust
I am facing a similar problem. When using an modal I expect a scroll lock for the page but even manually setting the overflow for
to hidden does not stop lenis-scrolling (tried with latest version and with 1.0.18-1). Is there any progress on this to be expected because for this is a crucial criteria.This is not planned to be part of Lenis for performance reason, you have to call lenis.stop()
manually.
You can still implement it by yourself using this snippet.
const lenis = new Lenis()
function raf(time) {
const isModalOpened = // check if you modal is here
if(isModalOpened) {
lenis.stop()
} else {
lenis.start()
}
lenis.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
Hi @clementroche , i am facing the same issue for modals. Here is the code I am using.
The issue is even if the isScrollAllowed
becomes false I cannot scroll through the modal. However, I can do that if I remove the lenis code entirely.
https://github.com/studio-freight/lenis/assets/72851613/5c216381-1d4c-4bb1-9019-c523f69dc166
I have Home.jsx
where all the components are there . . . .
import React, { useRef } from "react";
import Lenis from "@studio-freight/lenis";
import { useEffect } from "react";
import Work from "../components/work/Work";
import { useScrollUtils } from "../Store";
const Home = () => {
const { isScrollAllowed, setIsScrollAllowed } = useScrollUtils();
useEffect(() => {
console.log(isScrollAllowed); // I get "false" as an answer correctly, when I change the value
const lenis = new Lenis({
duration: 3,
});
function raf(time) {
if (isScrollAllowed) lenis.start();
else lenis.stop();
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
}, [isScrollAllowed]);
return (
<div style={{ position: "relative" }}>
<Work />
</div>
);
};
export default Home;
Inside the WorkCard.jsx
component I have the card, where I am able to Open a modal. I have omitted extra jsx code to save your time.
import React, { useRef } from "react";
import { motion, useInView } from "framer-motion";
import { useScrollUtils } from "../../Store";
const WorkCard = ({ isWorkModalOpen, setWorkModalOpen }) => {
const { isScrollAllowed, setIsScrollAllowed } = useScrollUtils();
return (
<div className="workcard_container">
<motion.div>
<button
onClick={() => {
setIsScrollAllowed(false);
setWorkModalOpen(true);
}}
>
See my work
</button>
</motion.div>
</div>
);
};
export default WorkCard;
I had the same issue and managed to fix it by using .destroy()
and re-creating the Lenis instance.
I'm in a Nuxt (Vue.js) context and .stop()
wouldn't allow the scroll inside of the modal generated by a 3rd party script on Chrome. Leaving this here in case someone faces the same issue:
onMounted(() => {
lenis.value = new Lenis({})
function raf(time:number) {
const isOverflowHidden = document.body.style.overflowY === 'hidden'
if (isOverflowHidden && lenis.value) {
lenis.value.destroy()
lenis.value = null;
}
else if (!isOverflowHidden && !lenis.value) {
lenis.value = new Lenis({})
}
lenis.value?.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
})
@esiao nice work!
Describe the bug In some cases such as lightbox plugins or modal boxes, when the modal box is visible the plugins set overflow: hidden; to html tag to prevent scrolling of the body on the background because the modal is active. Lenis.js doesn't respond to dynamically changes of overflow property.
To Reproduce Try using Lenis.js with a lightbox plugin such as this; https://dimsemenov.com/plugins/magnific-popup/
Thanks for this great plugin.