2017-08-15 88 views
1

我在https://jsfiddle.net/72mnd2yt/1/有一些代碼,它不顯示我想繪製的雪碧。我試圖按照https://stemkoski.github.io/Three.js/Sprite-Text-Labels.html的代碼並逐行閱讀,但我不確定我錯在哪裏。有人會介意看看它嗎?雪碧沒有顯示

下面是一些相關的代碼:

// 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(); 

回答

2

的幾點:

1)canvas.width = "100%"canvas.width = "100"(畫布大小被認爲是像素)。與canvas.height相同。

2)$('body').height()爲0,因此渲染器畫布不可見(您可以在開發工具中查看它,它在元素樹中,但壓扁到0px高)。我對jQuery一無所知,所以不確定這是爲什麼,但我會推薦使用window.innerHeightwindow.innerWidth。所以renderer.setSize(window.innerWidth, window.innerHeight)。您還需要在相機初始化中進行此更改。

3)說到相機初始化,當寬度和高度作爲單獨的參數傳遞時,應該只有寬高比參數。 See the docs。所以
var camera = new THREE.PerspectiveCamera(70, window.innerWidth, window.innerHeight, 1, 1000)
成爲
var camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 1000)

4)由於紋理被認爲是靜態的,你需要的東西添加到該部分:

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

這是一個一次性的標誌,所以你需要如果您想要動態紋理,則每次畫布更改時都要設置它。您不必每次都製作一個新的THREE.Texture,只需在渲染循環中添加texture.needsUpdate(或者如果您希望提高效率,只需在需要更改紋理時觸發)。 See the docs,在.needsUpdate之下。


在這一點上,它應該工作。這裏有一些進一步的事情要考慮:

5)而不是使用Texture你可以使用CanvasTexture,它爲你設置.needsUpdate。你發佈的小提琴是使用Three.js r71,它沒有它,但新版本。這將是這樣的:

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

6)看起來你已經根據註釋掉return picture這條道路上,但你可以使用從畫布產生任何canvas元素,或數據網址紋理。如果getPicture現在返回一個數據的網址,試試這個:

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

您也可以間接地使用數據鏈接與Texture

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

如果沒有,只是堅持TextureCanvasTexture,雙方將採取畫布元素。 Texture可以通過傳遞一個src設置爲數據url的圖像元素來間接獲取url。


撥弄修復概述: https://jsfiddle.net/jbjw/x0uL1kbh/