# Continuously update drawing during mouseDragged

**URL:** https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762
**Category:** Coding Questions
**Created:** [October 20, 2020, 7:06pm UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762 "2020-10-20T19:06:54Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![rajmb](https://avatars.discourse-cdn.com/v4/letter/r/f14d63/32.png) [@rajmb](https://discourse.processing.org/u/rajmb)
#### Post date: [October 20, 2020, 7:06pm UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762/1 "2020-10-20T19:06:54Z")

</div>

I am trying to create a simple mspaint like application on the web using p5 as a learning exercise. I have provided a button to draw an ellipse on the canvas and want to show the ellipse being resized as the mouse is dragged. The final ellipse should be shown once the mouse button is released.

```auto
let penColor = '#ffffff';
let bgColor = '#000000';
let strokeWt = 4;
let globalX = 0;
let globalY = 0;

function setup() {
  createCanvas(400, 400);
  background(color(bgColor));
}

function draw() {
  stroke(penColor);
  strokeWeight(strokeWt);
  noFill();
}

function mousePressed() {
  globalX = mouseX; 
  globalY = mouseY;
}

function mouseReleased() {
  ellipseMode(CORNERS);
  ellipse(globalX, globalY, mouseX, mouseY);
}

function mouseDragged() {
  push();
  ellipseMode(CORNERS);
  ellipse(globalX, globalY, mouseX, mouseY);
  stroke(bgColor);
  ellipse(globalX, globalY, mouseX, mouseY);
  pop();
}

```

The code can be viewed here:

> **[p5.js Web Editor](https://editor.p5js.org/rajmb502/sketches/0UB2fQ9t-)**

As can be seen above, the current code does give a beautiful pattern but it is not what I wanted. It also overwrites any previous ellipses drawn below, which I want to retain. I saw a reference to thread() in another post but that does not work in JS. Any ideas how this can be achieved?

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [October 20, 2020, 10:17pm UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762/2 "2020-10-20T22:17:50Z")

</div>

Hello and welcome to the forum!

It’s great to have you here with us!

basically, use `background` at start of draw() and when you release mouse, put the new ellipse in an ArrayList and display the content of the ArrayList throughout.

it’s not easy

Here is an example in processing (not p5) with lines

**to draw a line, click mouse once, release mouse, move mouse, click mouse again and release mouse**

Warm regards,

Chrisir

```auto

// to draw a line click mouse once, release mouse, click mouse again and release mouse 

// The coordinates of the lines: each line goes "from" a point "to" a point (PVector).

// The lists are parallel in that sense that the elements of both lists together make a line: 
// the 0th element of both lists make one line, the 1st element of both lists make one line, the 2nd etc. 
ArrayList<PVector> from = new ArrayList(); 
ArrayList<PVector> to = new ArrayList();

// necessary to know if the mouse enters a "from" or a "to" point of a line
int situation=0;

// -------------------------------------------------------------------------
// processing core functions  

void setup() {
  size(600, 1000);
  stroke(255);
}//func

void draw() {
  background (0); 
  stroke(255);

  // show all stored lines 
  for (int i = 0; i < to.size(); i++) {
    PVector currentFrom = from.get(i);
    PVector currentTo = to.get(i);
    // the line 
    linePV ( currentFrom, 
      currentTo );
  }//for

  // we show current line 
  if (situation==1) {
    stroke(0, 255, 0); 
    linePV(from.get(from.size()-1), 
      new PVector(mouseX, mouseY));
  }
}//func 

// -------------------------------------------------------------------------
// Inputs 

void mousePressed() {
  // depending on situation we store mouse-position as "from" or as "to" point 
  if (situation==0) 
    from.add (new PVector (mouseX, mouseY));
  else if (situation==1)
    to.add (new PVector (mouseX, mouseY));

  // manage situation variable  
  situation++;
  if (situation>1)
    situation=0;
}//func

// -------------------------------------------------------------------------
// Tools 

void linePV ( PVector pv1, PVector pv2) {
  line(pv1.x, pv1.y, 
    pv2.x, pv2.y);
}//func 
//

```

---

<div class="post-metadata">

### Author: ![rajmb](https://avatars.discourse-cdn.com/v4/letter/r/f14d63/32.png) [@rajmb](https://discourse.processing.org/u/rajmb)
#### Post date: [October 21, 2020, 5:12am UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762/3 "2020-10-21T05:12:24Z")

</div>

Thank you Chrisir for your welcome and the prompt response. I was previously thinking of using PGraphics to store the last known image and paint over it with the new shape. But this is a great idea to use an ArrayList as it provides a way to create an Undo feature too - It does seem difficult as I need to distinguish the shape being drawn currently from all that has been drawn previously. Let me think thru the solution.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [October 21, 2020, 9:26am UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762/4 "2020-10-21T09:26:29Z")

</div>

> [@rajmb](#):
>
> It does seem difficult as I need to distinguish the shape being drawn currently from all that has been drawn

That’s not difficult.

Just draw the content of the ArrayList and on top the current moving ellipse.

* * *

**An idea**

What is more difficult:

to work with 2 parallel ArrayLists is cumbersome and error-prone. Instead you could make a class Ellipse with x,y and width and height and then let the ArrayList contain objects of that type:

`ArrayList<Ellipse> ellipses = new ArrayList();`

Then you can just store the data in the object of the class.

`ellipses.add(new Ellipse(x,y,w,h));`

There is a tutorial about objects. Please read it. [Objects / Processing.org](https://www.processing.org/tutorials/objects/)

Chrisir

---

<div class="post-metadata">

### Author: ![rajmb](https://avatars.discourse-cdn.com/v4/letter/r/f14d63/32.png) [@rajmb](https://discourse.processing.org/u/rajmb)
#### Post date: [October 21, 2020, 1:36pm UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762/5 "2020-10-21T13:36:00Z")

</div>

Thank you Chrisir once again. I have tried implementing the same here: [https://editor.p5js.org/rajmb502/sketches/0UB2fQ9t-](https://editor.p5js.org/rajmb502/sketches/0UB2fQ9t-)

But I think I am making some mistake as the ellipse does not stop drawing even when mouse is released. Trying to debug now.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [October 21, 2020, 1:40pm UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762/6 "2020-10-21T13:40:03Z")

</div>

in mousePressed say hold=true;

in mouseReleased say hold =false;

in mouseDragged run its content only when `if (hold==true)`

before setup say `boolean hold=false;`

---

<div class="post-metadata">

### Author: ![rajmb](https://avatars.discourse-cdn.com/v4/letter/r/f14d63/32.png) [@rajmb](https://discourse.processing.org/u/rajmb)
#### Post date: [October 21, 2020, 1:54pm UTC](https://discourse.processing.org/t/continuously-update-drawing-during-mousedragged/24762/7 "2020-10-21T13:54:41Z")

</div>

Thanks Chrisir. It is done and is working fine now 🙂

Pasting code here for other’s reference:

```auto
let penColor = '#ffffff';
let bgColor = '#000000';
let strokeWt = 4;
let globalX = 0;
let globalY = 0;
let arrayOfShapes = [];
let data;
let shape = 'ellipse';
let hold = false;
  
function setup() {
  createCanvas(400, 400);
  stroke(penColor);
  strokeWeight(strokeWt);
  noFill();
  frameRate(10);
}

function draw() {
  background(color(bgColor));
  if (arrayOfShapes != null) {
    for(let i = 0; i < arrayOfShapes.length;i++) {
          if (arrayOfShapes[i].tool == 'ellipse') { 
            ellipseMode(CORNERS); 
            ellipse(arrayOfShapes[i].x, arrayOfShapes[i].y, arrayOfShapes[i].px, arrayOfShapes[i].py); 
          }
    }
  }
}

function mouseReleased() {
  data = {x:globalX, y:globalY, px:pmouseX, py:pmouseY, foregroundColor:penColor.toString('#rrggbb'), sW:strokeWt, tool:shape};
  arrayOfShapes.push(data);
  hold = false;
}

function mouseDragged() {
  if (hold == true) {
    push();
    strokeWeight(strokeWt/2);
    ellipseMode(CORNERS);
    ellipse(globalX, globalY, mouseX, mouseY);
    pop();    
  }
}

function mousePressed() {
  if ((mouseX > 0) && (mouseY > 0)) {
    globalX = mouseX; 
    globalY = mouseY;    
    hold = true;
  }
}

```
