5

I am trying to load a font in three.js which so far is incredible hard. Hope sb can help on this matter.

I tried using javascript fonts like as suggested in the book Mastering three.js. With the version from the book that worked. I had to upgrade to the most recent version of three.js however for another reason and the fonts from the book don't work with the latest three.js version. So I tried converting the json fonts of three.js to js-fonts via https://gero3.github.io/facetype.js/ That didn't work as the website does not do anything when I press the convert button.

Then I tried to orient myself on some examples from the latest three.js version using the FontLoader. There I struggle with obtaining the font since FontLoader does not return anything. So tried to assign the font to a global variable myfont in the funciton that I pass to the FontLoader. However that function does not get called when I do the loader.load(...) but in my code only when the very last line of the snippet I put here is executed. I.e. I get errors in the code beforehand. Is there a good reason why the code only gets executed then and not when I load the font?

Cheers Tom

var loader = new THREE.FontLoader();
loader.load( 'three.js-master/examples/fonts/helvetiker_regular.typeface.json', function ( font ) {
    init( font );
} );

var myfont;

function init( font ) {
    myfont = font;
    console.log("inner value "+myfont);
}   
console.log("2nd time" +myfont);

var params = {
    material: 0,
    extrudeMaterial: 1,
    bevelEnabled: false,
    bevelThickness: 8,
    bevelSize: 4,
    font: myfont,
    weight: "normal",
    style: "normal",
    height: 0,
    size: 11,
    curveSegments: 4
};

var textGeo = new THREE.TextGeometry("3D text", params);
console.log("3rd time "+myfont);

textGeo.computeBoundingBox();
console.log("4th time "+myfont);

textGeo.computeVertexNormals();
console.log("5th time "+myfont);
var material = new THREE.MeshFaceMaterial([
    new THREE.MeshPhongMaterial({color: 0xff22cc, shading: THREE.FlatShading}), // front
    new THREE.MeshPhongMaterial({color: 0xff22cc, shading: THREE.SmoothShading}) // side
]);
console.log("6th time "+myfont);
var textMesh = new THREE.Mesh(textGeo, material);
console.log("7th time "+myfont);
textMesh.position.x = -textGeo.boundingBox.max.x / 2;
textMesh.position.y = -5;
textMesh.position.z = 30;
textMesh.name = 'text';
scene.add(textMesh);
console.log("8th time "+myfont);

camControl = new THREE.OrbitControls(camera, renderer.domElement);

var geometry = new THREE.BoxGeometry( 70, 70, 70 );

var texture =  THREE.ImageUtils.loadTexture('wallpaper.jpg');
var mainMaterial = new THREE.MeshBasicMaterial({ 
    map:texture, 
    side:THREE.DoubleSide 
}); 
console.log("9th time "+myfont);
var nonMainMaterial = new THREE.MeshBasicMaterial( { color: 0xcccccc } );

var materials = [mainMaterial, nonMainMaterial,nonMainMaterial,nonMainMaterial,nonMainMaterial,nonMainMaterial];
var meshFaceMaterial = new THREE.MeshFaceMaterial( materials );

console.log("10th time "+myfont);
var cube = new THREE.Mesh( geometry, meshFaceMaterial );
            console.log("11th time "+myfont);

scene.add( cube );
console.log("12th time "+myfont);


var cubeBSP = new ThreeBSP(cube);
console.log("13th time "+myfont);
var textBSP = new ThreeBSP(textMesh);
console.log("14th time "+myfont);
var resultBSP = cubeBSP.subtract(textMesh);

1 Answer 1

3

The FontLoader() uses the XHRLoader under the hood. My understanding is that it's an asynchronous function from looking at the code, where the callback function is executed on the "load" event. Loading takes time, so the rest of your code is executing before the font is finished loading. Move the rest of your code into the init() function and it should work.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Will try it. Is there any way to know when the font will be loaded? Otherwise it seems I have to put all my code for creating a scene e.g. merging and subtracting objects into the initialization method of a font loading which seems extremely ugly to me. Or is there a way to load it synchronously?
You can make your scene, cubes and whatever else, and then just add only your text mesh when the font is done loading. So your init() callback function would contain all of your textGeo and textMesh initialization and finally end with scene.add( textMesh ).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.