在画布上绘制图像并作为纹理返回

时间:2016-08-20 22:48:13

标签: three.js html5-canvas

首先,我想清楚一点,当谈到画布和画布时,我是一个绝对的初学者。 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 个答案:

答案 0 :(得分: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()可以访问{{1}变量,虽然从你的示例代码看起来不像它,因为出现在它之后定义,但这不是JavaScript的工作方式:texture变量总是全局的他们定义的范围。

使用方法#2,您需要在纹理上绘制一些额外的工作,将纹理重新转换为画布并将生成的画布发送到GPU。 ImageLoaderTexture文档结合起来提示您需要如何绘制从var获得的图像。

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

TextureLoader

注意:不要忘记使用数据URL,如果您需要绘制的图像很小,那么这可以作为“data:”URL包含在您的代码中,这样就无需转到服务器和等待它加载到事件处理程序中。 MDN上的示例。