How to get click event on images that are placed on the canvas

I have a program to display multiple images on a canvas. Now I want to get the image data using a mouse click event that is put on the canvas. My JavaScript cod is

var canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
canvas.width = 720;
canvas.height = 480;

//I got images data in one array 
var imageobj = new Array();
for (var d=0;d<calloutImageArray.length;d++)
{
    imageobj[d] = new Image();
    (function(d)
     imageobj[d].src = sitePath+"ATOM/chapter1/book/"+calloutImageArray[d];
     imageobj[d].onload = function() 
      {
        ctx.drawImage(imageobj[d], calloutImageArrayX[d], calloutImageArrayY[d],calloutImageArrayW[d], calloutImageArrayH[d]);
      }; 
   })(d);
}

      

+3


source to share


2 answers


Pretty easy to do:

  • Listen for mousedown events with canvas.addEventListener

  • In the middle, check if the mouse is inside any image.

  • Get image data for the image under the mouse.

Sample code:

function handleMousedown(e){

    // tell the browser we're handling this event
    e.preventDefault();
    e.stopPropagation();

    // get the mouse position
    var mouseX=e.clientX-BBoffsetX;
    var mouseY=e.clientY-BBoffsetY;

    // loop through each image and see if mouse is under
    var hit=-1;
    for(var i=0;i<imageobj.length;i++){
        var x=calloutImageArrayX[i];
        var y=calloutImageArrayY[i];
        var w=calloutImageArrayW[i];
        var h=calloutImageArrayH[i];
        if(mouseX>=x && mouseX<=x+w && mouseY>=y && mouseY<=y+h){
            hit=i;
        }
    }

    // you clicked the image with index==hit
    // so get its image data
    if(hit>=0){
        var imageData=ctx.getImageData(
            calloutImageArrayX[hit],
            calloutImageArrayY[hit],
            calloutImageArrayW[hit],
            calloutImageArrayH[hit]);

        // now do your thing with the imageData!

    }
}

      



Sample code and demo example:

var $results=document.getElementById('results');

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var BB,BBoffsetX,BBoffsetY;
function setBB(){
  BB=canvas.getBoundingClientRect();
  BBoffsetX=BB.left;
  BBoffsetY=BB.top;
}
setBB();
window.onscroll=function(e){ setBB(); }


var imageobj=[];
var calloutImageArrayX=[10,125,10,125];
var calloutImageArrayY=[10,10,150,150];
var calloutImageArrayW=[];
var calloutImageArrayH=[];


// put the paths to your images in imageURLs[]
var imageURLs=[];  
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/character3.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/character2.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/character1.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stack1/avatar.png");

// the loaded images will be placed in imageobj[]
var imagesOK=0;
startLoadingAllImages(imagesAreNowLoaded);

// Create a new Image() for each item in imageURLs[]
// When all images are loaded, run the callback (==imagesAreNowLoaded)
function startLoadingAllImages(callback){

  // iterate through the imageURLs array and create new images for each
  for (var i=0; i<imageURLs.length; i++) {
    // create a new image an push it into the imageobj[] array
    var img = new Image();
    img.crossOrigin='anonymous';
    // Important! By pushing (saving) this img into imageobj[],
    //     we make sure the img variable is free to
    //     take on the next value in the loop.
    imageobj.push(img);
    // when this image loads, call this img.onload
    img.onload = function(){ 
      // this img loaded, increment the image counter
      imagesOK++; 
      // if we've loaded all images, call the callback
      if (imagesOK>=imageURLs.length ) {
        callback();
      }
    };
    // notify if there an error
    img.onerror=function(){alert("image load failed");} 
    // set img properties
    img.src = imageURLs[i];
  }      
}

// All the images are now loaded
// Do drawImage & fillText
function imagesAreNowLoaded(){

  // the imageobj[] array now holds fully loaded images
  // the imageobj[] are in the same order as imageURLs[]

  // add widths & heights to the appropriate arrays
  for(var i=0;i<imageobj.length;i++){
    calloutImageArrayW.push(imageobj[i].width);
    calloutImageArrayH.push(imageobj[i].height);
  }

  // listen for mousedown events
  canvas.onmousedown=handleMousedown;

  draw();

}


function draw(){
  ctx.clearRect(0,0,cw,ch);
  for(var d=0;d<imageobj.length;d++){
    ctx.drawImage(imageobj[d], 
                  calloutImageArrayX[d], calloutImageArrayY[d],
                  calloutImageArrayW[d], calloutImageArrayH[d]);
  }    
}        



function handleMousedown(e){

  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // get the mouse position
  var mouseX=e.clientX-BBoffsetX;
  var mouseY=e.clientY-BBoffsetY;

  // loop through each image and see if mouse is under
  var hit=-1;
  for(var i=0;i<imageobj.length;i++){
    var x=calloutImageArrayX[i];
    var y=calloutImageArrayY[i];
    var w=calloutImageArrayW[i];
    var h=calloutImageArrayH[i];
    if(mouseX>=x && mouseX<=x+w && mouseY>=y && mouseY<=y+h){
      hit=i;
    }
  }

  // you clicked the image with index==hit
  // so get its image data
  if(hit>=0){
    var imageData=ctx.getImageData(
      calloutImageArrayX[hit],
      calloutImageArrayY[hit],
      calloutImageArrayW[hit],
      calloutImageArrayH[hit]);

    var pos;
    switch(hit){
      case 0:pos='top-left';break;
      case 1:pos='top-right';break;
      case 2:pos='bottom-left';break;
      case 3:pos='bottomRight';break;
    }
    $results.innerHTML='You clicked the '+pos+' image.<br>This imageData has this length: '+imageData.data.length;

  }

}
      

body{ background-color: ivory; }
canvas{border:1px solid red;}
      

<h4 id="results">Click on an image</h4>
<canvas id="canvas" width=300 height=300></canvas>
      

Run codeHide result


+1


source


Take my advice and go with something like fabricJS, it will make your life really easy. In this case, you can easily have multiple objects on the canvas and also do it separately (Scale, rotate, pan).



+1


source







All Articles