FontLoader is not a constructor in ThreeJs? [duplicate] - three.js

I am trying to add a 3D text over the BoxGeometry sides for front, right, left and top.
I implmented this code as below :
loadFont = () =>{
const loader = new THREE.FontLoader();
loader.load( 'https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function ( response ) {
console.log("response "+response);
return response;
} );}
createText = () => {
let font = this.loadFont();
this.textGeo = new THREE.TextGeometry( "Hello", {
font: font,
size: 70,
height: 20,
curveSegments: 4,
bevelThickness: 2,
bevelSize: 1.5,
bevelEnabled: true
});
const materials = [
new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } ), // front
new THREE.MeshPhongMaterial( { color: 0xffffff } ) // side
];
this.textMesh1 = new THREE.Mesh(this.textGeo, materials );
this.textMesh1.position.y = 80;
this.textMesh1.position.z = 0;
this.textMesh1.rotation.x = 0;
this.textMesh1.rotation.y = Math.PI * 2;
this.scene.add(this.textMesh1);
this.root.add(this.textMesh1);
I am not able to receive a 3D text in my scene?
Getting Error - "THREE.TextGeometry: font parameter is not an instance of THREE.Font."
When I try using
const loader = new FontLoader();
this.textGeo = new TextGeometry( "Hello", {
font: font,
size: 70,
height: 20,
curveSegments: 4,
bevelThickness: 2,
bevelSize: 1.5,
bevelEnabled: true
});
I don't get exact place from where I am required to import these FontLoader and TextGeometry classes.
Any help, guidance or reference would be helpful. Thanks

TextGeometry and FontLoader have been moved out of the core some time ago so you have to import them from three/examples/jsm/geometries/TextGeometry.js and three/examples/jsm/loaders/FontLoader.js.
Next, the following line of code does not work since loadFont() actually works asynchronous:
let font = this.loadFont();
loadFont() will always return undefined since you return the font in the onLoad() callback function of FontLoader.load(). You have to rewrite your listing to account for the asynchronous nature of the code flow.

Related

How to create a Points (Mesh) of TextGeometry?

I am creating a TextGeometry but not able to convert in Points like a sphere or like a detailed 3d object.
In the below image I have created a sphere using
var dotGeometry = new THREE.SphereBufferGeometry(2, 100, 100);
var dotMaterial = new THREE.PointsMaterial({ size: 1, sizeAttenuation: false });
var dot = new THREE.Points(dotGeometry, dotMaterial);//new THREE.MeshBasicMaterial()
scene.add(dot);
and the for text I use
const fontloader = new THREE.FontLoader();
fontloader.load('./models/font.json', function (font) {
const textgeometry = new THREE.TextGeometry('Hello', {
font: font,
size: 1,
height: 0.5,
curveSegments: 12,
bevelEnabled: false,
bevelThickness: 10,
bevelSize: 8,
bevelOffset: 0,
bevelSegments: 5
});
var dotMaterial = new THREE.PointsMaterial({ size: 1, sizeAttenuation: false });
let textmesh = new THREE.Points(textgeometry, dotMaterial) //new THREE.MeshBasicMaterial({
// color: 0xffffff,
// wireframe: true
// }));
textmesh.geometry.center();
scene.add(textmesh);
// textmesh.position.set(0, 2, 0)
});
So how to create a geometry having many points for text also, Why I am not able to use MeshBasicMaterial for Points in sphere?
What you see is actually the expected result. TextGeometry produces a geometry intended for meshes. If you use the same data for a point cloud, the result is probably not as expected since you just render each vertex as a point.
When doing this with TextGeometry, you will only see points at the front and back side of the text since points in between are not necessary for a mesh.
Consider to author the geometry in a tool like Blender instead and import it via GLTFLoader.

Threejs issue with CSG substract rendering

I try to substract text geometry from an mesh which has been previously omported (GLB with GLTFLoader).
Unfortunatly object seems not intersect rather than when I add the text geometry in my scene for debugging I see it properly and my mesh should have removed part.
See photo below:
Image 1
But I got this result:
Image 2
I tried to lower up the size of my font, and with x100 ratio I got the result below (here the mesh has removed part but I do not know what is refering to):
Image 3
The code:
let font
function engraving() {
const loaderFont = new FontLoader()
loaderFont.load('fonts/helvetiker_regular.typeface.json', function (f) {
font = f
regenerateGeometry()
})
}
function regenerateGeometry() {
let newGeometry
newGeometry = new TextGeometry("AAAAAAAAA", {
font: font,
size: 0.003,
height: 0.003,
curveSegments: 2,
})
newGeometry.center()
//bender.bend(newGeometry, 'y', Math.PI / 16)
newGeometry.translate(0, 0, 0)
const material = new THREE.MeshStandardMaterial({
envMap: '',
metalness: 1.0,
roughness: 0.0,
color: 0xffd700,
})
const textCSG = CSG.fromGeometry(newGeometry)
var engraved = engravedCSG.subtract(textCSG)
engravedMesh.geometry.dispose()
engravedMesh.geometry = CSG.toMesh(
engraved,
new THREE.Matrix4()
).geometry
}
Looking forward for some advise

