Pregunta

I have a canvas with a grid, and if the user clicks on a rectangle, it should be filled with a color. What I'm having trouble doing is checking if the user is clicking on a rectangle already colored, so the program can either remove it or change its color.

Fiddle: http://jsfiddle.net/JQd4j/2/

var build_canvas = document.getElementById("builder-canvas");
var build_context = build_canvas.getContext("2d");
var builder = function () {

    var x;
    for (x = 0.5; x <= 800; x += 15) {
        build_context.moveTo(x, 0);
        build_context.lineTo(x, 390);
    }

    var y;
    for (y = 0.5; y < 400; y += 10) {
        build_context.moveTo(0, y);
        build_context.lineTo(796, y);
    }

    build_context.strokeStyle = "#000000";
    build_context.stroke();
};
builder();

build_context.fillStyle = 'red';
build_canvas.onclick = function (e) {
    var rect = build_canvas.getBoundingClientRect(),
        x = e.clientX - rect.left,
        y = e.clientY - rect.top;

    x = Math.floor((x / 15)) * 15;
    y = Math.floor((y / 10)) * 10;

    build_context.fillRect(x + 1, y + 1, 14, 9);
}

Thank you in advance.

¿Fue útil?

Solución

Create an array which corresponds to the grid. When clicked simply set the array's value to something else than what it is initially.

Initialize an array with number of columns x number of rows:

var cols = 27;
var rows = 40;
var clicked = new Uint8Array(cols * rows);  // initialized with 0

Then simply calculate the index of the cell in that array and check for a value, for example 1:

build_canvas.onclick = function (e) {

    var rect = build_canvas.getBoundingClientRect(),
        x = e.clientX - rect.left,
        y = e.clientY - rect.top,
        cellX = (x / 15)|0,           // get hor. cell position
        cellY = (y / 10)|0,           // get ver. cell position
        index = cols * cellY + cellX; // get array index

    if (clicked[index] === 1) {       // clicked ? (===1)
        alert('clicked already');     // do some action
        return;
    }

    clicked[index] = 1;               // is clicked now...

    x = cellX * 15;                   // get pixel position
    y = cellY * 10;

    build_context.fillRect(x + 1, y + 1, 14, 9);
}

Modified fiddle

The index of a 1-dimensional array representing a 2D array is always calculated width x y position + x position.

Otros consejos

Another way, by checking the color of where you are trying to paint:

    var p = build_context.getImageData(x+1, y+1, 1, 1).data; 
    var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
    if(hex=='#000000'){
        build_context.fillRect(x + 1, y + 1, 14, 9);
    }else{
        //do something
    }


function rgbToHex(r, g, b) {
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top