SitePoint Sponsor

User Tag List

Results 1 to 3 of 3
  1. #1
    SitePoint Addict
    Join Date
    Oct 2005
    Posts
    288
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    get id of image from canvas mouse-down event

    rather than show what I've tried, here are some code snippets. How do I get the image id on mousedown in HTML5?
    (note: don't know why the comments are not alligned, there are no tabs in the source)
    Code:
    <!DOCTYPE html>
    ...
      <canvas id='canvas' width='600' height='300'>
        Canvas not supported
      </canvas>
    
      <script type="text/javascript">
    // ----- Globals ----- 
    
      var canvas = document.getElementById('canvas'),
            context = canvas.getContext('2d');
            canvas.addEventListener("mousedown", GetSourceIndex, false);
    ...
      function DisplayCard(card, xPos, yPos){                 // show card on canvas
           var img = new Image();
           img,id="someid";                                                // IMAGE ID ASSIGNED HERE
           img.src = card.ordinal + card.suit + ".gif";          // build file name
           img.onload = function() {                                    // wait for image to load
              context.drawImage(img, xPos, yPos);            // place it on canvas
           } // end onload
      } // end function DisplayCard
    
    ...
      function GetSourceIndex(e) {                                  // mousedown event (card to move)
    // WANT TO GET THE image's ID HERE.
    ...
    (the img.id="someid" is simply to show where I would build then assign an id)

    I'm expecting there is an additional argument to add to the addEventListener and/or argument to the GetSourceIndex function. But so far, despite intense Googling, I've had no luck in finding the solution..

    grNadpa
    Last edited by Grnadpa; Oct 31, 2013 at 11:00. Reason: clarification

  2. #2
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,411
    Mentioned
    45 Post(s)
    Tagged
    12 Thread(s)
    My answer is based on code provided here: http://stackoverflow.com/questions/1...-within-canvas

    First you need a utility function which gets the canvas coordinates of the mouse pointer:

    Code JavaScript:
    stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)      || 0;
    stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)       || 0;
    styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10)  || 0;
    styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)   || 0;
    // Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page
    // They will mess up mouse coordinates and this fixes that
    var html = document.body.parentNode;
    htmlTop = html.offsetTop;
    htmlLeft = html.offsetLeft;
     
     
    function getMouse(e, canvas) {
        var element = canvas, offsetX = 0, offsetY = 0, mx, my;
     
        if (element.offsetParent !== undefined) {
            do {
                offsetX += element.offsetLeft;
                offsetY += element.offsetTop;
            } while ((element = element.offsetParent));
        }
     
        offsetX += stylePaddingLeft + styleBorderLeft + htmlLeft;
        offsetY += stylePaddingTop + styleBorderTop + htmlTop;
     
        mx = e.pageX - offsetX;
        my = e.pageY - offsetY;
     
        return {x: mx, y: my};
    }

    Then there is a handler for the mousedown event, which gets the mouse position (using the above function) and then loops over an array of placed cards to see if any of them are under the pointer:

    Code JavaScript:
    canvas.addEventListener("mousedown", getCard, false);
     
    function getCard(e) {
        var mouse = getMouse(e, canvas).
            l = cardsPlayed.length;
     
        for (var i = 0; i < l; i++) {
            if ((mouse.x > cardsPlayed[i].x && mouse.x < cardsPlayed[i].x + xOffset) 
                && (mouse.y > cardsPlayed[i].y && mouse.y < cardsPlayed[i].y + yOffset)) {
     
                console.log(cardsPlayed[i].card);
                break;
            }
        }
    }


    and finally you need some code to create an array with the x and y coordinates of each card. For testing, I did this:

    Code JavaScript:
    for (var i = 1; i < 6; i++) {
        var card = GetNextCard();
        DisplayCard(card, xOffset * i, yOffset);
        cardsPlayed.push({ card: card, x: xOffset * i, y: yOffset });
    }

    but you could just as easily store any data you want along with the coordinates.

  3. #3
    SitePoint Addict
    Join Date
    Oct 2005
    Posts
    288
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by fretburner View Post
    but you could just as easily store any data you want along with the coordinates.
    Agree that storing the data is the better option.

    Thank you for the thorough reply.

    My script has a function which does calculate the proper offset (within the major browsers).However, it only works for two rows at the moment unless each row consumes an entire card height (yOffset).
    Code:
    	function GetPlayedCardsOffset(e, xOffset, yOffset){ // Calculate Index to playedCards[]
          if (e.x != undefined && e.y != undefined) {       // browser recognize e.x e.y?
             x = e.x;                                       //  yes: capture position
             y = e.y;
          }  else {                                         //  no: e.g. Firefox
             x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
             y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
          } // end if-else
    
    		if(y < 2*yOffset) { 						// only draw card is 1st row
    			return 0;								// draw card is in playedCards[0]
    		} // end if
    		return(Math.floor(x/xOffset));              // card is playedCards[quotient]
    	} // end function GetPlayedCardsOffset
    In planning to add rows, I plan to partially overlay each row with the next row showing only the top of the card "underneath".That complicates how this function would convert the y coordinate. I thought rather than make this function a bit more cumbersome, I could "just" assign an id to each image and retrieve it on a mouse down event (very much as pulling the clientX and clientY).

    Your reply shows the error of my musings.

    Interestingly, though, as I recall, Firebug did show the id I assigned in the lower-right data panel as I stepped through.

    Again, thanks.for your continued patience and instruction.

    grNadpa


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •