We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm trying to build a Drawing Program using Processing. I am currently stuck on using PGrapchics.
When the user draws a rectangle, it shows the shape being drawn. When the user releases their mouse, it then creates a PGraphic of the final shape. I would then like the user to draw on top of that. Here is my problem:
I had to reset the background of the canvas when drawing a rectangle because otherwise, it shows a trail of rectangles. The result is that while the user draws a new rectangle the old ones disappear and come back once the mouse has been releasd
Some thoughts: I would also like to add features where the user can select on a previously drawn rectangle and change it's colour, stroke, send to back, bring to front etc..
To achieve this, I'm storing all drawn rectangles (PGraphics) into an ArrayList which will be drawn via a for loop. This will allow me to adjust the behaviour by moving the PGraphics elements up and down the ArrayList.
QUESTIONS: Is this correct or should I be creating an ArrayList of rectangles? Instead of creating my own class of Shape am I better off using PShape?
int startX;
int startY;
int endX;
int endY;
boolean drawing;
int strokeW = 3;
Shape shape;
PGraphics shapeLayer;
ArrayList<PGraphics> layersList = new ArrayList();
void setup() {
size(500, 500);
cursor(CROSS);
background(255);
smooth();
}
void draw() {
strokeWeight(strokeW);
if (key >= '0' && key <= '9') {
strokeW = key - '0';
}
for(int i = 0; i < layersList.size(); i++) {
image(layersList.get(i), 0, 0);
}
if (drawing) {
shape.createRectangle();
}
}
void mousePressed() {
startX = mouseX;
startY = mouseY;
shapeLayer = createGraphics(width, height);
shapeLayer.beginDraw();
}
void mouseDragged() {
drawing = true;
endX = constrain(mouseX, 0, 500);
endY = constrain(mouseY, 0, 500);
shape = new Shape(startX, startY, endX, endY);
shapeLayer.clear();
}
void mouseReleased() {
drawing = false;
shapeLayer.endDraw();
layersList.add(shapeLayer);
}
Here is the Shape Class:
class Shape {
int startX;
int startY;
int endX;
int endY;
Shape(int x1, int y1, int x2, int y2) {
startX = x1;
startY = y1;
endX = x2;
endY = y2;
}
void createRectangle() {
background(255, 0);
shapeLayer.strokeWeight(strokeW);
shapeLayer.rectMode(CORNERS);
shapeLayer.rect(startX, startY, endX, endY);
rectMode(CORNERS);
rect(startX, startY, endX, endY);
}
}
Answers
I use a similar technique in my Layers program.
See https://forum.processing.org/two/discussion/20926/layers-a-sketch-for-painting-updated-13-march-2017#latest
My goodness, that program is beautiful. Unfortunately it's a little too complicated for my understanding
Would you be drawing only rectangles or will you drawing other shapes? If the latter, then having an array of PGraphics is better as it will provide you with more power at the end although the amount of work to implement will be equivalent. Now, do you also want to manage layers? I envision a layer to be a group of PGraphics. That is a good feature to consider as well.
I agree with you @codeav3. @cameyo did a really good job there!
Kf
@kfrajer i will be drawing other shapes too - should I keep my custom Shape class or use the PShape? I would like to manage the layers by moving some in front of others when the user presses a particular key. e.g. if the user clicks on a shape already drawn and then presses 'b', it sends it back one layer.
I think in your case you will need either a custom shape class or just work with PGraphics objects. A custom shape class is required as you need to keep track of stroke color and weight as well as fill parameters. If after you draw the shape, you think it the shape will not change, then a PGraphics could be an alternative and a better option. Are you familiar with PGraphics? With PGraphics you don't need to keep track of parameters. You will just draw on them and it has a transparent background to start. When you are done, you can place it anywhere in your sketch. You can also re-scale it or apply filters to it. In order to manage top and bottom figures, it will be as simple as deciding which PGraphics should be drawn first. The first object draw will be the one that is at the bottom of overlapping PGraphics.
Kf