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.
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:
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?
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
// 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
//
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.
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.