if you turn off strict mode, it may behave more like you are expecting…
you can also put canvasRef in your dependency array - empty dependency array really means to run when loaded, so it would just show intent.
Still due to my extremely poor knowledge of React I have another question. Here - Vitejs - Vite (forked) - StackBlitz - I created the nice button which should toggle autorotation. But inspite all my efforts to pass the correct state it only fires once and doesn’t change anything. Hope that you’ll be able to help somehow.
it’s because your useEffect will only run once and the props that you have in your onBeforeRenderObservable are stale from the closure. You would want another useEffect with the props that change as dependencies.
edit:
// you need to pass the changing props to your component first:
<ViewerComponent
orbit={orbitSpeed}
source={'https://playground.babylonjs.com/scenes/BoomBox.glb'}
/>
Add a new useEffect or something your component to pick up those changes:
the problem with your observable was not react related - except you’d need to know that the props come in as a new object every time (not re-used like a useRef<>).
// you were effectively doing this - maybe that makes the stale closure clearer.
// this props object is not re-used by React.
const props = { orbit: true };
object.onBeforeRenderObservable.add(() => console.log(props.orbit))
// props object falls out of scope here and is never re-used
Regarding createViewerForCanvas, this was exactly the motivation for this layer. If we want additional viewer integrations with browser based frameworks (React being the prime example), createViewerForCanvas contains the common things needed. The React component would mostly be about providing a React-centric API and React-based UI layer (for things like the animation controls, etc.).
Note that Web Components Custom Elements do work directly in React directly as well. See React DOM Components – React. As of React 18, if you are using TypeScript you do need some manual type declarations. Here is an example:
Even with this, there is still a downside in that you have the limitations of html elements, like attributes (translated to react properties) needing to be strings only. This can be unnatural in React, especially for common React cases like being able to pass a callback to a property.
@ryantrem: Do we have it on the backlog to update the docs + CDN to have an example of createViewerForCanvas()? Would you accept a PR (@labris example)? It feels like this may go over the heads of newcomers on how well Viewer V2 can be utilised, with access to the Viewer ref. The layering is nicely done.
I have noticed a 3.1mb reduction from using Viewer V2 vs creating a minimal scene via babylonjs: import * as BABYLON from "babylonjs" import { Viewer, createViewerForCanvas } from '@babylonjs/viewer' - 3.1mb
I haven’t documented the lower layers (Viewer and createViewerForCanvas) since they are still marked as @experimental (the HTML3DElement layer is not marked as @experimental). It’s becoming increasingly unlikely that we will make significant changes to the lower layers, so the risk of wasted work documenting them is also going down.
There is already a doc page that briefly discusses using HTML3DElement in React and adding the type declarations here: Babylon.js docs
We could update that doc page to simply point to this thread as well for now. If we want to put an actual example of creating your own React component using createViewerForCanvas, we potentially could do that as well, although I would also want to add:
Probably a general doc page about the lower level Viewer and createViewerForCanvas layers).
Ideally add support to the Babylon docs website for embedding StackBlitz samples (assuming codepen.io doesn’t have React support that I just haven’t found).
Cool! Just to make sure I’m understanding, you are saying that if you create and render a minimal scene based on the Babylon UMD package (e.g. import * as BABYLON from "babylonjs" + code using the BJS API) your bundle is 3.1mb larger than if you just use the new Babylon Viewer directly, correct? For the Viewer, we did a fair bit of work to make sure it only pulls in what is needed when it is needed, whereas the Babylon UMD package has pretty much every part of Babylon, so that sounds about right.
These TypeScript declarations are helpful thank you.
Noted! I will happily try to help where I can find time.
Correct! I even included the UFO and env in the Viewer build but not the other so probably a better reduction. T’was minified, no source-maps. React.