Persistent Shape with Mouse?

Hi all!

I suppose I’m not quite understanding the relationship between setup and draw and how to keep things persistent based on how the background is rendered. I was wondering how to keep something persistent with the mouse.

On every refresh/reload of this project, a new background image comes up, generated from the array in preload and the user can click randomly colored dots wherever they choose. This works but I was wondering how to keep the dot with the mouse cursor, instead of it just appearing with the mouse click. I’ve been able to get that functionality technically but it drags the dots all over the image, as if it was a brush and I was drawing with it.

Does anyone have some tips on how to remember how rendering works and/or tips on how to get this working? Thank you!

let retro;

function preload() {
  let img = ['./photo_1.jpg', './photo_2.jpg', './photo_3.jpg', './photo_4.jpg'];
  let pos = floor(random(img.length));
  retro = loadImage(img[pos]);
}

function setup() {
  createCanvas(720, 700);
  background(retro);
}

function mousePressed() {
  let colors = [color('blue'), color('yellow'), color('green'), color('red')];
  let pickedColor = random(colors);
  fill(pickedColor);
  noStroke();
  ellipse(mouseX, mouseY, 50, 50);
}```
1 Like
  • setup () runs only once

  • draw() runs on and on - everything that is permanent needs to be drawn here

  • mousePressed is only called once when you click the mouse

Therefore you need to draw in draw()

1 Like

Thanks! I haven’t played around with your suggestion yet but the issue with draw that I encountered was that the circle attached to the mouse cursor would constantly draw, instead of just being a circle attached to the cursor. Does that make sense?

you need to delete the canvas in draw:

(example in processing java)

void setup() {
  // init
  size(1200, 600, P3D);
  background(255);
} // func 

void draw() {
  // runs on and on 
  background(255);

  fill(255, 0, 0);
  ellipse(mouseX, mouseY, 
    5, 5);
} // func
1 Like

Ah, didn’t explain my issue clearly enough – I would like the circles to actually be drawn once, like stickers! So the behavior would be ellipse attached to mouse cursor but when the user clicks, it will be placed down. When I took your advice to put the background in draw, it did have the persistent mouse cursor behavior i was looking for but no longer placed down the circle.

Thanks for your help so far! I’m sure I’m just missing something obvious.

No, it’s not obvious.

It has to do with the usage of background(255); at beginning of draw().

Here is a solution that has background(255); and stores the points and draws them throughout.


ArrayList<PVector> points = new ArrayList ();

void setup() { 
  size(800, 800);
}// function 

void draw() { 
  background(255); 

  fill(255, 0, 0);
  text("Hello ", 19, 19);

  ellipse(mouseX, mouseY, 
    4, 4);

  fill(2, 0, 230);
  for (int i = 0; i<points.size(); i++) {
    PVector pv1 = points.get(i);
    ellipse(pv1.x, pv1.y, 4, 4);
  }//for
}// function draw()

void mousePressed() {
  points.add(new PVector(mouseX, mouseY));
}// function
3 Likes

difficult to understand,
could you possibly talk about this?
https://editor.p5js.org/kll/sketches/LEIpcL5uO

2 Likes

Yes, this is closet! I was envisioning the circle attached to the cursor to be randomly filled, however. Regardless, this is a good start!

@Chrisir thanks! Is it necessary to store the points, as a general rule of thumb?

hi, please you need to understand that we are talking here about two very different
approaches, i call it

  • paint job
    i used a image “layer” by layer = createGraphics(720,400);
    where at mouse click the random colored circles are stored ( painted in )

  • draw job
    while @Chrisir stores the mouseclicks ( position ) in a list ( and uses a JAVA program here you need to translate )
    and at draw()
    the background() cleans all
    and a FOR loop draws all circles from the positions array.

i hope you see the very different ways to do it.

how to discuss the differences / advantages?
in a paint job you can clear all as show in my code,
but you would not be able “forget” single events ( like the delete the oldest when make a new circle )
what i very well possible with a array approach.


i not like that filled as i not see where i am painting over,
but that you see the random color already ( now i use it in stroke )
is a very good idea.
please check my ( revised ) link again