2

So, I have an <img> tag that has an onclick attribute. The onclick calls a function called analyze(this), with this being the image.

The analyze function does some things to the image that aren't entirely relevant, except for the fact that it draws it onto the <canvas> element (using the drawImage function).

But now, I want to also pick the color I just clicked on in the image. I am currently using the method answered here (the answer with 70+ votes, not the chosen one): How do I get the coordinates of a mouse click on a canvas element?

But, I think I might be doing this wrong. I have the image drawn and my functions called (and those all work), but the color picking part isn't being called. I think that this is because I didn't actually capture the event. This is generally how my code looks:

<img onclick="javascript:analyze(this);" />

function analyze(img_elem) {
    // This is getting the canvas from the page and the image in it
    var canvaselement = document.getElementById('canvas').getContext('2d'),
        img = new Image();

    img.onload = function () {
        canvaselement.drawImage(img, 0, 0, 250, 250);

        ...

        canvaselement.onClick = function () {
            var coords = canvaselement.relMouseCoords(event);
            pick(img, canvaselement, coords); // pass in coordinates            
        }

    }

    img.src = img_elem.src;
}

function relMouseCoords(event) {
    var totalOffsetX = 0;
    var totalOffsetY = 0;
    var canvasX = 0;
    var canvasY = 0;
    var currentElement = this;

    do {
        totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
        totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
    }
    while (currentElement = currentElement.offsetParent)

    canvasX = event.pageX - totalOffsetX;
    canvasY = event.pageY - totalOffsetY;

    return {
        x: canvasX,
        y: canvasY
    }
}

function pick(img, canvaselement, coords) {
    var pickedColor = "";
    canvaselement.drawImage(img, 0, 0, 250, 250);

    xx = coords.x;
    yy = coords.y;
    var imgData = canvas.getImageData(xx, yy, 1, 1).data;

    pickedColor = rgbToHex(imgData);

    //alert(pickedColor);
    return pickedColor;
}

So, the code never gets to the pick function. I have a feeling that it's because I didn't actually capture the onclick event. I'm also not even sure if this is the right way to get the coordinates on the canvas, I'm just sort of hoping that I even get to that part of the debugging process at this point.

Thanks for your help!

Community
  • 1
  • 1
Cassidy
  • 3,328
  • 5
  • 39
  • 76

2 Answers2

0

The problem is probably that you're assigning canvaselement to the results of getContext('2d') and not to the element itself, which you will need for the click event binding. Create two variables, one for the DOM element itself and one for the context, something like:

var canvaselement = document.getElementById('canvas'),
    canvaselementctx = canvaselement.getContext('2d');

...
canvaselement.onClick = function() {
    var coords = canvaselementctx.relMouseCoords(event);
    ...
}
glortho
  • 13,120
  • 8
  • 49
  • 45
  • This won't work either... there is no definition for relMouseCoords on the context. –  Aug 07 '13 at 19:12
0

You have a couple of errors in the code but the reason the code you got from the linked post is that you forgot to include the prototype definition it uses:

HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;

Now you can call relMouseCoords on the canvas element:

/// event name in lower case
canvaselement.onclick = function () {
    var coords = canvaselement.relMouseCoords(event);
    //...

However, you will still get problems as you don't use a canvas context for the drawing calls.

function analyze(img_elem) {
    // This is getting the canvas from the page and the image in it
    var canvaselement = document.getElementById('canvas').getContext('2d'),

        /// get context like this
        ctx = canvaselement.getContext('2d'),
        img = new Image();

    img.onload = function () {

        /// use context to draw
        ctx.drawImage(img, 0, 0, 250, 250);

        //...