0

A friend of mine needs an small application which renders a 32x32 set of black rectangles. When one of these is clicked it needs to switch to a white rectangle. The image created by changing color to these boxes then would need to be exported as a png or jpg.

I was pretty sure I could do this using Canvas, but now that I have my grid working, I suddenly realize that I have absolutely no idea how to actually get the interaction to work, or if it's even possible to make it work.

Would I be able to use SVG for this task? I know Canvas has a function to export what is displayed on the canvas, but without the interaction it's pretty useless.

What's my best option? Can it actually be done?

Eight
  • 29
  • 6
  • Not quite sure what the actual difficulty is with the canvas? Share your code and what you are stumbling on specifically. – jcaron Feb 16 '16 at 22:10
  • If the question is about capturing an image from canvas or SVG, see http://stackoverflow.com/questions/923885/capture-html-canvas-as-gif-jpg-png-pdf and http://stackoverflow.com/questions/3975499/convert-svg-to-image-jpeg-png-etc-in-the-browser -- canvas seems easier for this – Stuart Feb 16 '16 at 22:14
  • If it's about user interaction with objects drawn on the canvas -- there is no simple way to do this and you would have to record the location of the rectangles and then check the mouse coordinates when user clicks on the canvas. SVG is probably easier from this point of view. – Stuart Feb 16 '16 at 22:16
  • The question is about changing colors of the rectangles. I'll look into SVG – Eight Feb 16 '16 at 22:18
  • SVG is easier because the rectangles will be like other objects on the page and you can attach event listeners to them. But like I said, you will then have a harder time exporting as png or jpg. As the interaction sounds fairly simple anyway I would probably use canvas. – Stuart Feb 16 '16 at 22:20
  • 1
    Given that the SVG solution needs 32x32 (==1024) items added to the DOM, I would go with html5 canvas this time. If it were more like 15x15 I would go with SVG. [Here's](http://stackoverflow.com/questions/17790027/show-converted-mouse-coordinates-of-an-element-with-javascript/17792043#17792043) a somewhat on-point previous post showing how to listen for mouse events an determine which grid-cell the mouse is over. – markE Feb 16 '16 at 22:36

1 Answers1

2

This shows how you would manage simple interaction using canvas: make a 32 x 32 array showing whether the rectangles are switched on or not. When the user clicks on the canvas, calculate which rectangle the mouse is positioned over and toggle it.

For more complicated interactions you would need to store coordinates of each shape drawn and then redraw the entire canvas, to make sure overlapping shapes are dealt with correctly.

JSfiddle

var canvas = document.getElementById('rectangles'),
    context = canvas.getContext('2d'),
    rectangles = [],
    rectWidth = canvas.width / 32,
    rectHeight = canvas.height / 32;

function makeRectangles() {
    var x, y, row;
    for (y = 0; y < 32; y++) {
        row = [];
        for (x = 0; x < 32; x++) {
            row.push(true);
            drawRectangle(x, y, true);
        }
        rectangles.push(row);
    }
}

function drawRectangle(x, y, black) {
    context.strokeStyle = 'cyan';
    context.fillStyle = black ? 'black' : 'white';
    context.beginPath();
    context.rect(x * rectWidth, y * rectHeight, rectWidth, rectHeight);
    context.fill();
    context.stroke();
}

function canvasClick(ev) {
    var x = Math.floor((ev.pageX - canvas.offsetLeft) / rectWidth),
        y = Math.floor((ev.pageY - canvas.offsetTop) / rectHeight);
    rectangles[y][x] = !rectangles[y][x];
    drawRectangle(x, y, rectangles[y][x]);
}

makeRectangles();
canvas.addEventListener('click', canvasClick);
Stuart
  • 9,597
  • 1
  • 21
  • 30