简体   繁体   中英

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>

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/

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);
        }

});

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');
    }
}

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>

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM