In a project I have a larger number of texts that change dynamically.
I have solved this so far with canvas texture. For comparison I have now tried ShapeGeometry. For this I placed a line between the canvas text in my BeginnerExample - step 11 .
I find it is a better result, especially when the camera is very close or a bit further away. I want to test it in my project.
I have programmed a small test example for this purpose.
DynamicChangeableText (See next post - improvement!)
See below for code.
To change the text dynamically, I need the font in a global variable. I remembered that you can make an appropriate assignment after the loading process is finished, but I could not find an appropriate example.
While searching I saw some suggested solutions, but they seem too elaborate or complicated for my simple case.
I have found a simple solution, but I am not sure if it is performant, because an unnecessary check remains in the animate function.
Is there another very simple and more efficient solution?
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/load-font-into-global-variable-efficiency/31608 -->
<head>
<title> DynamicChangeableText </title>
<meta charset="utf-8" />
<style>
body {
margin: 0;
}
</style>
</head>
<body> </body>
<script src="../js/three.min.134.js"></script>
<script src="../js/OrbitControls.134.js"></script>
<script src="../js/FontLoader.134.js"></script>
<script>
// @author hofk
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 3 );
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xfdfde2, 1 );
document.body.appendChild( renderer.domElement );
const controls = new THREE.OrbitControls( camera, renderer.domElement );
const fontLoader = new THREE.FontLoader( );
let textsGeometry = [];
let text = [];
let ft = { type: null };
let change = false;
// https://threejs.org/examples/fonts/helvetiker_regular.typeface.json
fontLoader.load( 'helvetiker_regular.typeface.json', font => ft = font );
console.log( 'global 0', ft );
animate( );
function animate( ) {
requestAnimationFrame( animate );
if ( ft.type === 'Font' && !change ) {
console.log( 'global 1', ft);
change = true;
initText( );
}
if ( ft.type === 'Font' && change ) {
changeText( )
}
renderer.render( scene, camera );
}
function initText( ) { // 1000 text lines
for ( let i = 0; i < 1000 ; i ++ ) {
const textsShapes = ft.generateShapes( 'initial text >>> ' + i , 0.04 );
textsGeometry[ i ] = new THREE.ShapeGeometry( textsShapes );
const textsMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, side: THREE.DoubleSide } );
text[ i ] = new THREE.Mesh( textsGeometry[ i ], textsMaterial );
text[ i ].position.set( 0, -20 + i / 20 , 0 );
scene.add( text[ i ]);
}
}
function changeText( ) { // change some text lines dynamically
for ( let i = 390; i < 410; i ++ ) {
const textShp = ft.generateShapes( 'new text >>> ' + i + ' random ' + Math.random( ), 0.035 );
textsGeometry[ i ].dispose( );
text[ i ].geometry = new THREE.ShapeGeometry( textShp );
text[ i ].geometry.needsUpdate = true;
}
}
</script>
</html>