HTML5画布中的图像点击事件

5

我有一个HTML5的画布,并在其中添加了一张图片,我想调用图片的点击事件,但是事件没有触发。我正在编写一个HTML代码和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>

什么是vclick?它是jQuery Mobile使用的东西吗?还是你只是在“click”中打错了一个字母?这可能会导致问题。 - Jonas Grumann
此外,您可以创建一个图像,为其指定一个ID,然后将其放置在画布中,但是画布中的图像没有ID。 - Jonas Grumann
5个回答

8

现在我了解你想要达到的目标,你想将图像放入画布中,然后使用jQuery检查当你点击图像时。但是,遗憾的是,它不是这样工作的。画布中的图像不再是DOM元素,只有画布本身是一个DOM元素。这意味着你可以调用:

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

但是你不能调用

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

因为 #canvasImage 并不存在,即使原始图片是一个dom节点。 如果在项目中确实没有其他选择,fabricjs 可能会有帮助: http://fabricjs.com/

3

您无法在画布上绘制的图像或形状上添加事件监听器,因此您必须在绘制图像的像素上添加事件监听器,例如:

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

});

2

图片是画在画布上的,不能将其视为一个元素。

您可以通过检查点击的坐标是否在图像上来实现它。
这里有一个示例。

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

当你有大量通过程序生成的图像时,这是一个完全不切实际的解决方案。你会建议如何处理呢? - Axl

0

嗯,你实际上可以使用一个解决方法,其中涉及将你的图像转换为向量SVG图像(你可以使用PNGtoSVG来进行转换)

然后,你需要从SVG文件中提取路径(如果在文本编辑器中打开SVG文件,则为'd'属性),并在画布中使用它:

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

它使用Path2D()创建可跟踪的元素,然后精确地检查元素是否在内部被点击,该事件原则上应满足OP的需求。

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>


-1

看起来缺少点击事件的监听器。这样做怎么样:

<!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>

什么出了问题?我在我的浏览器上测试了代码并在W3C上验证了一切都正常,弹出窗口也显示出来了。你能具体点说出问题是什么吗? - merosss
我刚刚添加了显示购物篮的代码,如果这是问题的话 ;) - merosss
@merosss,如果鼠标在画布上的任何位置被点击,你的代码将会弹出“Hello”。 - singhiskng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接