How to display an html annotation in the center of the selected geometry in React-Three-Fiber?

I want to display an Html annotation in the center of a bounding box (or sphere) of selected geometry.
(Like this HTML annotations - CodeSandbox)
But in my case I’m loading an external file that contains multiple geometries and I don’t want to load each part separately. Is there a good way to deal with this?
If you don’t mind, it would be helpful if you could show the specific code.

Below is an example sandbox URL and code.

const mat = new THREE.MeshStandardMaterial({ color: "orange" });

const Model = (props) => {
  const objRef = useRef();
  //Load Rhino3dm object
  const object = useLoader(Rhino3dmLoader, "./rhino_logo.3dm", (loader) => {
    loader.setLibraryPath("https://cdn.jsdelivr.net/npm/rhino3dm@0.15.0-beta/");
  });

  //Init material
  useLayoutEffect(() => {
    object.traverse((o) => {
      if (o.isMesh) {
        o.material = mat;
      }
    });
  });

  return (
    <primitive
      ref={objRef}
      castShadow
      receiveShadow
      onClick={(e) => {
        e.stopPropagation();
        props.setSelected(e.object.geometry);
      }}
      onPointerMissed={(e) => {
        props.setSelected(null);
      }}
      object={object}
      {...props}
    />
  );
};

//I want to put an Html tag in the middle of the bounding box(or sphere) of the selected geometry.
function HtmlAnnotation(props) {
  if (props.selected == null) return <></>;
  //const pos = props.selected.boundingSphere.center;
  return (
    <mesh geometry={props.selected} {...props}>
      <BBAnchor anchor={[0, 0, 0]}>
        <Html distanceFactor={3} center>
          <div className="content">
            hello <br />
            world
          </div>
        </Html>
      </BBAnchor>
    </mesh>
  );
}

export default function App() {
  const [selected, setSelected] = useState(null);
  return (
    <div className="App">
      <Canvas>
        <Suspense fallback={null}>
          <Model
            selected={selected}
            setSelected={setSelected}
            scale={0.1}
            rotation={[-Math.PI / 2, 0, 0]}
          />
          <Environment preset="sunset" background />
          <HtmlAnnotation
            selected={selected}
            scale={0.1}
            rotation={[-Math.PI / 2, 0, 0]}
          />
        </Suspense>
        <OrbitControls />
      </Canvas>
    </div>
  );
}

Here is another example of annotations which you can refer to.

Example : Annotations

image

In blender, I create some empty’s, with custom properties. They can be positioned anywhere you like, and you can have as many as you want. The custom properties are converted into Drei Html when the model is loaded.


And here’s another example : House
When you press the number 3, the annotation becomes visible.

image
These annotations are dynamically created from a loaded json file.

1 Like

Thank you for your reply. The references you provided are great and exactly what I want to do!!
These examples should solve my problem. Thanks again!!