So my code is almost done. I just have a problem filling in the rectangles in the function detection as the line buffer code keeps reseting the grid using image data. I tried adding a second canvas to store the fill in rectangles and the second canvas was below the first one and the filled in rectangles weren’t in the right places.I am new to programming so this is bad functioning code.
<!DOCTYPE html>
<html>
<head>
<title>Grid</title>
</head>
<body>
<canvas id="cnv" width="500" height="500" style="border: 2px solid black"></canvas>
<script type="text/javascript"></script>
<script>
var cnv = document.getElementById('cnv');
cnv.addEventListener('click', clickHandler);
cnv.addEventListener('mousemove', moveHandler);
var ctx = cnv.getContext('2d');
var x1 = {};
var y1 = {};
var x2 = {};
var y2 = {};
var counter = 0;
var move = 0; //for determining if line is in the same column
var boxes = "";
var size = 25; //size of boxes
var dotSize = 5;
var dotAdj = 7; //dot adjustment
var line = false;
function drawGrid(cnv, size) {
var width = cnv.width,
height = cnv.height,
x,
y;
ctx.beginPath();
for (x = 0; x < width; x += size) {
ctx.moveTo(x, 1);
ctx.lineTo(x, cnv.height);
}
for (y = 0; y < height; y += size) {
ctx.moveTo(0, y);
ctx.lineTo(cnv.width, y);
}
ctx.stroke();
};
drawGrid(cnv, size);
function clickHandler(event) {
if (counter == 0) {
counter = 1;
x1 = event.clientX - ctx.canvas.offsetLeft;
y1 = event.clientY - ctx.canvas.offsetTop;
//console.log(['point 1', x1, y1]);
} else {
counter = 0;
x2 = event.clientX - ctx.canvas.offsetLeft;
y2 = event.clientY - ctx.canvas.offsetTop;
//console.log(['point 2', x2, y2]);
line_algorithm();
}
if (!line) { //no line, starts line function
line = new Line(event.layerX, event.layerY);
} else { //line drawn from first point to second point
line = line.close(event.layerX, event.layerY);
}
};
function moveHandler(event) {
if (line) { //line buffers to where mouse is
line.drawBuffer(event.layerX, event.layerY)
}
};
function Line(x, y) {
this.currentState = ctx.getImageData(0, 0, cnv.width, cnv.height);
this.x = x;
this.y = y;
drawDot.call(this, x, y);
function resetState() {
ctx.clearRect(0, 0, cnv.width, cnv.height);
ctx.putImageData(this.currentState, 0, 0);
};
function drawLine(x, y) {
ctx.beginPath();
ctx.moveTo(this.x - dotAdj, this.y - dotAdj);
ctx.lineTo(x - dotAdj, y - dotAdj);
ctx.stroke();
};
function drawDot(x, y) {
ctx.beginPath();
ctx.arc(x - dotAdj, y - dotAdj, dotSize, 0, 2 * Math.PI);
ctx.stroke();
};
this.close = function(x, y) {
resetState.call(this);
drawLine.call(this, x, y);
return false;
};
this.drawBuffer = function(x, y) {
resetState.call(this);
drawDot.call(this, this.x, this.y);
drawDot.call(this, x, y);
ctx.setLineDash([5, 10]);
drawLine.call(this, x, y);
ctx.setLineDash([]);
};
};
function line_algorithm() {
var m = ((y1 - y2) / (x1 - x2)); //slope
var b = (y1 - (m * x1)); //y intercept
console.log(['point 1', x1, y1, ' point 2', x2, y2]);
console.log(['m', m, ' b', b]);
for (var i = 1; i <= cnv.width / size; i++) {
if (x1 >= (i - 1) * size && x1 <= (i * size) && x2 >= (i - 1) * size && x2 <= (i * size)) { //check if line is in same column
move = 1; //line is in the same column
}
} //end of while loop
if (move === 1) {
noshift(m, b);
} else {
shift(m, b);
}
function detection(row, column) { //hitcheck list string starts off as ""
if (boxes.indexOf(row + ":" + column + ",") === -1) { //if last hitcheck ISN'T in list of coordinates then box is filled in
boxes = boxes + row + ":" + column + ","; //adds hitcheck to list
console.log(['box hit', row, column]);
//row = 1, column = 1, [0,0], row = 2, column = 1, [25,0]
// ctx.beginPath();
// ctx.rect((row - 1) * size, (column - 1) * size, size, size);
// ctx.fillStyle = 'black';
// ctx.fill();
// ctx.putImageData(this.currentState, 0, 0);
//ctx.clearRect(0, 0, cnv.width, cnv.height);
}
}
function noshift(m, b) { //line is in the same column
console.log(['no shift hit']);
move = 0;
boxes = "";
//need to make a statement for when the y is the same
if (y1 != y2) {
var y3 = Math.min(y1, y2);
var x3 = (y3 - b) / m;
var row = 0;
var column = Math.floor(x3 / size) + 1; //right and left
while (y3 <= Math.max(y1, y2)) { //loop starts from smaller y coordinate to bigger y coordinate, inc by 1
row = Math.floor(y3 / size) + 1; //up and down
detection(row, column);
y3 += 1;
}
} else { //y is the same
var y3 = 0;
var x3 = (y3 - b) / m;
var row = 0;
var column = Math.floor(x3 / size) + 1; //right and left
while (y3 <= y1) { //loop starts from smaller y coordinate to bigger y coordinate, inc by 1
row = Math.floor(y3 / size) + 1; //up and down
detection(row, column);
y3 += 1;
}
}
}
function shift(m, b) { //line crosses more than one column
console.log(['shift hit']);
boxes = "";
var x3 = Math.min(x1, x2);
var y3 = 0;
var row = 0;
var column = 0;
while (x3 <= Math.max(x1, x2)) { //loop starts from smaller x coordinate to bigger x coordinate, inc by 1
y3 = m * x3 + b; //y = mx + b;
row = Math.floor(y3 / size) + 1; //math.floor gets lowest possible integer, 5.3 to 5
column = Math.floor(x3 / size) + 1; //row and column are x and y of a box hit, use smaller coordinates
detection(row, column);
x3 += 1;
}
}
}; //end of line_algortihm
</script>
</body>
</html>