Reputation: 5088
The title is poorly worded but there's no way to concisely describe the problem. I'm drawing images to the 2D context of a dynamically created canvas. The data of the context is then saved to an image via toDataURL
, which is then draw on every frame. The code below is condensed, I will be drawing multiple images to the context, not just one; which is why I'm saving to an image. I will only draw part of the image at once but the image remains constant so I thought this was the best method, if there are alternatives I will happily accept those as answers.
In short: many images drawn on an image. Part of the image draw each frame. The code below works:
var picture = new Image();
picture.src = "images/tilesheet.png";
var canvas = document.getElementById("background");
var context = canvas.getContext("2d");
function generate(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = canvas.width;
ctx.canvas.height = canvas.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
ctx.drawImage(picture,0,0);
image = new Image();
image.src = ctx.canvas.toDataURL("image/png");
}
function draw(){
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, 0,0,100,100,0,0,100,100);
}
function play(){
generate();
setInterval(function(){draw();}, 0.0333);
}
window.onload = function(){
if(picture.complete)play();
else picture.onload = play;
}
<canvas id="background"></canvas>
window.Game = {};
canvas = document.getElementById("background");
var tilesheet = new Image();
tilesheet.src = "images/tilesheet.png";
(function(){
function Map(){
this.width = 2736;
this.height = 2736;
this.image = null;
}
Map.prototype.generate = function(){
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
ctx.fillStyle = "red";
ctx.rect (0, 0, 40, 40);
ctx.fill();
ctx.drawImage(tilesheet,0,0);
this.image = new Image();
this.image.setAttribute('crossOrigin', 'anonymous');
this.image.src = ctx.canvas.toDataURL("image/png");
}
Map.prototype.draw = function(context){
context.drawImage(this.image, 0,0, context.canvas.height, context.canvas.height, 0, 0, context.canvas.height, context.canvas.height);
}
Game.Map = Map;
})();
(function(){
var room = new Game.Map();
room.generate();
var draw = function(){
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
room.draw(canvas.getContext("2d"));
}
Game.play = function(){setInterval(function(){draw();}, 0.0333);}
})();
window.onload = function(){
if(tilesheet.complete)Game.play();
else tilesheet.onload = Game.play;
}
<canvas id="background"></canvas>
It seems therefore, that the problem is lying in the fact that I'm using function objects but I'm not sure. What am I doing wrong? There are no errors in the debug console.
Upvotes: 1
Views: 578
Reputation: 4094
Those two have different execution order.
First one:
image.onload
generate()
Second one:
generate()
image.onload
That's why it's not working - generate()
expects image to be loaded, however second case order doesn't guarantees it.
Instead of
...
room.generate();
...
Game.play = function(){setInterval(function(){draw();}, 0.0333);}
do this
...
Game.play = function(){
room.generate();
setInterval(function(){draw();}, 0.0333);
}
Upvotes: 1