Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
361 views
in Technique[技术] by (71.8m points)

javascript - 从画布将文本绘制为三个js作为精灵(draw text from canvas into three js as a sprite)

long story short, I'm making a live line chart and I'm using three.js due to the high number of lines per second that needs to be pushed inside this thing, so, now I'd need to draw the text values for the x and y axis, after a pretty long struggle ( because I'm a total noob @ threejs ) I figured out the wonderful technique of using the canvas as a sprite ( which is darn rad ).

(长话短说,我正在制作一个实时折线图,并且由于每秒需要插入大量线,因此我正在使用three.js,因此,现在我需要绘制文本值对于x轴和y轴,经过了很长时间的奋斗(因为我是一个总的noob @ threejs),我才想到了使用画布作为sprite(darn rad)的绝妙技术。)

This is the code that I use

(这是我使用的代码)

/// 2D REALM

var canvas = document.createElement('canvas'),
        context = canvas.getContext('2d'),
        metrics = null,
        textHeight = 100,
        textWidth = 0,
        actualFontSize = 2;

        context.fillStyle = '#FF0000';
        var size = 250;
          canvas.width = size;
          canvas.height = size;

function addText(position, text) {
  context.textAlign = 'center';
  context.font = '24px Arial';
  context.fillText("Game Over", size/2, size/2);

  var texture = new THREE.Texture(canvas);
  texture.needsUpdate = true;
  var material = new THREE.SpriteMaterial( { map: texture, color: 0x333333, fog: false } );
  var sprite = new THREE.Sprite( material );
  sprite.position.set(0,100,0);

  return sprite;
}

. . .

 $(document).ready(function() {
   h = $(window).height() - $('.speed-graph').outerHeight() - $('.speed-toolbar').outerHeight() - $('.channel-toolbar').outerHeight() - $('.status_bar').outerHeight() + 1;
      w = $(window).width() - $('.palette').outerWidth();


      camera = new THREE.PerspectiveCamera( 75, parseFloat(w) / parseFloat(h), 0.1, 5000 );


    //renderer.setSize( window.innerWidth, window.innerHeight );
      console.log("w: " + w + " | h: " + h);
      renderer.setSize(w, h);

      $('body').append( renderer.domElement );

      var material = new THREE.LineBasicMaterial({ color: 0x000000, linewidth: 1 });
      var geometry = new THREE.Geometry();

      geometry.vertices.push( new THREE.Vector3(-10 , 0, 0 ) );
      geometry.vertices.push( new THREE.Vector3(8 , 0, 0 ) );

      lines['line'].push(  new THREE.Line( geometry, material ))
      text = addText(new Array(0, 9), "lorem ipsum");
      //lines['label'].push( addText(new Array(0, 9), "0") );
      scene.add( lines['line'][0] );
      scene.add( text );


      camera.position.z = 5;
      render(); 
});

now, the lines get drawn as they should, but I had no luck at all with the text.

(现在,线条已经按需绘制,但是我对文字完全没有运气。)

I can't understand the reason why I can't see the text, because I don't get any compiler error.

(我不明白为什么看不到文本的原因,因为我没有得到任何编译器错误。)

  ask by holographix translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

in the end, I figured it out by myself, problem was that the canvas didn't had a proper size, plus a bunch of other stuff.

(最后,我自己弄清楚了,问题是画布尺寸不合适,再加上一堆其他东西。)

for the sake of the solution, and hoping to help others in the future, here's the working code along with a codepen to see it live in action.

(为了解决该问题,并希望将来能对其他人有所帮助,以下是工作代码以及一个代码笔库,以确保其付诸实践。)

  /// 2D REALM

  //var canvas = document.createElement('canvas'),
  var     canvas,
          context,
          metrics = null,
          textHeight = 10,
          textWidth = 0,
          actualFontSize = 0.12;

       canvas = document.createElement('canvas'),
       context = canvas.getContext('2d');
       context.fillStyle = '#FF0000';


  function addText(position, text) {
    // 2d duty
    metrics = context.measureText(text);
    var textWidth = metrics.width;

    canvas.width = textWidth;
    canvas.height = textHeight;
    context.font = "normal " + textHeight + "px Arial";
    context.textAlign = "center";
    context.textBaseline = "middle";
    context.fillStyle = "#ff0000";
    context.fillText(text, textWidth / 2, textHeight / 2);

    var texture = new THREE.Texture(canvas);
    texture.needsUpdate = true;
    var material = new THREE.SpriteMaterial({ map: texture, useScreenCoordinates: false });
    var sprite = new THREE.Sprite( material );

    var textObject = new THREE.Object3D();
   // var sprite = new THREE.Sprite(texture);
    textObject.textHeight = actualFontSize;
    textObject.textWidth = (textWidth / textHeight) * textObject.textHeight;
    sprite.scale.set(textWidth / textHeight * actualFontSize, actualFontSize, 1);

  //  sprite.position.set(10,10,0);

    textObject.add(sprite);
    return textObject;
  }

  var scene = new THREE.Scene();
  var camera;
  var renderer = new THREE.WebGLRenderer({
      alpha: 1,
      antialias: true,
      clearColor: 0xffffff
  });


   $(document).ready(function() {
     h = $(window).height() - $('.speed-graph').outerHeight() - $('.speed-toolbar').outerHeight() - $('.channel-toolbar').outerHeight() - $('.status_bar').outerHeight() + 1;
        w = $(window).width() - $('.palette').outerWidth();


        camera = new THREE.PerspectiveCamera( 75, parseFloat(w) / parseFloat(h), 0.1, 5000 );

        console.log("w: " + w + " | h: " + h);
        renderer.setSize(w, h);

        $('body').append( renderer.domElement );

        text = addText(new Array(0, 9), "it works!!");
        scene.add( text );
        console.log(text.position);
  //      text.position.x = 3.0;

        camera.position.z = 5;
        render(); 
  });

  // render the whole things up
  function render() {

    requestAnimationFrame(render);
    renderer.render(scene, camera);

  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...