2017-08-15 2 views
1

Ich habe einen Code unter https://jsfiddle.net/72mnd2yt/1/, der das Sprite nicht anzeigt Ich versuche zu zeichnen. Ich habe versucht, den Code bei https://stemkoski.github.io/Three.js/Sprite-Text-Labels.html zu folgen und es Zeile für Zeile zu lesen, aber ich bin mir nicht sicher, wo ich falsch gelaufen bin. Würde es jemandem etwas ausmachen, sich das anzuschauen? HierSprite wird nicht angezeigt

ist einige relevante Code:

// picture 
var getPicture = function(message){ 
    var canvas = document.createElement('canvas'); 
    canvas.width = "100%"; 
    canvas.height = "100%"; 

    var context = canvas.getContext('2d'); 
    context.font = "10px"; 
    context.fillText(message, 0, 10); 
    var picture = canvas.toDataURL(); 
    // return picture; 
    return canvas; 
}; 

// let there be light and so forth... 
var getScene = function(){ 
    var scene = new THREE.Scene(); 
    var camera = new THREE.PerspectiveCamera(
    70, 
    $('body').width(), 
    $('body').height(), 
    1, 
    1000 
); 

    var light = new THREE.PointLight(0xeeeeee); 
    scene.add(camera); 
    scene.add(light); 

    var renderer = new THREE.WebGLRenderer(); 
    renderer.setClearColor(0xefefef); 
    renderer.setSize($('body').width(), $('body').height()); 

    camera.position.z = -10; 
    camera.lookAt(new THREE.Vector3(0, 0, 0)); 

    return [scene, renderer, camera]; 
}; 

// now for the meat 
var getLabel = function(message){ 
    var texture = new THREE.Texture(getPicture(message)); 
    var spriteMaterial = new THREE.SpriteMaterial(
    {map: texture } 
); 
    var sprite = new THREE.Sprite(spriteMaterial); 
    //sprite.scale.set(100, 50, 1.0); 
    return sprite 
}; 

var setup = function(){ 
    var scene; 
    var renderer; 
    var camera; 
    [scene, renderer, camera] = getScene(); 
    $('body').append(renderer.domElement); 

    var label = getLabel("Hello, World!"); 
    scene.add(label); 

    var animate = function(){ 
    requestAnimationFrame(animate); 
    renderer.render(scene, camera); 
    }; 

    animate(); 
}; 


setup(); 

Antwort

2

Einige Punkte:

1) canvas.width = "100%" sollte canvas.width = "100" (Leinwand Größen angenommen werden px sein). Gleiches mit canvas.height.

2) $('body').height() ist 0, daher ist der Renderer-Canvas nicht sichtbar (Sie können dies in den Dev-Tools überprüfen, es ist im Elementbaum, aber auf 0px high gequetscht). Ich weiß nichts über jQuery, also nicht sicher, warum das ist, aber ich würde stattdessen window.innerHeight und window.innerWidth stattdessen empfehlen. Also renderer.setSize(window.innerWidth, window.innerHeight). Sie möchten diese Änderung auch bei der Kamerainitialisierung vornehmen.

3) Wenn Sie von der Kamerainitialisierung sprechen, übergeben Sie Breite und Höhe als separate Argumente, wenn es nur ein Seitenverhältnis-Argument geben soll. See the docs. So
var camera = new THREE.PerspectiveCamera(70, window.innerWidth, window.innerHeight, 1, 1000)
wird
var camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 1000)

4) Da Texturen angenommen werden statisch zu sein, müssen Sie etwas zu diesem Teil hinzuzufügen:

var texture = new THREE.Texture(getPicture(message)) 
texture.needsUpdate = true // this signals that the texture has changed 

Das ist eine einmalige Flag, so müssen Sie um es jedes Mal zu ändern, wenn sich die Leinwand ändert, wenn Sie eine dynamische Textur möchten. Sie müssen nicht jedes Mal ein neues THREE.Texture erstellen, fügen Sie einfach texture.needsUpdate in die Renderschleife ein (oder in ein Ereignis, das nur ausgelöst wird, wenn Sie möchten, dass sich die Textur ändert, wenn Sie auf Effizienz achten). See the docs, unter .needsUpdate.


An dieser Stelle sollte es funktionieren. Hier sind einige weitere Dinge zu beachten:

5) Statt Texture verwenden Sie CanvasTexture, die .needsUpdate für Sie setzt. Die Geige, die Sie gepostet haben, verwendet Three.js r71, die es nicht hat, aber neuere Versionen tun. Das würde wie folgt aussehen:

var texture = new THREE.CanvasTexture(getPicture(message)); 
// no needsUpdate necessary 

6) Es sieht aus wie Sie auf diesem Weg waren bereits auf der Grundlage der Kommentar gesetzt return picture, aber Sie können entweder Canvas-Element oder eine Daten URL aus der Leinwand für eine Textur erzeugt verwenden . Wenn getPicture jetzt eine Daten URL zurückgibt, versuchen Sie dies:

var texture = new THREE.TextureLoader().load(getPicture(message)) 

Sie können auch indirekt eine Daten URL mit Texture verwenden:

var img = document.createElement('img') 
var img = new Image() 
img.src = getPicture(message) 
var texture = new THREE.Texture(img); 
texture.needsUpdate = true 

Wenn nicht, nur Stick mit Texture oder CanvasTexture, nehmen beide ein Leinwandelement. Texture kann indirekt eine URL übernehmen, indem ein Bildelement übergeben wird, dessen src auf die Daten-URL gesetzt ist.


Fiddle mit den skizzierten fixen: https://jsfiddle.net/jbjw/x0uL1kbh/