Rizwan Qureshi
Rizwan Qureshi

Reputation: 592

Image Click Event in HTML5 Canvas

I have a HTML5 canvas and I have added an image in it and I want to call click event of image but event doesn't fire. I am writing a html code and some code of jqmobile

<html>
<head>
    <script src="jquery-1.10.2.min.js"></script>
    <script src="jquery.mobile-1.2.1.js"></script>
    <script src="jquery.mobile-1.2.1.min.js"></script>
</head>
<body>
    <canvas id="canvas1" style="position: absolute; left: 0px; top: 0px;" width="1280" height="960">This text is displayed if your browser does not shown.
    </canvas>
    <script>
        $(function () {

            var ctx = document.getElementById("canvas1").getContext("2d");
            var imgBasket = new Image();
            imgBasket.id = "imgBasket";
            imgBasket.src = "Basket.png";
            ctx.drawImage(imgBasket, 580, 260, 200, 200);


            //this jquery mobile event not working in canvas
            $("document").on("vclick", "#imgBasket", function () {
                alert("Hello");
            });
        });
    </script>
</body>
</html>

Upvotes: 5

Views: 21991

Answers (5)

RAZ0229
RAZ0229

Reputation: 306

Well, you can actually use a workaround that involves converting your image to vector SVG image (You can do that using PNGtoSVG)

Then, you need to extract the path (the 'd' attribute in your SVG file if you open it in a text editor) from your svg file and use that in you canvas:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const yourImg = new Path2D('d'); // extracted path as parameter
ctx.fill(yourImg);

// Listen for click event
canvas.addEventListener('click', (e) => {

   // See if it lies inside the given path
   if (ctx.isPointInPath(yourImg, e.offsetX, e.offsetY)) 
       alert('Hello'); // clicked on your Image

   // Draw Image
   ctx.clearRect(0, 0, canvas.width, canvas.height);
   ctx.fill(yourImg);
});

It creates a trackable element using Path2D() and then checks precisely if the element was clicked inside, the event and should meet OP's needs in principle.

const canvas = document.getElementById('canvas');
canvas.style.border = 'solid 1px #000';
const ctx = canvas.getContext('2d');

const yourImg = new Path2D('M17.21 9l-4.38-6.56c-.19-.28-.51-.42-.83-.42-.32 0-.64.14-.83.43L6.79 9H2c-.55 0-1 .45-1 1 0 .09.01.18.04.27l2.54 9.27c.23.84 1 1.46 1.92 1.46h13c.92 0 1.69-.62 1.93-1.46l2.54-9.27L23 10c0-.55-.45-1-1-1h-4.79zM9 9l3-4.4L15 9H9zm3 8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z');

ctx.fill(yourImg);

canvas.addEventListener('click', (e) => {

   if (ctx.isPointInPath(yourImg, e.offsetX, e.offsetY))
      {
        alert('Hello')
      }
       
       ctx.clearRect(0, 0, canvas.width, canvas.height);
       ctx.fill(yourImg);
    });
<h4>Try clicking the 'bucket' icon:</h4>

<canvas id="canvas" width="400" height="250"></canvas>

Upvotes: 0

merosss
merosss

Reputation: 555

It seems like the listener for the click event is missing. What about doing it this way:

<!DOCTYPE html><html>
  <head><title>Canvas HTML5 Test Page</title>
     <script>
       function newCanvasListen() {
           var canvas = document.getElementById("canvas1");
           var ctx = canvas.getContext("2d");

           var imgBasket = new Image();
           imgBasket.src = "Basket.png";
           imgBasket.id = "imgBasket";

           imgBasket.onload = function() {
               var imageBasket = ctx.drawImage(imgBasket, 0, 0);
               ctx.fillStyle = imageBasket;
           };

           canvas.addEventListener("mousedown", doMouseDown, false);

       }
       function doMouseDown(event) {
           alert("Hello");
       }
     </script>
  </head>
  <body onLoad=newCanvasListen()>
    <canvas width="256" HEIGHT="256" ID="canvas1">
       This text is displayed if your browser does not shown.
    </canvas>
  </body>
</html>

Upvotes: -1

pareshm
pareshm

Reputation: 4984

You cannot add eventlistener on image or shape you drawed on canvas so you have to add eventlistener on pixels where you have drawed the image means for example:

var img=document.getElementById("img1");
//ctx.drawImage(img,x,y,height,width);          
ctx.drawImage(img,10,10,20,20);
    $("#canvas1").on("click",function(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;

     //Image x y cordinates adding width and height

if((canvasX>=10 && canvasX<=30) && (canvasY>=10 && canvasY<=30))
        {
            alert("canvasX:"+canvasX+"  "+"canvasY:"+canvasY);
        }

});

Upvotes: 3

singhiskng
singhiskng

Reputation: 511

image is painted on canvas, you can't considered it as a element.

you can do it like checking co-ordinates of click, if it lies on your image or not.
here is a sample.

var canvas = document.getElementById("canvas1");
canvas.addEventListener("mousedown", clicked, false);

function clicked(e){
    e.preventDefault();
    var x = e.clientX;
    var y = e.clientY;

    if(x>580 && x<780 && y>260 && y>460){ //780 = 580+(200) <- image width
        alert('Hello');
    }
}

Upvotes: 2

Jonas Grumann
Jonas Grumann

Reputation: 10786

Now I understand what you are trying to achieve, you want to put an image in a canvas and then use jquery to see when you clicked on the image. Well, sadly, it doesn't work like this. Images in the canvas are no longer dom elements, only the canvas itself is one. This means you can call:

$('#canvas').on('click', function() {});

but you can't call

$("document").on("click", "#canvasImage", function () {});

Because the #canvasImage isn't there, even if the original image was a dom node. If there's really no other way of going with your project, fabricjs might help:

http://fabricjs.com/

Upvotes: 8

Related Questions