Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Nov 2012
    Posts
    3
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Question OOP: adding Event to an Javascript object

    I want to add an eventlisterer 'click' to an object, which is represented to the user as image. This wouldn't work, but shows what i want to achieve:

    function object {
    this.picture = null;
    this.src = 'images/defualt.png';
    this.id = 1;
    this.setImage(this.src);
    }

    object.prototype.setImage = function(src) {
    this.picture = new Image();
    this.picture.src = src;
    this.picture.addEvenListener('click' , clickme, false);
    }

    clickme = function() {
    alert('hurray, i'm clicked...');
    }

  • #2
    Senior Coder
    Join Date
    Dec 2010
    Posts
    2,391
    Thanks
    11
    Thanked 568 Times in 561 Posts
    It would work ... but the image must be attached to the DOM otherwise it will (of course) not be visible and not be clickable.
    Code:
    object.prototype.clickme = function() {
       alert('Hooray!');
    };
    
    object.prototype.setImage = function(src) {
       this.picture = new Image();
       this.picture.src = src;
       document.body.appendChild(this.picture);
       this.picture.addEventListener('click' , this.clickme, false);
    };

  • Users who have thanked devnull69 for this post:

    Ben Stuijts (11-12-2012)

  • #3
    New to the CF scene
    Join Date
    Nov 2012
    Posts
    3
    Thanks
    2
    Thanked 0 Times in 0 Posts
    There is only one but... I'm drawing the picture of the object on my canvas. I should have told this:

    object.prototype.draw = function(xpos, ypos) {
    ctx.drawImage(this.picture,sx, sy, swidth, sheight,xpos,ypos, width, height);
    }

    NB: the vars sx, sy, swidth, sheight, width and height are optional; I would like to use them , so i can define my picture from a tilesheet.

  • #4
    Senior Coder
    Join Date
    Dec 2010
    Posts
    2,391
    Thanks
    11
    Thanked 568 Times in 561 Posts
    Then (of course) you need to attach the event listener to the canvas and not to the image ... because the image does not exist in the page DOM

  • #5
    New to the CF scene
    Join Date
    Nov 2012
    Posts
    3
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Hello,

    This is a working solution, but not that great, because it wil take some calc power... I've add an eventlistener to the canvas(click). When clicking the canvas, a function will check all objects, to see you've clicked them. Not nice, but a start...

    // declaring multiple objects:
    var obj = new Array;
    obj[0] = new object();
    obj[1] = new object();

    // adding to the objectclass:
    this.xpos;
    this.ypos;
    this.width;
    this.height;

    etc...

    Code:
    canvas.addEventListener("click", select, false);
    
    function select(e) {
    	var mouseX = e.offsetX || e.layerX;
    	var mouseY = e.offsetY || e.layerY;
    	//alert('canvas was clicked / mousecoördinates are: ' + mouseX + ' , ' + mouseY);
    	var objects = obj.length;
    	for(var i = 0; i < objects; i++) {
    
    		var X = obj[i].xpos;
    		var W = X + obj[i].width;
    		var Y = obj[i].ypos;
    		var H = Y + obj[i].width;
    
    		if ( mouseX >= X && mouseX <= W && mouseY >= Y && mouseY <= H) 
    		{ 
    		//alert('object found'); 
    		object_click(i);
    		}
    	}
    }
    
    function object_click(id) {
      alert('object with id = ' + id + 'clicked and found.');
    }
    Hopefully you will know a much better solution, because this is nice with a couple of objects, but not nice with thousands of them of course..

    Sorry still learning! ;-)

  • #6
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,275
    Thanks
    10
    Thanked 581 Times in 562 Posts
    you can put clear divs over the canvas to catch clicks on a known rectangular area without searching at "click-time".

    you can even export the canvas to the background-image of a <table>, use css to style tr/td to size, bind onclicks to TDs, and use the onclick's e.target.cellIndex/e.target.parentNode.rowIndex to get boxy "coords".


    if you want the most flexibility, build a mini mvc to avoid math at run-time.
    you can use something like (posX / 30) to slice the canvas into 30px wide boxes.
    once you know the box number, you can check the relationship from a simple array.
    that array can hold links to whatever objects you want, I use strings in this theoretical example:

    Code:
    // id a click with one of these 5 model groups:
    var groups=[
     "alpha",
     "beta",
     "charlie",
     "delta",
     "echo"
    ];
    
    //a 3X3 grid of the view of groups:
    var objs=[
    [ 1,2,1 ],
    [ 1,5,1 ],
    [ 4,3,3 ]
    ];
    
    
    
    // control click dispatches to a 90px X 90px 9panel box:
    
    var clickedGroup= groups[ 
        objs[ 
             Math.floor( y / 30 ) 
        ][
             Math.floor( x / 30 ) 
        ] 
    ];
    
    alert( clickedGroup ); //should be "bravo" or "delta" or one of those.
    no loops, no conditionals, no long-hand pixel coords or brittle repetition.
    this pattern de-couples the specific image from the physical layout and from the behavior, allowing placeholders and easy scaling.
    Last edited by rnd me; 11-13-2012 at 11:29 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • Users who have thanked rnd me for this post:

    Ben Stuijts (11-13-2012)


  •  

    Posting Permissions

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