We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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
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(). *-:)
P.S.: Avoiding defining methods inside class constructors. That's a huge waste of RAM! @-)
Rather than defining
this.showdetails = function() { };
directly inside Event class,place it outside using prototype pattern:
Event.prototype.showDetails = function() { };
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:
break
keyword to early quit the loop:https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break
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); } }
No need for sqrt() and we can use sq() to square an expression: *-:)
http://p5js.org/reference/#/p5/sq