2016-02-05 118 views
1

标题措辞不佳,但无法简明地描述问题。我正在将图像绘制到动态创建的画布的2D上下文中。上下文的数据然后通过toDataURL保存到图像,然后在每一帧中绘制。下面的代码是浓缩的,我将绘制多个图像的上下文,而不仅仅是一个;这就是为什么我要保存图像。我只会一次画出部分图像,但图像保持不变,所以我认为这是最好的方法,如果有替代方案,我会乐意接受这些答案。简而言之:在图像上绘制许多图像。部分图像绘制每一帧。下面 代码工作: 函数对象无法将图像绘制到画布中的图像

var picture = new Image(); 
 
picture.src = "images/tilesheet.png"; 
 
var canvas = document.getElementById("background"); 
 
var context = canvas.getContext("2d"); 
 
function generate(){ 
 
\t var ctx = document.createElement("canvas").getContext("2d"); 
 
\t \t ctx.canvas.width = canvas.width; 
 
\t \t ctx.canvas.height = canvas.height; 
 
\t ctx.fillStyle = "red"; \t 
 
\t ctx.rect (0, 0, 40, 40); 
 
\t ctx.fill(); 
 
\t ctx.drawImage(picture,0,0); 
 
\t image = new Image(); 
 
\t image.src = ctx.canvas.toDataURL("image/png"); \t \t 
 
} 
 
function draw(){ 
 
\t context.clearRect(0, 0, canvas.width, canvas.height); 
 
\t context.drawImage(image, 0,0,100,100,0,0,100,100); \t 
 
} 
 
function play(){ 
 
    generate(); 
 
    setInterval(function(){draw();}, 0.0333); 
 
} 
 
window.onload = function(){ 
 
\t if(picture.complete)play(); 
 
\t else picture.onload = play; \t 
 
}
<canvas id="background"></canvas>
尽管如此,这并不:
window.Game = {}; 
 
canvas = document.getElementById("background"); 
 
var tilesheet = new Image(); 
 
tilesheet.src = "images/tilesheet.png"; 
 
(function(){ 
 
\t function Map(){ 
 
\t \t this.width = 2736; 
 
\t \t this.height = 2736; 
 
\t \t this.image = null; 
 
\t } 
 
\t Map.prototype.generate = function(){ 
 
\t \t var ctx = document.createElement("canvas").getContext("2d"); 
 
\t \t \t ctx.canvas.width = this.width; 
 
\t \t \t ctx.canvas.height = this.height; 
 
\t \t ctx.fillStyle = "red"; \t 
 
\t \t ctx.rect (0, 0, 40, 40); 
 
\t \t ctx.fill(); 
 
\t \t ctx.drawImage(tilesheet,0,0); 
 
\t \t this.image = new Image(); 
 
\t \t this.image.setAttribute('crossOrigin', 'anonymous'); 
 
\t \t this.image.src = ctx.canvas.toDataURL("image/png"); \t \t \t \t \t 
 
\t } 
 
\t Map.prototype.draw = function(context){ \t \t \t \t \t \t \t \t \t \t \t \t \t 
 
\t \t context.drawImage(this.image, 0,0, context.canvas.height, context.canvas.height, 0, 0, context.canvas.height, context.canvas.height); \t \t \t 
 
\t } 
 
\t Game.Map = Map; 
 
})(); 
 
(function(){ 
 
\t var room = new Game.Map(); 
 
\t room.generate(); 
 
\t var draw = function(){ 
 
\t \t canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height); \t 
 
\t \t room.draw(canvas.getContext("2d")); \t \t 
 
\t } 
 
\t Game.play = function(){setInterval(function(){draw();}, 0.0333);} 
 
})(); 
 
window.onload = function(){ 
 
\t if(tilesheet.complete)Game.play(); 
 
\t else tilesheet.onload = Game.play; \t 
 
}
<canvas id="background"></canvas>

因此它看来,这个问题是在撒谎的事实,我使用的函数对象,但我我不确定。我究竟做错了什么?调试控制台中没有错误。

回答

1

这两个有不同的执行顺序。

第一招:

  1. ...
  2. 附加image.onload
    1. 呼叫generate()
    2. ...

第二个:

  1. ...
  2. 呼叫generate()
  3. 附加image.onload
    1. ...

这就是为什么它不工作 - generate()需要加载图像,但第二种情况下的订单不能保证它。

而不是

... 
room.generate(); 
... 
Game.play = function(){setInterval(function(){draw();}, 0.0333);} 

做到这一点

... 
Game.play = function(){ 
    room.generate(); 
    setInterval(function(){draw();}, 0.0333); 
} 
+0

您的解决方案工程:)不过我很困惑,当然,如果'room.generate()为什么...;'不那么既不是'var room = new Game.Map();'?这会导致一个未定义的异常...不是? – jaunt

+1

问题是'room.generate()'被称为过早 - 图像尚未准备好,因为它没有在它使用的图像的'onload'中被调用。 –

+0

呵呵,我现在明白了,欢呼:) – jaunt