Reputation: 620
As an introduction to canvas and the way they worked, I wanted to create a small quizz. Using only colors, I haven't any very strong problems that I can't solve by using google.
Now I want to show a background picture to the quizz but more precisely, I want that any question have a different picture as a background.
So I did this:
My main loop is a event binding on a function with click working like that:
qcm.canvas.addEventListener('click', function(evt) {
main(qcm, evt);
}, false);
Then, my main loop will use values in qcm object to know what to draw. In any case, I'll clear my canvas and then drawing back the canvas skeletton (which at the moment contain only the background picture assignement).
This is my clear canvas function, using only a clearRect.
function clearCanvas(qcm)
{
//Suppression du contenu du canvas
qcm.context.clearRect(0, 0, qcm.canvas.scrollWidth, qcm.canvas.scrollHeight);
// Rechargement du décor du canvas
initCanvas(qcm);
}
the InitCanvas function which should draw the background is this one:
function initCanvas(qcm)
{
//Background color
//qcm.context.fillStyle = QcmConfiguration.Canvas_BackColor;
//qcm.context.fillRect(0,0,qcm.canvas.scrollWidth, qcm.canvas.scrollHeight);
if (qcm.backgroundImage != undefined)
{
var background = new Image();
background.addEventListener('load', function()
{
qcm.context.drawImage(background, 0, 0, qcm.canvas.scrollWidth, qcm.canvas.scrollHeight);
}, false);
background.src = qcm.backgroundImage;
}
}
When my canvas end "init" phase, it the draw the frame I want to show, (question, answer, score ... depending on the qcm status).
For example, here is a part of the main loop function:
clearCanvas(qcm);
log(QcmLogsType.Initialisation, "Chargement du start panel");
drawStartPanel(qcm);
Where my drawStartPanel is a function which just draw a "Play" button:
function drawStartPanel(qcm)
{
// Dessin du rectangle colorée pour le bouton play
qcm.context.fillStyle = QcmConfiguration.Start_BackButtonColor;
qcm.context.fillRect((qcm.canvas.scrollWidth / 2) - 25, (qcm.canvas.scrollHeight / 2) - 25, 50, 50);
// Dessin du triangle "play"
qcm.context.fillStyle = QcmConfiguration.Start_ForeButtonColor;
qcm.context.beginPath();
qcm.context.moveTo((qcm.canvas.scrollWidth / 2) - 10, (qcm.canvas.scrollHeight / 2) - 10);
qcm.context.lineTo((qcm.canvas.scrollWidth / 2) - 10, (qcm.canvas.scrollHeight / 2) + 10);
qcm.context.lineTo((qcm.canvas.scrollWidth / 2) + 12, qcm.canvas.scrollHeight / 2);
qcm.context.closePath();
qcm.context.fill();
}
But when I execute my code, my start button seems to be "under" the picture, which mean that the picture load event seems to execute after the drawStartpanel function while the call is before...
This way I think that the main option is to put the picture as display:none in the html code and then draw it on the canvas, but I don't really like this idea, because I later want to try to do something which will go get pictures on a database, which will not allow to do something like that.
So I'm looking:
Either for a way to force the load event manually Or a way to not use the load event to show my picture
(I didn't post the entire code as it's 800 lines but will if needed :) )
Upvotes: 0
Views: 358
Reputation: 3487
Simply move your drawStartPanel function in the load
callback like this :
function initCanvas(qcm, callback) {
// Background color
// qcm.context.fillStyle = QcmConfiguration.Canvas_BackColor;
// qcm.context.fillRect(0,0,qcm.canvas.scrollWidth, qcm.canvas.scrollHeight);
if (qcm.backgroundImage !== 'undefined') {
var background = new window.Image();
background.onload = function () {
qcm.context.drawImage(background, 0, 0, qcm.canvas.scrollWidth, qcm.canvas.scrollHeight);
// Here call the start button drawing function assuming it always takes the qcm object as an argument
callback(qcm);
}
background.src = qcm.backgroundImage;
}
}
Calling it like this :
clearCanvas(qcm);
log(QcmLogsType.Initialisation, "Chargement du start panel");
initCanvas(qcm, drawStartPanel);
Going further
Another way of getting the drawings synchronously applied is to use Javascript Promises
Upvotes: 1