2016-08-20 99 views
0

首先,我想弄清楚,我是一个绝对的初学者,当谈到帆布& three.js所在画布上绘制的图像,并返回作为纹理

我已经采取了现有项目并且正在尝试做一些小的修改,即将图像绘制到纹理上而不是仅写入文本。我希望纹理具有设置的背景颜色,并试图在其上绘制透明png图像。

我试图修改的方法返回一个纹理用于​​另一个函数,该函数目前正在做更多的东西,我可能无法在这里解释。

我试过几种方法,我似乎无法得到我想要的行为。

方法#1

在这种方法中,我得到的背景颜色,但我没有得到的图像显示

   var ts = calc_texture_size(size + size * 2 * margin) * 2; 
       canvas.width = canvas.height = ts; 
       context.fillStyle = back_color; 
       context.fillRect(0, 0, canvas.width, canvas.height); 
       var img = new Image(); 
       function drawIcon() { 
        context.drawImage(img,0,0); 
       } 
       img.onload = drawIcon(); 
       img.src = "img/test.png"; 

       var texture = new THREE.Texture(canvas); 
       texture.needsUpdate = true; 
       return texture; 

方法2

做一些后研究,似乎我应该使用TextureLoader,但我无法弄清楚如何在画布上绘制颜色/形状。在这种情况下,图像独立显示,没有任何背景颜色。

var imgTex = new new THREE.TextureLoader().load("img/test.png",function(t){ 
        texture.map = imgTex; 
       }); 
       texture.needsUpdate = true; 
       return texture; 

我怎样才能成功地绘制在彩色背景上的图像,并返回它作为其他功能使用纹理?

+1

[HERE](https://jsfiddle.net/2pha/e6rbt3r4/)是在画布上合并2个图像并将其应用为纹理的示例 – 2pha

回答

1

您的问题与JavaScript事件处理有很大关系,就像我昨天回答的问题:How to make a Json model auto-rotates in the scene?。你永远不可能有一个“onload”,然后期待为你返回变量 - 变量只是在执行回调之前才被定义。相反,您需要将工作推迟到回调,或者在其他地方继续轮询变量,直到定义为止。

更具体到你的问题,但:

有了办法#1,您所发送的质地回填到GPU,再呈现更多的内容,但没有更新这是后发送到GPU纹理该图像已加载。将texture.needsUpdate = true;移至您的drawIcon()可能会在此解决。未经测试的例子:

var ts = calc_texture_size(size + size * 2 * margin) * 2; 
var img = new Image(); 
var texture = new THREE.Texture(canvas); 

canvas.width = canvas.height = ts; 
context.fillStyle = back_color; 
context.fillRect(0, 0, canvas.width, canvas.height); 
img.onload = function() { 
    context.drawImage(img,0,0); 
    texture.needsUpdate = true; 
}; 
img.src = "img/test.png"; 
return texture; 

注意:您应该始终在JavaScript中的范围,让事情更清晰的开始定义var变量... drawIcon()有权访问texture变量,虽然它看起来并不喜欢,因为它似乎它从你的示例代码后它被定义,但是这不是JavaScript的是如何工作的:var变量始终是全局的,以他们在规定的范围内

随着做法#2,您需要在纹理上绘制一些额外的工作,将纹理转回到画布并将生成的画布发送到GPU。 ImageLoaderTexture文档结合提示您需要如何绘制从TextureLoader获得的图像。

两种方法结合起来,应该是这样的(也完全未经测试):

var ts = calc_texture_size(size + size * 2 * margin) * 2; 
canvas.width = canvas.height = ts; 
context.fillStyle = back_color; 
context.fillRect(0, 0, canvas.width, canvas.height); 

var textureLoader = new THREE.TextureLoader().load(
    "img/test.png", 
    function(texture) { 
     var image = texture.image; 
     context.drawImage(texture.image, 0, 0 0); 
     var texture = new THREE.Texture(canvas); 
     texture.needsUpdate = true; 
     // Now do something with texture, like assigning it 
     // to your material 
    } 
); 

注意:不要忘记使用数据的URL,如果你需要画的图像较小,则这可以作为一个“data:”URL包含在你的代码中,这样可以避免去服务器并等待它加载到事件处理程序中。例如在MDN