Reputation: 33
I have 2 functions, the first function draws a lined empty grid (28x16) and the second function draws a square box that fills a selected grid location with a colour, each box is 25X25. the 2nd function allows me to draw a box anywhere in the canvas using the grid location. hence, to draw a box I created another function that calls the grid locations and draw it there, for example to draw a box in the grid location where x=5 and y=4 this line must be entered drawWalls(5,4);
this line can be used again and again to draw different boxes, so I can draw the boxes and the function works perfect, now I want to create more than 1 square box at the same time (for example a line of boxes), the problem is, I have never created a loop like this or a loop that has more than 1 variable, please help, also I am getting a little confused with arrays, I want to know if these boxes are stored in an array and how can I call them again, say for example I click on a box and it gets deleted, this is not important but if you have any ideas on the first problem then please help, thank you for your time.
draw grid
function drawGrid() {
ctxBg.beginPath();
for (var i = 0; i <= canvasWidth-25; i+= 25) {
ctxBg.moveTo(-25 + i,55);
ctxBg.lineTo(-25 + i, canvasHeight - 55);
}
for (var i = 25; i <= canvasHeight -75; i+= 25) {
ctxBg.moveTo(55,25 + i);
ctxBg.lineTo(canvasWidth-55, 25 + i);
}
ctxBg.stroke();
}
function ClearBg() {
ctxBg.clearRect(0,0,canvasWidth,canvasHeight);
}
Draw the wall
function Wall(row, col) {
this.row = row;
this.col = col;
this.color = "#000";
this.width = 25
this.height = 25
this.leftX = this.row;
this.rightX = this.row + this.width;
this.topY = this.col;
this.bottomY = this.col + this.height;
}
function drawWalls(x,y) {
walls.push( new Wall(x, y));
for (var b = 0; b < walls.length; b++) {
ctxWall.fillStyle = walls[b].color;
ctxWall.fillRect(walls[b].row * gridSize, walls[b].col * gridSize, walls[b].width, walls[b].height);
}
}
function createWalls() {
drawWalls(9,9);
drawWalls(8,8);
drawWalls(7,7);
}
I am trying to make the function createWalls in a loop to draw them all together, unfortunately I still haven't created the mouse click event, but I will soon
Upvotes: 1
Views: 2122
Reputation: 18097
This was a fun thing to do: http://jsfiddle.net/techsin/rcjouqkf/
To get any 'box/cell' coordinates all you have to do is this:
represent the box you are at. then times that number with the box size. this gives you box's right edge repeat for y to get bottom edge.
to get top and left just subtract the size from edges.
var can = getById('can'),
boxes = 20,
size = 20,
ctx = can.getContext('2d'),
clearBtn = getById('clearBtn');
drawGrid();
function drawGrid() {
var len = can.height = can.width = boxes * size;
for (var i = 0; i < boxes; i++) {
ctx.beginPath();
ctx.moveTo(size + size * i - .5, 0);
ctx.lineTo(size + size * i - .5, len);
ctx.moveTo(0, size + size * i - .5);
ctx.lineTo(len, size + size * i - .5);
ctx.stroke();
}
}
can.addEventListener('mousemove', function (evt) {
var mousePos = getMousePos(can, evt);
var sx = (Math.ceil(mousePos.x/size)-1)*size,
sy = (Math.ceil(mousePos.y/size)-1)*size;
console.log(sx,sy,sx+size,sy+size);
ctx.fillRect(sx,sy,size,size);
}, false);
clearBtn.addEventListener('click', function (evt) {
ctx.clearRect(0,0,can.width,can.height);
drawGrid();
});
function getMousePos(canvas, evt) {
var rect = can.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function getById(x) {
return document.getElementById(x);
}
Upvotes: 5
Reputation: 105015
Put the definitions of your walls in javascript objects and store those wall-objects in an array. Then use the array to draw your walls as necessary.
Each wall-object holds the information required to draw one wall:
var walls=[
{direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'},
{direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'}
];
Then you can loop through the array and draw each wall based on each wall-object:
var cellSize=25;
function drawAllWalls(walls){
for(var i=0;i<walls.length;i++){
var w=walls[i];
ctxWall.fillStyle=w.fill;
if(w.direction=='horizontal'){
for(var x=w.startX;x<=w.endX;x++){
ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize)
}
}else{
for(var y=w.startY;y<=w.endY;y++){
ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize)
}
}
}
}
If you later want to delete a particular wall you can:
If you later want to delete just 1 box from a wall, you can:
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctxBg=canvas.getContext("2d");
var ctxWall=canvas.getContext("2d");
var canvasWidth=canvas.width;
var canvasHeight=canvas.height;
var colCount=8;
var rowCount=8;
var cellSize=25;
var walls=[
{direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'},
{direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'}
];
drawGrid();
drawAllWalls(walls);
function drawAllWalls(walls){
for(var i=0;i<walls.length;i++){
var w=walls[i];
ctxWall.fillStyle=w.fill;
if(w.direction=='horizontal'){
for(var x=w.startX;x<=w.endX;x++){
ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize)
}
}else{
for(var y=w.startY;y<=w.endY;y++){
ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize)
}
}
}
}
function drawGrid(){
ctxBg.beginPath();
for(var x=0;x<colCount+1;x++){
ctxBg.moveTo(x*cellSize,0);
ctxBg.lineTo(x*cellSize,rowCount*cellSize);
}
for(var y=0;y<rowCount+1;y++){
ctxBg.moveTo(0,y*cellSize,0);
ctxBg.lineTo(colCount*cellSize,y*cellSize);
}
ctxBg.stroke();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
Upvotes: 3