reactjsstl-format

React STL Viewer capture image


I'm using react-stl-viewer to render STL files for my website. After the file is rendered I want to capture a 2D image for use elsewhere on the website. Is there a way to achieve this using this package?

Here's the provided example code:

import React from 'react';
import ReactDOM from 'react-dom';
import {StlViewer} from "react-stl-viewer";

const url = "https://storage.googleapis.com/ucloud-v3/ccab50f18fb14c91ccca300a.stl"

const style = {
    top: 0,
    left: 0,
    width: '100vw',
    height: '100vh',
}

function App() {
    return (
        <StlViewer
            style={style}
            orbitControls
            shadows
            url={url}
        />
    );
}

ReactDOM.render(<App/>, document.getElementById('root'));

Solution

  • Found a solution! If you keep a reference to the canvas element of STLViewer, you can call toBlob() and convert the blob into an image file.

    Here's the completed code using the given example:

    import React, { useEffect, useState } from 'react';
    import { StlViewer } from 'react-stl-viewer';
    
    const url =
      'https://storage.googleapis.com/ucloud-v3/ccab50f18fb14c91ccca300a.stl';
    
    const style = {
      top: 0,
      left: 0,
      width: '100vw',
      height: '100vh',
    };
    
    function App() {
      const [viewerElement, setViewerElement] = useState(null);
    
      const captureThumbnail = () => {
        if (viewerElement) {
          const canvas = viewerElement.querySelector('canvas');
          if (canvas) {
            canvas.toBlob((blob) => {
              const file = new File([blob], "my-snapshot.jpg");
              // Do something with the image file
            });
          }
        }
      }
    
      useEffect(() => {
        if (viewerElement) {
          captureThumbnail();
        }
      }, [viewerElement]);
    
      return (
        <div>
          <div ref={setViewerElement}>
            <StlViewer style={style} orbitControls shadows url={url}/>
          </div>
        </div>
      );
    }
    
    export default App;