Search code examples
reactjsthree.js3djsxreact-three-fiber

react-three/fiber creating 3D text


I'm trying to create 3d text using Threejs + react-three/fiber . I loaded the font using font loader like this :

const font = new FontLoader().parse('/Microsoft Tai Le_Regular.json');

After that I tried to use component inside the mesh , for some reason it didn't work, any other type of Geometry would work .

<mesh>
  <!--  This can't even be compiled (maybe it has to do with typescript) -->
  <textGeometry />
</mesh>

With that problem , I tried to create the textGeometry on js instead of jsx So I did this :

const textOptions = {
  font: font,
  size: props.size,
  height: props.height,
  curveSegments: 12,
  bevelEnabled: true,
  bevelThickness: 10,
  bevelSize: 8,
  bevelOffset: 0,
  bevelSegments: 5
};
  
const textGeo = new TextGeometry(props.text, textOptions);

and Passed 'textGeo' to mesh geometry prop:

<mesh geometry={textGeo}>

But it still didn't work and gave this error : can't access property "yMax", data.boundingBox is undefined

Thanks for your help,


Solution

  • So I'll preface this by saying that I'm still a student so I can't explain exactly why all these steps need to be done but here's what worked for me. It seems that your issue is with the path that you are using to parse. The file name itself seems inaccurate but even if the file path is valid, it still will not work, it must be imported. Make sure that your json file is inside of your src folder and import the json file using the relative path.

    import myFont from '../relative_path'
    

    Make sure to import extend from r3f

    import { extend } from '@react-three/fiber'
    

    Next, textGeometry does not come standard with r3f, so it needs to be imported like so

    import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
    

    Then extend TextGeometry

    extend({ TextGeometry })
    

    This should work to get the textgeometry to compile. Take a look below for the full snippet.

    import { extend } from '@react-three/fiber'
    import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
    import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
    import myFont from '../relative_path'
    
    extend({ TextGeometry })
    
    export default function Text() {
    const font = new FontLoader().parse(myFont);
    
    return(
    <mesh position={[0,10,0]}>
        <textGeometry args={['test', {font, size:5, height: 1}]}/>
        <meshLambertMaterial attach='material' color={'gold'}/>
    </mesh>
    )
    

    }

    Obviously you can change the args and material to fit your needs.