Are mouse event listeners only for DOM elements?

Hi there. I'm creating a series of ellipses on the screen and want each one to respond to a mouse event. Ie: when ellipse is clicked, do something. These are not DOM elements - is that why I can't get it to work?

Here's a simplified example where I'm trying to attach a mousePressed listener to an ellipse. Doesn't work :(

``` var events = [];

  function setup() {
    createCanvas(windowWidth, windowHeight);

    for (var i=0; i<eventfile.length; i++){
      events[i] = new Event(eventname[i],eventsize[i]); //assume these exist
    }
    noLoop();
  }

  function draw() {
    for (var i=0; i<events.length; i++){
      events[i].display();
    }
  }

  function Event(eventname, eventsize) {
    this.y = eventsize*4;
    this.x = eventsize*2; 
    this.diameter = eventsize;
    this.eventname = eventname;

    this.display = function(){
      this.shape = ellipse(this.x, this.y, this.diameter, this.diameter);
    this.shape.mousePressed(this.showdetails); //THIS DOESN'T WORK
    }

    this.showdetails = function(){
      console.log (this.eventname)
    }
  }

```

Answers

  • edited September 2015

    ellipse() merely returns the p5 object. That is, the sketch's own reference:
    http://p5js.org/reference/#/p5/ellipse

    The sketch already got its own mousePressed() callback. Adding more will only make it "heavier":
    http://p5js.org/reference/#/p5/mousePressed

    Since each Event object got their own coords & dimensions, it's easy to check which 1 of them got clicked at by traversing their array and checking against mouseX & mouseY within mousePressed(). *-:)

  • edited September 2015

    P.S.: Avoiding defining methods inside class constructors. That's a huge waste of RAM! @-)
    Rather than definingthis.showdetails = function() { }; directly inside Event class,
    place it outside using prototype pattern: Event.prototype.showDetails = function() { };

  • edited September 2015

    Oh really? I was thinking about traversing the array to check for click... but then thought that would be a processor intensive way to check for click-target. That's the right way to do it even if there are 10,000s of elements in the array?

    There's no concept in p5 of the ellipse (or a shape in general) being an object per-se huh? It's drawn the to screen and then p5 considers it painted to screen with no further knowledge of it? Would seem handy to be able to save a reference to a shape and then to move it / attach a listener to it /etc as you would an HTML element. Otherwise, seems like i'm reinventing much of the wheel - like attaching an event listener to an object, in this case. My $.02.

    Thx for the tip on using prototype!

  • More tips:

  • Here's the "point is within circle" function, in case it's useful to anyone else:

    this.mouseoverme = function(){ var hit = Math.sqrt((mouseX-this.x)*(mouseX-this.x) + (mouseY-this.y)*(mouseY-this.y)) < this.radius; if (hit){ console.log(this.eventname); } }

  • edited September 2015 Answer ✓

    No need for sqrt() and we can use sq() to square an expression: *-:)
    http://p5js.org/reference/#/p5/sq

    Event.prototype.isMouseOverMe = function() {
      return sq(mouseX - this.x) + sq(mouseY - this.y) < sq(this.rad);
    };
    
Sign In or Register to comment.