Question

I have made a small red rectangle inside an orange canvas. I introduced a click event which will occur when I only click on the red portion. It works fine and gives me (255 0 0). But at the lower right corner it gives me (255 165 0) which is orange and clearly not what I wanted. Why is this happening? If there is any smarter way to do this, please advise. Thanks!

<html>
<head>
    <style>

    </style>
</head>

<body>
    <script>
        function makeit() {
            var canvas = document.getElementById("mycanvas");
            canvas.width = 200;
            canvas.height = 50;
            canvas.style.position = "absolute";
            canvas.style.top = "30px";
            canvas.style.left = "100px";
            canvas.style.border = "1px solid black";

            var ctx = canvas.getContext('2d');
            ctx.fillStyle = "orange";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.fill();

            ctx.fillStyle = "red";
            ctx.fillRect(0, 0, 20, 20);
            ctx.fill();
            canvas.addEventListener('click', myfunc, false);

            function myfunc(e) {
                if (e.layerX <= 20 && e.layerY <= 20) {
                    var imageData = ctx.getImageData(e.layerX, e.layerY, 1, 1);
                    alert(imageData.data[0] + " " + imageData.data[1] + " " + imageData.data[2]);
                }
            }
        }

        window.onload = makeit;
    </script>

    <canvas id="mycanvas"></canvas>
</body>
</html>
Was it helpful?

Solution

You should change to:

if (e.layerX < 20 && e.layerY < 20)

Here's why: context2D.getImageData samples a rectangle. If you sample a rectangle:

(20, any_value, 1, 1)

or

(any_value, 20, 1, 1)

your sample is outside of your red rectangle (0, 0, 20, 20). In other words, pixels at positions (x, 20) and (20, y) are orange.

OTHER TIPS

The CSS border is nudging the whole thing off by 1px. If you want a border, draw it on the canvas :)

var canvas = document.getElementById("mycanvas");
canvas.width = 200;
canvas.height = 50;
canvas.style.position = "absolute";
canvas.style.top = "30px";
canvas.style.left = "100px";

var ctx = canvas.getContext('2d');
ctx.fillStyle = "orange";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();

ctx.fillStyle = "red";
ctx.fillRect(0, 0, 20, 20);
ctx.fill();
canvas.addEventListener('click', myfunc, false);

function myfunc(e) {
    if (e.layerX <= 20 && e.layerY <= 20) {
        var imageData = ctx.getImageData(e.layerX, e.layerY, 1, 1);
        alert(imageData.data[0] + " " + imageData.data[1] + " " + imageData.data[2]);
    }
}

http://jsfiddle.net/UQM9Q/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top