Unable to use mousePressed() specific to canvas element (instead of global) in Instance mode

Building a page with multiple sketches (see http://forum.processing.org/two/discussion/10241/fail-to-load-any-sketch-on-webpage-in-instance-mode#latest for project description). I have set up each sketch with instance mode, but I would like the sketch to respond to mouse clicks only within its own canvas. I am trying to implement the mousePressed() listener specific to the canvas DOM element, according to the p5 wiki (https://github.com/processing/p5.js/wiki/Beyond-the-canvas#element-vs-global-listeners). None of the examples there are given in instance mode, and I'm having trouble translating the example structure to my own sketch.

Here is the full sketch:

`

var drawSpiralSketch = function( ds ) {

var theta = 0.0;
var radius = 0.0;

var x;
var y;

var frameRate = 60;
var arcRate = ds.HALF_PI / frameRate;

var canvas;

ds.setup = function() {
  canvas = ds.createCanvas(500, 500);
  canvas.id("draw-spiral");

  ds.frameRate(frameRate);
  ds.background(0);
  ds.stroke(255);
  ds.smooth();
  ds.noFill();
};

ds.draw = function() {

  incRadius = radius + 1.618;
  incTheta = theta + arcRate;

  ds.arc(x, y, radius, incRadius, theta, incTheta);

  radius = incRadius;
  theta = incTheta;
}; 

ds.mousePressed = function() {
  x = ds.mouseX;
  y = ds.mouseY;
  theta = radius = incTheta = incRadius = 0.0;
  return {
    x: x,
    y: y,
    theta: theta,
    radius: radius,
    incTheta: incTheta,
    incRadius: incRadius
  };
};

};

var drawSpiral = new p5(drawSpiralSketch, 'draw-spiral');

`

I have declared canvas as a global, and am able to call it successfully under ds.setup to change the DOM properties, but if I change ds.mousePressed to canvas.mousePressed, the console reads that "canvas is undefined".

Per the p5 wiki I have also tried to call the ds.mousePressed function within ds.setup as a response to a canvas.mousePressed event, like so:

ds.setup = function() { canvas = ds.createCanvas(500, 500); canvas.id('draw-spiral'); canvas.mousePressed(ds.mousePressed); ...

That has no effect on the sketch functionality, with mouse clicks outside of the canvas still reading the mouse position and creating a spiral from that origin point.

I'm considering adding conditionals in the ds.mousePressed function to check if the mouse position is within the given canvas coordinates (i.e., adding logic to check for 0 < x <= 500, 0 < y <=500), but I'd rather use canvas.mousePressed, somehow.

Thanks for any help!

Answers

  • Sorry about the code formatting - it doesn't seem to want to play nice with those first and last lines of the sketch.

  • Answer ✓

    @AmundsenJunior said:

    if I change ds.mousePressed to canvas.mousePressed, the console reads that "canvas is undefined".

    If you look carefully at the example you linked to they don't simply change the parent of the mousePressed function. Instead they create a separate named function and call this from mousePressed in setup. So in your case you might have something like this:

    var canvas;
    ds.setup = function() {
        canvas = ds.createCanvas(500, 500);
        // Assign a callback function to canvas.mousePressed event
        canvas.mousePressed(doThisOnMousePress);
    }
    
    //snip
    
    // instead of changing this to canvas.mousePressed; set it to a named function
    var doThisOnMousePress = function() {
        // do stuff
    }
    
  • Thank you, @blindfish! That solved it. I saw your response earlier in email, and really thought I had already tried every combination of that solution...except for the one correct way, I see.

    I specifically changed my ds.mousePressed function to the name ds.newSpiral, then called that function in ds.setup with canvas.mousePressed(ds.newSpiral).

    Thanks!

Sign In or Register to comment.