3D text and earcut

I’m trying to add 3D text to a project with JavaScript and React.

When I try to import earcut

import earcut from “earcut”;

it shows up in this path: AppData/Local/Microsoft/TypeScript/5.4/node_modules/@types/earcut/index"

it doesn’t pick up the path of the node modules of my project.

And when I try to create text I get:

earcut is not defined
at Object.CreateText (textBuilder.ts:277:23)
at createTextWithFont (InmersiveMap.jsx:81:44)

If I install @types/earcut, it does pick up the path of the node modules from my project. but the error is the same.

If I delete @types/earcut and earcut from the folder outside of my project, I still get the same error.

earcut is not defined
at Object.CreateText (textBuilder.ts:277:23)
at createTextWithFont (InmersiveMap.jsx:81:44)

what should I do?

import earcut from “earcut”

const createTextWithFont = async () => {
try {
const fontResponse = await fetch(“./fonts/kenney.json”);
if (!fontResponse.ok) {
throw new Error(“Error al cargar el archivo JSON”);
}
const fontData = await fontResponse.json();
console.log(fontData);

      const text = BABYLON.MeshBuilder.CreateText(
        "myText",
        "randomDescription",
        {
          fontData: fontData,
          size: 104,
          resolution: 256,
          depth: 5,
        },
        scene,
        earcut
      );
    } catch (error) {
      console.error(error);
    }
  };

  createTextWithFont();

"earcut": "^2.2.4",
"@types/earcut": "^2.1.4",

cc @RaananW

1 Like

For me the following worked:

import * as earcut from 'earcut';
(window as any).earcut = earcut;

and I use it like this:

const polygonBuilder = new PolygonMeshBuilder(${prefix}Polygon_${point.Id}, vectors, scene, (window as any).earcut.default);

I do not use the types though… but just installed normally with

npm install earcut

in the source directory of your project. It looks you install it globally?

2 Likes

This is the right way to go!

Typings are not needed, as you are not using earcut directly. However, if typescript complains, installing the types is the best solution.
Don’t install earcut as a global dependency (as it seems in your setup), just add it to your project.
If you want to share your project (on github or privately in a zip file), I will be able to debug what causes the issue on your side.

1 Like

Thank you, guys!

This is working nice:

import { useState, useEffect } from “react”;
import * as BABYLON from “@babylonjs/core”;
import earcut from “earcut”;

import { Inspector } from “@babylonjs/inspector”;
const InmersiveMap = () => {
useEffect(() => {
const canvas = document.getElementById(“renderCanvas”);
const engine = new BABYLON.Engine(canvas, true);

const createScene = async () => {
  const scene = new BABYLON.Scene(engine);
  Inspector.Show(scene, {});

  const fontData = await (await fetch("./fonts/kenney.json")).json();
  const myText = BABYLON.MeshBuilder.CreateText(
    "myText",
    "Hello World !! @ #$ % é",
    fontData,
    {
      size: 16,
      resolution: 64,
      depth: 10
    },
    scene,
    earcut
  );
  scene.clearColor = new BABYLON.Color3(255 / 255, 71 / 255, 0 / 255);

  scene.createDefaultCameraOrLight(true);
  scene.activeCamera.attachControl(canvas, true);

  engine.runRenderLoop(() => {
    scene.render();
  });

  return scene;
};

createScene().then(scene => {
  // Set the scene in state
  // This will trigger a re-render of the component
  setScene(scene);
});

// Clean up
return () => {
  engine.dispose();
};

}, );

// State to hold the scene
const [scene, setScene] = useState(null);

return (



);
};

export default InmersiveMap;

“dependencies”: {
@babylonjs/core”: “^7.5.0”,
@babylonjs/inspector”: “^7.5.0”,
“earcut”: “^2.2.4”,
“react”: “^18.2.0”,
“react-dom”: “^18.2.0”
},

With this function:

const createTextWithFont = async () => {
try {
const fontResponse = await fetch(“./fonts/kenney.json”);
if (!fontResponse.ok) {
throw new Error(“Error al cargar el archivo JSON”);
}
const fontData = await fontResponse.json();
console.log(fontData);

      const text = BABYLON.MeshBuilder.CreateText(
        "myText",
        "randomDescription",
        {
          fontData: fontData,
          size: 104,
          resolution: 256,
          depth: 5,
          
        },
        scene,
        earcut
      );
    } catch (error) {
      console.error(error);
    }
  };

  createTextWithFont();

i have this error:

App.jsx:39 TypeError: Cannot read properties of undefined (reading ‘yMax’)
at CreateTextShapePaths (textBuilder.ts:221:47)
at Object.CreateText (textBuilder.ts:280:24)
at createTextWithFont (App.jsx:25:44)

thank you so much :slight_smile:

ohhh, this:

{
fontData: fontData,

this was the problem…

3 Likes