0

Okay, so I was simply experimenting with HTML5 canvas and seeing if I could make a simple wave animation. When I made that work, I wanted to fill the width of the screen with canvases to make it seem like an ocean.

I decided that I needed to know the exact number of canvases needed to fill the width of the screen, and then some - without breaking the line. Simply enough:

var swidth = window.screen.width;
var iwidth = 100; //width of each canvas
var cwidth = Math.ceil(swidth / iwidth); //The number of canvases needed
var containWidth = iwidth * cwidth; //To keep them all in line I use a container which then overflows the page

Now I make a for loop which writes the canvases, based on cwidth. No problem.

But each of the canvases need to be cleared and reanimated each time. This is where I run into my problem. Just testing on my own screen, I figured how many canvases were needed, and wrote the appropriate number of variables (14 in my case). But what about other screens? When trying to add more variables than I needed, the function broke, because the excess variables were empty.

What I need is to somehow create exactly the correct number of variables, maybe in an array, and then call them within a function. I tried searching the intarwebz, but I couldn't find any examples of this.

The variables I need to write are

exvar0 = document.getElementById('myCanvas0').getContext('2d');

Where the number behind myCanvas must be incremented according to cwidth.

Then I need to use the variables within a function like

exvar0.clearRect(0,0,100,50);
exvar0.drawImage(img, i, 0);

But I need to write the variables the same number of times within the function as well.

I tried using variable.push(); to create an array with the correct number of variables, but I am unsure of how to use it. I hope someone can explain it to me, because it is driving me crazy to not be able to figure it out!

And of course, the solution is probably quite simple as well. Oh well, thank you to whoever takes their time to explain it to me, and sorry for my bad explanation. :'3

[Edit] Solution:

As I knew, the problem wasn't really so difficult. Thanks to T.J. Crowder I managed to think about it a bit more calmly, and of course it worked on the first try.

First calculate the number of canvases:

function waveCalc(){
var swidth = window.screen.width;
var iwidth = 100;
var cwidth = Math.ceil(swidth / iwidth); //Calculate number of canvases necessary to definitely fill the screen width, and then some.
var containWidth = iwidth * cwidth; //Calculate the width needed for the inner container to force line stability.

Make a string variable with the number of canvas elements needed:

canvas = '';
    for (i=0;i < cwidth;i++){
    canvas += '<canvas class="canvas" id="myCanvas' + i + '" width="100" height="50"></canvas>'; //Add each string with a new integer, to ensure unique IDs for all canvases.
    }

And write the string variable to the container element:

document.getElementById('candivcontainer').innerHTML = canvas; //Write out the canvases.

Use a for loop to push the correct number of variables into the cnvsVar array:

var cnvsVar = [];
var canNum;

for(canNum = 0; canNum < cwidth; canNum++){
cnvsVar.push(document.getElementById('myCanvas'+canNum).getContext('2d'));
}

Create an image object to hold the sprite used for the animation, and add a function onload to actually run the animation:

var img = new Image();
img.src = '/test/wavesprite.png';
img.onload = function() {
document.getElementById('candivcontainer').style.width = containWidth + "px";
    var i = 0;
setInterval(function(){

Here, make two new arrays in the same way as before, one for clearing the canvas, and one for redrawing it:

var y;
var clrRct = [];
var drwImg = [];

for(y = 0; y < cwidth; y++){
clrRct.push(cnvsVar[y].clearRect(0,0,100,50));
drwImg.push(cnvsVar[y].drawImage(img, i, 0));
}

    if (i > -2300){
    i -= 100;
    } else {
    i = 0;
    }
    },200);
};

And voila, it works! Simple as that. Silly me.

Aurora Vollvik
  • 175
  • 2
  • 14

1 Answers1

0

You're looking for an array. An array is a data structure used to hold a list of things; in your case, a list of canvases.

Creating an empty array:

var canvases = [];

(JavaScript is a bit unusual in that its standard "arrays" aren't really arrays at all, and you don't have to say in advance how big they're going to be. In most other languages, you would have to say how big it was going to be [how many entries it could hold].)

Adding an entry to the end of the array:

canvases.push(document.getElementById('myCanvas0').getContext('2d'));

Or you can do this:

canvases[canvases.length] = document.getElementById('myCanvas0').getContext('2d');

Now, that's getting an element that's already in the DOM, but if you don't know how many canvases you need, presumably you haven't put them in the DOM yet. So you might have a loop to create the canvases, append them to the DOM, and fill in your array, like this:

var canvases, canvas, index;
canvases = [];
for (index = 0; index < cwidth; ++index) { // You said `cwidth` was the number of canvases you needed
    canvas = document.createElement('canvas');
    document.body.appendChild(canvas); // Or wherever you need to put it
    canvases.push(canvas.getContext('2d'));
}

Using an entry from the array (in this case, the first one, at index 0):

canvases[0].clearRect(0,0,100,50);
canvases[0].drawImage(img, i, 0);

Looping through (you have lots of options for looping, this is just one of them):

var index;
for (index = 0; index < canvases.length; ++index) {
    canvases[index].clearRect(0,0,100,50);
    // ...
}
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Ah, of course. I figured I needed to use arrays, and that's what I tried before asking here. I'm just not too used with arrays, so I messed up the syntax a little. I knew the solution wouldn't be very complicated! Oh well, thanks anyway! – Aurora Vollvik Sep 20 '14 at 12:32