Call a function on clicking text loaded with 'new THREE.FontLoader'

I have 3D text that is created by new THREE.FontLoader():
const loader1 = new THREE.FontLoader();
loader1.load(
// resource URL
'./fonts/helvetiker_regular.typeface.json',
// onLoad callback
(font) => {
const textGeometry1 = new THREE.TextBufferGeometry(
"A",
{
font: font,
size: 0.6,
height: 0.1,
curveSegments: 20,
bevelEnabled: true,
bevelThickness: 0.015,
bevelSize: 0.02,
bevelOffset: 0,
bevelSegments: 50
}
)
const textMaterial1 = new THREE.MeshBasicMaterial({ color: 'black' })
const text1 = new THREE.Mesh(textGeometry1, textMaterial1)
text1.position.set(15.2, 0.2, 6.7)
text1.rotation.set(0, 0.8, 0)
scene.add(text1);
}
);
How can I call function once this text is clicked? I tried to work with mesh but seems like it does not work or I am doing something incorrectly?

Global Array undefined with FontLoader Function

Im pretty new, hope someone can help with this trivial question :)
The array is globaly defined var textMeshes = []; and a function to generate the text at a certain position The function works but i cannot access the array by index, I get a console error that textMeshes is not defined. But if i log textMeshes console.log(textMeshes) as hole array i see the array is filled. console.log(textMeshes[0]) results in undefined. I guess the issue is because fontLoader loads asyncron but please correct me if im wrong =). I really appreciate your help!
function addTextToScene (posX, posY, posZ, i){
var fontLoader = new THREE.FontLoader();
fontLoader.load( 'fonts/droid/droid_sans_regular.typeface.json', function ( font ) {
var textGeometry = new THREE.TextGeometry( '#' + i, {
font: font,
size: 16,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 1,
bevelSize: 0,
bevelSegments: 5
} );
textMesh = new THREE.Mesh( textGeometry, textMaterial );
var textMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000, specular: 0xffffff, shininess: 100, emissive: 0xffffff});
textMesh.position.x = posX;
textMesh.position.y = posY+50;
textMesh.position.z = posZ-50;
textMeshes.push( textMesh );
scene.add( textMesh );
} );
}
You are correct: the FontLoader.load() callback is asynchronous, so textMeshes going to be empty until after its content is loaded. Only then will this line take place:
textMeshes.push( textMesh );
before that, textMeshes[0] is going to be undefined because texMeshes has nothing inside it; it has a length of 0.
This is not much of a Three.js question, but more of an AJAX question. You should read this discussion to get more acquainted with the topic: How do I return the response from an asynchronous call?

Cannot get object to change position using tween

Apologies for asking this, but I am losing my mind.
In the context of a three.js scene I have built a cube with the following bit of code.
var gcap = new THREE.BoxGeometry( 10, 10, 1, 2, 2, 2 );
mcap = new THREE.MeshBasicMaterial( { color: 0x3182bd, wireframe: false, transparent: true, opacity: 0.5} );
cap = new THREE.Mesh( gcap, mcap );
cap.position.set( - 12, 19, 0 );
gcap.center();
cap.rotation.z = (28 * Math.PI)/180; //convert to radians
app.scene.add(cap);
So why does this tween not work (and by not working I mean there is not noticeable change in the scene):
new TWEEN.Tween(cap.position)
.to(-12, 19, 100 ).start();
but this one does:
new TWEEN.Tween(app.controls.target).to({
x: 31/2,
y: 29/2,
z: 11/2
}).start();
I realize this is probably a super-dumb question, but I'm new to tween (and really three.js in general).
In .to() you have to pass an object of the same structure that you pass in .Tween(), fully or partially. It depends on what values of the object you want to change.
And the second paremeter in .to() is duration.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var box1 = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
}));
box1.position.set(-3, 0, 0);
scene.add(box1);
var box2 = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial({
color: "blue",
wireframe: true
}));
box2.position.set(3, 0, 0);
scene.add(box2);
var tween1 = new TWEEN.Tween(box1.position) // here you pass the position {x, y, z}
.to({ // here you pass an object with properties you want to change (now you want to change all of them)
x: 1,
y: 3,
z: -2
}, 2000).delay(500).repeat(Infinity).yoyo(true).start();
var tween2 = new TWEEN.Tween(box2.position) // the same, position {x, y, z}
.to({ // but you want to change only y-coordinate, so you pass an object of {y}
y: 3
}, 1000).delay(500).repeat(Infinity).yoyo(true).start();
render();
function render() {
requestAnimationFrame(render);
TWEEN.update();
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>

Resources