1

I'm trying to print text along an arc using Three.js. With help from this post, I was able to get the math for the rotation. But, as you'll see, the text is all jumbled on top of itself. How can I get it to correctly space itself out? Codepen is here.

var container, camera, scene, renderer;

function init() {
  container = document.getElementById( 'canvas' );
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 100000);
  camera.position.z = 500;
  scene.add(camera);

  var loader = new THREE.FontLoader();
      loader.load( 'https://raw.githubusercontent.com/mrdoob/three.js/master/examples/fonts/helvetiker_bold.typeface.json', function ( font ) {


  var theText = "This is some text."

  var numRadsPerChar = 2*Math.PI/theText.length;

  for (var i = 0; i < theText.length; i++){
    var char = theText[i]
   var geometry = new THREE.TextBufferGeometry( char, {
    font: font,
    size: 60,
    height: 60,
    curveSegments: 20
  });

  var materials = [
    new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
          new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
        ];

    var mesh = new THREE.Mesh( geometry, materials );
    mesh.rotation.z = (i * numRadsPerChar);
    //mesh.position.x = i * 20;
    group = new THREE.Group();
    group.add( mesh );
    scene.add( group );
    };
  } );

  renderer = new THREE.WebGLRenderer({alpha: true});
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  animate();


} init();

 function animate() {   
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
  }
westcoast_509
  • 322
  • 1
  • 4
  • 13

2 Answers2

1

Had some help figuring this out, but here's the portion that needed to be edited to work:

  mesh.rotation.z = (i * numRadsPerChar);

Needed to be:

 mesh.position.x = 100 * Math.sin(i * numRadsPerChar);
 mesh.position.y = 100 * Math.cos(i * numRadsPerChar);
 mesh.rotation.z = Math.PI/2 -(i * numRadsPerChar);

Basically, I needed to add a constant (Math.PI/2) for the rotation. For the x and y positions, I had to take the sin and cosine, respectively, to get the letters to be placed properly around the arc. Here's a working codepen.

westcoast_509
  • 322
  • 1
  • 4
  • 13
1

Another way to do this would be to draw your text on a canvas and use the canvas in a texture with texture.wrapS and .wrapT set to THREE.RepeatWrapping.. then put that texture on a material.. then make a path with the extruded path geometry and set it's material. The you can move the text by setting the texture.offset.x or y each frame in your render loop.

manthrax
  • 4,918
  • 1
  • 17
  • 16