Google's <model-viewer> via Reagent

Google’s <model-viewer> provides all the key features I need without having to write a custom solution via something like react-three-fiber or directly in three.js.

I am struggling with how to properly integrate it into a Reagent (and React for that matter) structure. In order to make it easy to use with vanilla JS it is built as a web component and is largely controlled via the attributes on its html element. Normally that wouldn’t be much of a problem, but with the overhead of 3D and loading large models re-rendering this is expensive and in many cases functionality-breaking.

I’ve tried to naively use it inside a component and trying to eliminate the possibility of re-rendering. Using a ref to mutate it directly.

I have also tried setting it up as a separate html element from the Reagent controlled application and reference it in various events.

Both of these options introduced a lot of hacks and were not ideal in a single page application.

I am wondering if anyone has any tips on how to best wrap this in a Reagent shell, while still having access to the core element to use their underlying JS api.


Here is the example of its usage from their page:

<model-viewer 
  alt="Neil Armstrong's Spacesuit from the Smithsonian Digitization Programs Office and National Air and Space Museum" 
  src="shared-assets/models/NeilArmstrong.glb" 
  ar ar-modes="webxr scene-viewer quick-look" environment-image="shared-assets/environments/moon_1k.hdr" 
  poster="shared-assets/models/NeilArmstrong.webp" 
  seamless-poster 
  shadow-intensity="1" 
  camera-controls>
</model-viewer>

Thanks for any tips.


Additional discussion on Clojurians Slack (link requires access to Slack).

Question is also on Stack Overflow

I wonder if you could just extract the model viewer base element and create it manually inside a form 3 component in reagent. I did something similar with Vega and Cesium, but they weren’t built around web component (they expect to be passed a container element and then invoke a ctor/load method).