14islands / r3f-scroll-rig Goto Github PK
View Code? Open in Web Editor NEWA react-three-fiber scroll-rig for syncing 3D meshes and DOM elements.
License: MIT License
A react-three-fiber scroll-rig for syncing 3D meshes and DOM elements.
License: MIT License
SmoothScrollbar is always using the R3F event loop.
We should replace this with a custom rAF when imported from the scrollbar
export target.
"Should" be fixed by #13 🤞
Is it possible to use Lenis infinite scroll feature, through this library, as an alternative to R3F's <ScrollControls infinite/>
?
I tried to create my own version of your example with the GLB model (https://6l2fc3.csb.app/)
My UseCanvas is lower on the page and when it comes in view for the first time, it seems like the model and textures are loaded for the first time, causing a noticeable jank. After the first time however, I don't notice any jank anymore.
I experience the same issue with your own example. If you resize the viewport so the first watch-model is outside the viewport, you will notice the jank when it comes into view for the first time.
I have this on both Chrome & Firefox, MacBook Pro 2019.
Is there maybe a way to preload the model and textures into the GPU?
I am rendering a sphere with some texture to fill the landing page. When scrolling on ios safari the page becomes black (which is the body bgcolor) scrolling a few more times brings it back. I am thinking it is because of the resize that is happening in safari with the search bar. Anyone know how to fix this?
on Next.js 14 (App dir)
I have GlobalCanvas and smoothscrollbar in my layout.
This is how I call my sphere:
<div className="relative w-full h-screen overflow-hidden">
<>
<div
ref={el}
className={`flex w-screen h-screen overflow-hidden aspect-[16/9] z-0 `}
>
<div className="absolute size-full flex flex-col z-20">
<Banner />
</div>
</div>
<UseCanvas>
<ViewportScrollScene track={el} hideOffscreen={false}>
{(props) => (
<Icosahedron args={[1.5, 20]} {...props}>
<PerspectiveCamera
makeDefault
fov={50}
near={0.1}
far={2000}
position={[0, 0, 1]}
/>
<BackgroundSphere />
<Effects sRGBCorrection={false}>
<FXAAPass />
<ConstantNoisePass />
</Effects>
</Icosahedron>
)}
</ViewportScrollScene>
</UseCanvas>
</>
</div>
Edit: Added a codesandbox:
https://codesandbox.io/p/sandbox/hello-scrollscene-forked-tqdvwr
if you try resizing with devtools the thing flickers :/ I am relatively new to the three.js ecosystem and so I am just trying to recreate alot of things to learn. Please help point my mistakes out to me
Edit2: seems like the flickering was fixed on web (resizing with devtools doesnt make it flicker anymore) when I removed the perspective camera component and just used the orthographic={false} prop. However, issue persists on IOS when scrolling.
Hi !
Could you provide a working example with Next.js ? I can't seem to make it work.
I always get the error "e is not a function" when I wrap my frontpage in <SmoothScrollbar>
, and I have no idea why.
- error Error [TypeError]: e is not a function at file://node_modules/@14islands/r3f-scroll-rig/dist/scrollrig.modern.js:1:20176
Thank you
If a ScrollScene is outside the viewport when the page loads - the scene is never moved to it's correct location. Instead they sit as invisble meshes at 0,0,0
Since threejs still triggers raycast on invisible meshes - these ScrollScenes will trigger pointer events which can cause weird issues.
Hello, I'm in dire need of help.
I'm trying to copy codrops tutorial to familiarize myself with r3f scroll rig. I'm not used to using r3f. Using Next 14 app router.
I hope someone can help me understand better what's happening here.
I've been trying to wrap my head around the use of globalChildren with the useCanvas hook.
I've tried copying everything happening with Lens.
The expected result should be a filter covering the whole viewport, instead of a lens centered around the pointer.
I'm trying to apply post-processing to a plane texture like the Lens. I tried reusing the Text component as an exemple to render the filter on top of it.
Here's my GlobalCanvas with globalChildren inside, with my permanent Filter component wrapped around it :
<GlobalCanvas>
{(globalChildren) => (
<>
<Suspense fallback={null}>
<Filter>
{globalChildren}
</Filter>
</Suspense>
</>
)}
</GlobalCanvas>
<SmoothScrollbar config={{syncTouch: true}} />
If I use wobble on the text I can see that the WebGLText is rendered. The problem comes from the filter. Expected result would be a pixelated text. Here's my project's repo
Would be my pleasure to offer coffee. Sorry for taking your time. If anyone at 14islands or anyone familiar with r3f-scroll-rig can explain what I'm doing wrong, I'd be really really grateful.
Hi,
I wondered if it was possible to combine both scrolling 3d elements with fixed elements?
As an example, say I want a 3D logo that is fixed on top of the viewport, how would I go about doing this?
At the moment I managed to work something out with the GlobalCanvas, but I noticed I needed to factor in the scale manually for those elements. Is this the right way to go?
let xyz = new vec3( state.viewport.width * state.viewport.factor, state.viewport.height * state.viewport.factor, 0 )
<MyModel ref={el} scale={xyz} position={[state.viewport.width * state.viewport.factor * -0.2, 0, 0]} />
I've looked at the sticky example, but my requirement would be that I can set "position: fixed" on the element. That does not seem to work.
Another use case would be an animated gradient background, but with scrolling content on top. That would probably require 2 canvas elements, I'm afraid.
Curious to learn what your approach would be, but maybe this is outside of the scope of this library?
Hello,
Tried to animate the scroll to top of page (to then trigger a transition animation) with useScrollbar scrollTo, however seems to be not working correctly. Always throws errors:
Codesandbox: https://codesandbox.io/s/hello-scrollscene-forked-wo9fdr?file=/src/App.jsx
Uncaught TypeError: Cannot read properties of undefined (reading 'stop')
at Object.scrollTo (lenis.modern.mjs:167:127)
at eval (App.jsx:53:15)
Doesn't seem to be an issue on Lenis latest issue as showcased in this demo using Latest lenis and using their scrollTo:
Codesandbox: https://codesandbox.io/s/still-forest-jh6rnx
This issue is not a bug, it's a discussion of ideas.
Is it possible to make the scene track CSS animations?
Just like Drei's View, it can track CSS
Views use gl.scissor to cut the viewport into segments You tie a view to a tracking div which then controls the position and bounds of the viewport This allows you to have multiple views with a single, performing canvas These views will follow their tracking elements, scroll along, resize, etc
There are also more possibilities for integrating r3f and CSS animations.
May i know the differences of @react-three/drei ScrollControls and r3f-scroll-rig.
Seems like both able to achieve the same results?
Hey! Thanks for this amazing library, its by far the best solution to combine DOM with WebGL without headaches.
I have a question, as this is in the documentation:
Consider disabling SmoothScrollbar and all scrolling WebGL elements on mobile - it is usually laggy.
I was wondering what the issue is thats causing this, and what other options there are to mitigate this except progressive enhancement / disabling WebGL for those elements?
Perhaps it has something to do with syncing Lenis to the canvas?
Thanks in advance!
When using components directly inside the GlobalCanvas (without useCanvas hook or scrollScene), the meshPortalMaterial only display after saving the file by adding / removing another mesh.
I tried enabling all layers for the main camera, and some few things with gl but without success.
Might be the default render loop from the GlobalRenderer, but i'm a noob with Three.
Here is a repo to see it in action by comment/uncomment the sphere mesh.
'@studio-freight/lenis' has been renamed to just 'lenis',
Import trace for requested module:
./src/app/[locale]/client-layout.tsx
⨯ ./node_modules/@14islands/r3f-scroll-rig/dist/scrollrig.modern.js:1:847
Module not found: Can't resolve 'lenis'
Hi!
Currently, the useScrollbar hook exposes the scrollTo
method, but it is impossible to access other methods or the direct instance of Lenis. For example, I'd like to access start
and stop
methods. I'm able to access them by using a ref on the SmoothScrollbar
component, but ideally it would also be possible to access through a hook?
Maybe something similar to this:
const { lenis } = useScrollbar()
Let me know if that's possible? Thanks a lot for this library!
Uncaught ReferenceError: process is not defined
I've been trying to test this library but running into above error when I
any tips to move forward appreciated
requestRender
requirement for basic "demand" frameloopBy default frameloop="always"
By settings frameloop="demand"
Advanced:
Hello!
I have a question: is it possible to enable sync between tracked transformed elements and the webgl ScrollScene?
I reproduced my situation with a basic example of r3f-scroll-rig:
Here is a link for the repro: https://codesandbox.io/p/sandbox/scrollrig-and-translate-lvm5ct
Thank you so much,
L.
I think a video here will do more than a lot of words. Take a look:
First of all, let me tell you that I am using Astro, probably it's not what is expected for this library, but as Astro supports React it just works if you connect everything as it should be in a normal React application.
The problem is simple, I want to have a little interactive Island that displays a 3D model, this island sticks on scroll. The video shows that, as I scroll, it sticks just fine and it rotates with the scroll progress. The issue comes when the element goes out of view.
The first time I scroll the element until it's no longer visible, I just hide a bit over the top edge (I don't scroll much more). If I then go back up it works perfectly, as it should. However, as soon as I scroll for the second time, once the element goes out of view, I scroll until the end of the page. When I try to scroll up again, you can see that the element remains on the bottom of the sticky container and it doesn't go up like before. I am not sure why this happens so I thought of opening an issue.
I think that, for some reason, the "reflow" is not triggering, because if I resize the window (which actually triggers an automatic reflow), then the element gets repositioned and goes back to normal.
I've built a minimal reproduction from where the video was taken: https://codesandbox.io/p/devbox/r3f-scrollrig-bug-gj29np?file=%2Fsrc%2Fpages%2Fsection.astro%3A106%2C1
I am using Brave as a browser and I am on Linux.
Seems like there is a race condition with the IntersectionObserver when the ref is defined in the parent component.
For now, make sure you use the useTracker()
hook in the same component that collects the ref to be safe.
does not seem to work with what I tried when putting the global canvas in layout or a providers file that has "use client"
Seems like useThree viewport updates before the scroll-rig camera on resize, and can get out of sync.
A temporary workaround is always to recalculate the viewport when using it:
const viewport = useThree((s) => s.viewport).getCurrentViewport()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.