Blitz.js + React Three Fiber ==> React Three Blitz?
In order to celebrate the recent Blitz.js promotion to formal Beta,
we thought it might be fun to see how it integrates with one of our favorite frameworks, React Three Fiber. Introducing react-three-blitz!
What is Blitz.js?
If you haven't seen it yet, you owe it to yourself to checkout one of Brandon Bayer's (the founder and chief evangelist of Blitz.js) very thorough video introductions.
We are intrigued by blitz.js because it offers a compelling, uniquely integrated (Rails-like?) monolithic, full stack solution built using top tier open source components (React, Next.js, Prisma ORM, React Query, Passport.js Auth Strategies,etc.).
What is react-three-fiber?
To put it simply, r3f
a React renderer for THREE.js for the web and react-native. THREE.js has been a gamechanger but we really feel that @0xca0a/@drcmda et al's react-three-fiber [and the Drei utilites!] takes it to the next level by wrapping THREE.js primitives, etc. to keep all of our 3D web dev concise and performant.
A lot of credit for this integration idea goes to @onireanud et al and his @pmndrs umbrella creation react-three-next. This excellent project introduces a compelling pattern, especially for integrating r3f and next.js.
Specifically, react-three-next
uses a unified layout model containing a THREE.js/r3f canvas and a react DOM container overlaid on top of each other. A rendering filter is used to seperate HTML and r3f components and render them in the appropriate container.
Below is a quick rundown of changes we added/changed to get our 3D adventure started:
Fix/Circumvent SSR using next-transpile-modules
Three.js, Drei etc. don't play well with SSR so we needed a way to pre-transpile these libraries.
Reusable Canvas
Our goal here was to leverage a "reusable" Canvas ala react-three-next. All "3D" elements (hero, logo, etc. in our case) would render as children of this element. We also included some configurable niceties like r3f-perf, OrbitControls.
DOM/HTML Component Container
Also similarly to react-three-next we used a wrapper for all non 3D or plain "dom" elements.
SplitApp
Then, we use this component either aggregate the 3D and non-3D components, if 3D components are present. Or, just output a standard non-canvas component wrapper.k
Layout
As described earlier, this component is used to create separate arrays of r3f and HTML based on the presence of a "key". Using these arrays we determine whether or not to display the Canvas.
Index
Finally, we import our 3D component and disable SSR. Then, we use the Layout component from above and mark each 3D with a key (i.e. 'r3f', etc.) to let the render know we will be presenting a r3f component.
The react-three-blitz starter is definitely a work-in-progress. In fact, we don't have all the coolness ported yet from react-three-next (i.e. transitions, webpack customization, etc.). Also, there in-progress r3f issue preventing us from sharing a canvas across routes to optimize navigation responsiveness.
Allow opting out of forceContextLoss() #1004
I'm working on a page where I would like to reuse/manage webgl contexts outside of the specific components that use Canvas. would it be possible to add a way to opt out of Canvas calling forceContextLoss()
on unmount?
Nevertheless, we encourage you to give react-three-blitz a spin!
-c0d3t3k
c0d3t3k / react-three-blitz
React Three Fiber experimental starter template powered by Blitz.js
react-three-blitz
Blitz.js experiment/starter influenced heavily by @onireanud et al react-three-next
Getting Started
Run your app in the development mode.
yarn
yarn dev
Open http://localhost:3000 with your browser to see the result.
Interesting Changes
List of delta's from the base Blitz.js generated app
react-three-blitz
├── app/
│ ├── core/
| │ └── components/
│ │ | └── DarkMode.tsx
│ │ | └── Logo.tsx
│ │ └── layouts/
│ │ └── _canvas.tsx
│ │ └── _dom.tsx
│ │ └── Layout.tsx
│ ├── pages/
│ │ ├── _app.tsx
│ │ └── index.tsx
│ │ └── hero.tsx
│ ├── api/
│ ├── auth/
│ ├── pages/
│ ├── login3d.tsx
│ └── signup3d.tsx
├── blitz.config.js
├── tsconfig.json
#shouldersofgiants shoutouts:
Top comments (0)