Processing Drawing Application (GUI)

Processing Drawing Application (GUI)

This file describes to create a simple drawing application using Processing. This application includes basic drawing functionalities such as pen color and thickness selection, as well as options to undo and clear the canvas.

Overview of the Program

This drawing application uses the controlP5 library to create a user interface, including a color wheel, sliders, and buttons. The program allows users to draw on a canvas with the mouse and see their drawing in real-time.

Preparation

Enter the processing official website and download the processing application.


Download the installation package as shown in the picture, unzip and open the application.

The opened application interface is shown in the figure.

Before you begin, make sure you have installed the controlP5 library in the Processing IDE. You can install the controlP5 library via “Java” -> “Manage Modes” -> “Libraries”-> search the controlP5 library and install it.

Program Code

Here is the complete program code. Detailed explanations and comments will follow each section.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import controlP5.*;

ControlP5 cp5;
PGraphics canvas;
int currentColor = color(0);
float currentStrokeWeight = 4;
ArrayList<PImage> history = new ArrayList<PImage>();
int historyIndex = 0;

void setup() {
size(800, 600);
cp5 = new ControlP5(this);

canvas = createGraphics(width, height - 50);
canvas.beginDraw();
canvas.background(255);
canvas.endDraw();

// 创建GUI控件,并调整布局
cp5.addSlider("strokeWeight")
.setPosition(10, height - 70)
.setWidth(100)
.setRange(1, 20)
.setValue(4)
.getCaptionLabel().setColor(color(0)).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE);

cp5.addBang("Clear")
.setPosition(120, height - 70)
.setSize(50, 20)
.getCaptionLabel().setColor(color(0)).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE);

cp5.addBang("Undo")
.setPosition(180, height - 70)
.setSize(50, 20)
.getCaptionLabel().setColor(color(0)).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE);

cp5.addColorWheel("colorWheel", 240, height - 100, 80) // 调整位置和大小
.getCaptionLabel().setColor(color(0)).align(ControlP5.LEFT, ControlP5.BOTTOM_OUTSIDE);

saveHistory(); // 保存初始状态
}

void draw() {
background(255);
image(canvas, 0, 0);

// 绘制工具预览
fill(currentColor);
noStroke();
ellipse(mouseX, mouseY, currentStrokeWeight, currentStrokeWeight);
}

void mouseDragged() {
if (mouseY < height - 50) {
updateCanvas();
}
}

void updateCanvas() {
canvas.beginDraw();
canvas.stroke(currentColor);
canvas.strokeWeight(currentStrokeWeight);
canvas.line(mouseX, mouseY, pmouseX, pmouseY);
canvas.endDraw();
}

void clear() {
canvas.beginDraw();
canvas.background(255);
canvas.endDraw();
saveHistory();
}

void undo() {
if (historyIndex > 0) {
historyIndex--;
canvas = createGraphics(width, height - 50);
canvas.beginDraw();
canvas.image(history.get(historyIndex), 0, 0);
canvas.endDraw();
}
}

void saveHistory() {
if (historyIndex < history.size() - 1) {
history.subList(historyIndex, history.size()).clear();
}
PImage snapshot = canvas.get();
history.add(snapshot);
historyIndex = history.size() - 1;
}

void controlEvent(ControlEvent event) {
if (event.isFrom("colorWheel")) {
currentColor = color((int)event.getController().getValue());
} else if (event.getName().equals("Clear")) {
clear();
} else if (event.getName().equals("Undo")) {
undo();
} else if (event.getName().equals("strokeWeight")) {
currentStrokeWeight = event.getValue();
}
}

Initialization Settings (setup function)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void setup() {
size(800, 600); // Set window size
cp5 = new ControlP5(this); // Initialize controlP5

canvas = createGraphics(width, height - 50); // Create a canvas
canvas.beginDraw();
canvas.background(255); // Set the canvas background to white
canvas.endDraw();

// Create controls
// Including sliders, clear and undo buttons, color wheel
// ...

saveHistory(); // Save the initial canvas state
}
  • size(800, 600): Sets the size of the window.
  • createGraphics(width, height - 50): Creates a PGraphics object to be used as the canvas.
  • canvas.background(255): Sets the canvas background to white.

Drawing Loop (draw function)

1
2
3
4
5
6
7
8
9
void draw() {
background(255); // Set background color
image(canvas, 0, 0); // Display current canvas

// Show brush preview
fill(currentColor); // Set fill color
noStroke(); // No border
ellipse(mouseX, mouseY, currentStrokeWeight, currentStrokeWeight); // Draw a circle representing the brush size
}
  • background(255): Sets the window background to white on each draw.
  • image(canvas, 0, 0): Draws the current canvas content to the window.

Mouse Dragging Event Handling (mouseDragged function)

1
2
3
4
5
void mouseDragged() {
if (mouseY < height - 50) {
updateCanvas(); // Call the function to update the canvas
}
}
  • When the mouse is dragged within the canvas area, call the updateCanvas function to draw lines.

Update Canvas (updateCanvas function)

1
2
3
4
5
6
7
void updateCanvas() {
canvas.beginDraw();
canvas.stroke(currentColor); // Set brush color
canvas.strokeWeight(currentStrokeWeight); // Set brush thickness
canvas.line(mouseX, mouseY, pmouseX, pmouseY); // Draw a line
canvas.endDraw();
}
  • canvas.line(mouseX, mouseY, pmouseX, pmouseY): Draws a line on the canvas from the previous mouse position to the current position.

Clear the Canvas (clear function)

1
2
3
4
5
6
void clear() {
canvas.beginDraw();
canvas.background(255); // Reset the canvas background to white
canvas.endDraw();
saveHistory(); // Save the state
}

Undo Operation (undo function)

1
2
3
4
5
6
7
8
9
void undo() {
if (historyIndex > 0) {
historyIndex--;
canvas = createGraphics(width, height - 50);
canvas.beginDraw();
canvas.image(history.get(historyIndex), 0, 0); // Restore to the previous history state
canvas.endDraw();
}
}
  • Use the history array to save the historical states of the canvas. In the undo operation, we revert to the previous state.

Save History State (saveHistory function)

1
2
3
4
5
6
7
8
9
10
void saveHistory() {
if (historyIndex < history.size() - 1) {
history.subList(historyIndex, history.size()).clear();
}


PImage snapshot = canvas.get();
history.add(snapshot); // Save the current state to the history array
historyIndex = history.size() - 1;
}

Handle Control Events (controlEvent function)

1
2
3
4
void controlEvent(ControlEvent event) {
// Handle different control events such as color change, clear, undo, etc.
// ...
}
  • This function handles events from controlP5 controls, such as adjusting the brush color and thickness, and clear and undo operations.

Results Display

The GUI interface of the drawing program obtained through processing programming using the above code is as follows.

Try using it to draw a picture.

Conclusion

Developing this Processing drawing application was an enlightening and creative experience. It demonstrated how to utilize Processing’s fundamental capabilities for real-time drawing and user interaction, providing an intuitive understanding of the basics of computer graphics and interface design.By integrating the controlP5 library, the project revealed the potential of incorporating external libraries into the Processing environment to enhance functionality. Overall, the development process of this drawing application was enjoyable and educational, showcasing the immense potential of programming as a creative tool.


Processing Drawing Application (GUI)
https://nexmaker-fab.github.io/2023zjude-10-36/2023/12/31/processingGUI/
Author
Chenye Meng
Posted on
December 31, 2023
Licensed under