-
-
Notifications
You must be signed in to change notification settings - Fork 480
/
Copy pathinteractivity.hbs
829 lines (747 loc) · 41.6 KB
/
interactivity.hbs
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
---
title: learn
slug: learn/
---
<div class="column-span">
<div id="learn-page">
<main >
<div class="attribution">
This is based on the Interactivity chapter from the second edition of<em>
<a href="https://processing.org/handbook/">Processing: A Programming Handbook for Visual Designers and Artists</a></em>, published by MIT Press. Copyright 2013 MIT Press. This tutorial was originally written for Processing version 2.0+ but has been ported and updated here for P5 by Alex Yixuan Xu. If you see any errors or have comments, please
<a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
</div>
<h1>Interactivity</h1>
<p>The screen forms a bridge between our bodies and the realm of circuits and electricity inside computers. We control elements on screen through a variety of devices such as touch pads, trackballs, and joysticks, but the keyboard and mouse remain the most common input devices for desktop computers. The computer mouse dates back to the late 1960s, when Douglas Engelbart presented the device as an element of the oN-Line System (NLS), one of the first computer systems with a video display. The mouse concept was further developed at the Xerox Palo Alto Research Center (PARC), but its introduction with the Apple Macintosh in 1984 was the catalyst for its current ubiquity. The design of the mouse has gone through many revisions in the last forty years, but its function has remained the same. In Engelbart's original patent application in 1970 he referred to the mouse as an "X-Y position indicator," and this still accurately, but dryly, defines its contemporary use.</p>
<p>The physical mouse object is used to control the position of the cursor on screen and to select interface elements. The cursor position is read by computer programs as two numbers, the x-coordinate and the y-coordinate. These numbers can be used to control attributes of elements on screen. If these coordinates are collected and analyzed, they can be used to extract higher-level information such as the speed and direction of the mouse. This data can in turn be used for gesture and pattern recognition.</p>
<p>Keyboards are typically used to input characters for composing documents, email, and instant messages, but the keyboard has potential for use beyond its original intent. The migration of the keyboard from typewriter to computer expanded its function to enable launching software, moving through the menus of software applications, and navigating 3D environments in games. When writing your own software, you have the freedom to use the keyboard data any way you wish. For example, basic information such as the speed and rhythm of the fingers can be determined by the rate at which keys are pressed. This information could control the speed of an event or the quality of motion. It's also possible to ignore the characters printed on the keyboard itself and use the location of each key relative to the keyboard grid as a numeric position.</p>
<p>The modern computer keyboard is a direct descendant of the typewriter. The position of the keys on an English-language keyboard is inherited from early typewriters. This layout is called QWERTY because of the order of the top row of letter keys. It was developed for typewriters to put physical distance between frequently typed letter pairs, helping reduce the likelihood of the typebars colliding and jamming as they hit the ribbon. This more than one-hundred-year-old mechanical legacy still affects how we write software today.</p>
<h2>Mouse Data</h2>
<p>The variables <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> (note the capital X and Y) store the x-coordinate and y-coordinate of the cursor relative to the origin in the upper-left corner of the display window. To see the actual values produced while moving the mouse, run this program to print the values to the screen:</p>
<!-- this script only needs to get added once even if there are multiple widget instances -->
<script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function draw() {
background(255);
frameRate(12);
text("X: "+mouseX, 0, height/4);
text("Y: "+mouseY, 0, height/2);
}
</script>
<p>When a program starts, the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> values are 0. If the cursor moves into the display window, the values are set to the current position of the cursor. If the cursor is at the left, the mouseX value is 0 and the value increases as the cursor moves to the right. If the cursor is at the top, the mouseY value is 0 and the value increases as the cursor moves down. If mouseX and mouseY are used in programs without a <a href="/reference/#/p5/draw"> draw()</a> or if <a href="/reference/#/p5/noLoop">noLoop()</a> is run in <a href="/reference/#/p5/setup">setup()</a>, the values will always be 0.</p>
<p>The mouse position is most commonly used to control the location of visual elements on screen. More interesting relations are created when the visual elements relate differently to the mouse values, rather than simply mimicking the current position. Adding and subtracting values from the mouse position creates relationships that remain constant, while multiplying and dividing these values creates changing visual relationships between the mouse position and the elements on the screen. In the first of the following examples, the circle is directly mapped to the cursor, in the second, numbers are added and subtracted from the cursor position to create offsets, and in the third, multiplication and division are used to scale the offsets.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
}
function draw() {
background(126);
ellipse(mouseX, mouseY, 33, 33);
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
}
function draw() {
background(126);
ellipse(mouseX, 16, 33, 33); // Top circle
ellipse(mouseX+20, 50, 33, 33); // Middle circle
ellipse(mouseX-20, 84, 33, 33); // Bottom circle
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
}
function draw() {
background(126);
ellipse(mouseX, 16, 33, 33); // Top circle
ellipse(mouseX/2, 50, 33, 33); // Middle circle
ellipse(mouseX*2, 84, 33, 33); // Bottom circle
}
</script>
<p>To invert the value of the mouse, subtract the mouseX value from the width of the window and subtract the mouseY value from the height of the screen.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
}
function draw() {
let x = mouseX;
let y = mouseY;
let ix = width - mouseX; // Inverse X
let iy = height - mouseY; // Inverse Y
background(126);
fill(255, 150);
ellipse(x, height/2, y, y);
fill(0, 159);
ellipse(ix, height/2, iy, iy);
}
</script>
<p>The variables <a href="/reference/#/p5/pmouseX">pmouseX</a> and <a href="/reference/#/p5/pmouseY">pmouseY</a> store the mouse values from the previous frame. If the mouse does not move, the values will be the same, but if the mouse is moving quickly there can be large differences between the values. To see the difference, run the following program and alternate moving the mouse slowly and quickly. Watch the values print to the screen.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function draw() {
background(255);
frameRate(12);
text(pmouseX - mouseX, 0, height/4);
}
</script>
<p>Draw a line from the previous mouse position to the current position to show the changing position in one frame and reveal the speed and direction of the mouse. When the mouse is not moving, a point is drawn, but quick mouse movements create long lines.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
strokeWeight(8);
}
function draw() {
background(204);
line(mouseX, mouseY, pmouseX, pmouseY);
}
</script>
<p>Use the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables with an if structure to allow the cursor to select regions of the screen. The following examples demonstrate the cursor making a selection between different areas of the display window. The first divides the screen into halves, and the second divides the screen into thirds.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
fill(0);
}
function draw() {
background(204);
if (mouseX < 50) {
rect(0, 0, 50, 100); // Left
}
else {
rect(50, 0, 50, 100); // Right
}
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
fill(0);
}
function draw() {
background(204);
if (mouseX < 33) {
rect(0, 0, 33, 100); // Left
}
else if (mouseX < 66) {
rect(33, 0, 33, 100); // Middle
}
else {
rect(66, 0, 33, 100); // Right
}
}
</script>
<p>Use the logical operator && with an if structure to select a rectangular region of the screen. As demonstrated in the following example, when a relational expression is made to test each edge of a rectangle (left, right, top, bottom) and these are concatenated with a logical AND, the entire relational expression is true only when the cursor is inside the rectangle.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
fill(0);
}
function draw() {
background(204);
if ((mouseX > 40) && (mouseX < 80) && (mouseY > 20) && (mouseY < 80)){
fill(255);
}
else {
fill(0);
}
rect(40, 20, 40, 60);
}
</script>
<p>This code asks, "Is the cursor to the right of the left edge and is the cursor to the left of the right edge and is the cursor beyond the top edge and is the cursor above the bottom?" The code for the next example asks a set of similar questions and combines them with the keyword else to determine which one of the defined areas contains the cursor.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
fill(0);
}
function draw() {
background(204);
if ((mouseX <= 50) && (mouseY <= 50)) {
rect(0, 0, 50, 50); // Upper-left
}
else if ((mouseX <= 50) && (mouseY > 50)) {
rect(0, 50, 50, 50); // Lower-left
}
else if ((mouseX > 50) && (mouseY <= 50)) {
rect(50, 0, 50, 50); // Upper-right
}
else {
rect(50, 50, 50, 50); // Lower-right
}
}
</script>
<h2>Mouse buttons</h2>
<p>Computer mice and other related input devices typically have between one and three buttons; p5 can detect when these buttons are pressed with the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> and <a href="/reference/#/p5/mouseButton">mouseButton</a> variables. Used with the button status, the cursor position enables the mouse to perform different actions. For example, a button press when the mouse is over an icon can select it, so the icon can be moved to a different location on screen. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true if any mouse button is pressed and false if no mouse button is pressed. The variable <a href="/reference/#/p5/mouseButton">mouseButton</a> is LEFT, CENTER, or RIGHT depending on the mouse button most recently pressed. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable reverts to false as soon as the button is released, but the <a href="/reference/#/p5/mouseButton">mouseButton</a> variable retains its value until a different button is pressed. These variables can be used independently or in combination to control the software. Run these programs to see how the software responds to your fingers.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
fill(0);
}
function draw() {
background(204);
if (mouseIsPressed == true) {
fill(255); // White
}
else {
fill(0); // Black
}
rect(25, 25, 50, 50);
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
fill(0);
}
function draw() {
background(204);
if (mouseButton == LEFT) {
fill(0); // Black
}
else if (mouseButton == RIGHT) {
fill(255); // White
}
else {
fill(126); // Gray
}
rect(40, 20, 40, 60);
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noStroke();
fill(0);
}
function draw() {
background(204);
if (mouseIsPressed == true) {
if (mouseButton == LEFT) {
fill(0); // Black
}
else if (mouseButton == RIGHT) {
fill(255); // White
}
}
else {
fill(126); // Gray
}
rect(40, 20, 40, 60);
}
</script>
<p>Not all mice have multiple buttons, and if software is distributed widely, the interaction should not rely on detecting which button is pressed.</p>
<h2>Keyboard data</h2>
<p>p5 registers the most recently pressed key and whether a key is currently pressed. The boolean variable <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> is true if a key is pressed and is false if not. Include this variable in the test of an if structure to allow lines of code to run only if a key is pressed. The <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable remains true while the key is held down and becomes false only when the key is released.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
strokeWeight(4);
}
function draw() {
background(204);
if (keyIsPressed == true) { // If the key is pressed,
line(20, 20, 80, 80); // draw a line;
}
else { // Otherwise,
rect(40, 40, 20, 20); // draw a rectangle.
}
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let x = 20;
function setup() {
createCanvas(100, 100);
strokeWeight(4);
}
function draw() {
background(204);
if (keyIsPressed == true) { // If the key is pressed,
x++; // add 1 to x.
}
line(x, 20, x-60, 80);
}
</script>
<!-- made changes about the key variable not guaranteed to be case sensitive in p5 -->
<p>The <a href="/reference/#/p5/key">key</a> variable stores a single alphanumeric character. Specifically, it holds the most recently pressed key. However, it is not guaranteed to be case sensitive. To get the proper capitalization, it is best to use it within <a href="/reference/#/p5/keyTyped">keyTyped()</a>. For non-ASCII keys, use the <a href="/reference/#/p5/keyCode">keyCode</a> variable. The key can be displayed on screen with the <a href="/reference/#/p5/text">text()</a> function (p. 150).</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
textSize(60);
fill(255);
}
function draw() {
background(0);
text(key, 20, 75); // Draw at coordinate (20,75)
}
</script>
<!-- no differences in "" and '' in p5, made changes -->
<!-- <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. The single quotes signify A as the data type char (p. 144). The expression key == "A" will cause an error because the double quotes signify the A as a String, and it's not possible to compare a String with a char. The logical AND symbol, the && operator, is used to connect the expression with the <a href="/reference/#/p5/keyPressed">keyPressed</a> variable to ascertain that the key pressed is the uppercase A.</p> -->
<p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. Note the use of double quotation marks or single quotation marks has no influence on the program as long as you are consistent. The logical AND symbol, the && operator, is used to connect the expression with the <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable to ascertain that the key pressed is the uppercase A.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
strokeWeight(4);
stroke(255);
}
function draw() {
background(0);
// If the 'A' key is pressed, draw a line
if ((keyIsPressed == true) && (key == 'A')) {
line(50, 25, 50, 75);
}
else { // Otherwise, draw an ellipse
ellipse(50, 50, 50, 50);
}
}
</script>
<p>The previous example works with an uppercase A, but not if the lowercase letter is pressed. To check for both uppercase and lowercase letters, extend the relational expression with a logical OR, the || relational operator. Line 9 in the previous program would be changed to:</p>
<pre><code class="language-javascript">
if ((keyIsPressed == true) && ((key == 'a') || (key == 'A'))) {
</code></pre>
<!-- changes made -->
<h2>Coded keys</h2>
<p>Because each character has a numeric value as defined by the <a href="https://www.w3schools.com/charsets/ref_html_ascii.asp">ASCII table</a>, the value of the <a href="/reference/#/p5/keyCode">keyCode</a> variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
stroke(0);
}
function draw() {
if (keyIsPressed === true) {
let x = keyCode - 32;
line(x, 0, x, height);
}
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let angle = 0;
function setup() {
createCanvas(100, 100);
stroke(0);
}
function draw() {
background(204);
if (keyIsPressed === true) {
if ((keyCode >= 32) && (keyCode <= 126)) {
// If the key is alphanumeric, // use its value as an angle
angle = (keyCode - 32) * 3;
}
}
arc(50, 50, 66, 66, 0, radians(angle));
}
</script>
<p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let y = 35;
function setup() {
createCanvas(100, 100);
stroke(0);
}
function draw() {
background(204);
line(10, 50, 90, 50);
if (keyCode == UP_ARROW) {
y = 20;
}
else if (keyCode == DOWN_ARROW) {
y = 50;
}
else {
y = 35;
}
rect(25, y, 50, 30);
}
</script>
<!--made changes to original content here -->
<!-- <p>Because each character has a numeric value as defined by the ASCII table (p. 605), the value of the key variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
stroke(0);
}
function draw() {
if (keyIsPressed === true) {
let x = keyCode - 32;
line(x, 0, x, height);
}
}
</script>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let angle = 0;
function setup() {
createCanvas(100, 100);
stroke(0);
}
function draw() {
background(204);
if (keyIsPressed === true) {
if ((keyCode >= 32) && (keyCode <= 126)) {
// If the key is alphanumeric, // use its value as an angle
angle = (keyCode - 32) * 3;
}
}
arc(50, 50, 66, 66, 0, radians(angle));
}
</script>
<h2>Coded keys</h2>
<p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let y = 35;
function setup() {
createCanvas(100, 100);
stroke(0);
}
function draw() {
background(204);
line(10, 50, 90, 50);
if (keyCode == UP_ARROW) {
y = 20;
}
else if (keyCode == DOWN_ARROW) {
y = 50;
}
else {
y = 35;
}
rect(25, y, 50, 30);
}
</script> -->
<h2>Events</h2>
<p>A category of functions called events alter the normal flow of a program when an action such as a key press or mouse movement takes place. An event is a polite interruption of the normal flow of a program. Key presses and mouse movements are stored until the end of <a href="/reference/#/p5/draw">draw()</a>, where they can take action that won't disturb drawing that's currently in progress. The code inside an event function is run once each time the corresponding event occurs. For example, if a mouse button is pressed, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function will run once and will not run again until the button is pressed again. This allows data produced by the mouse and keyboard to be read independently from what is happening in the rest of the program.</p>
<h2>Mouse events</h2>
<!-- added mouseClicked() mouseOver() mouseOut() doubleClicked()-->
<p>The mouse event functions are <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, <a href="/reference/#/p5/mouseDragged">mouseDragged()</a>, <a href="/reference/#/p5/mouseOver">mouseOver()</a>, and <a href="/reference/#/p5/mouseOut">mouseOut()</a>:</p>
<ul class="list_view">
<li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
<li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
<li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
<li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
<li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
<li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block is run one time when the mouse is moved while a mouse button is pressed</li>
<li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
<li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
</ul>
<p>The <a href="/reference/#/p5/mousePressed">mousePressed()</a> function works differently than the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable. The value of the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true until the mouse button is released. It can therefore be used within <a href="/reference/#/p5/draw">draw()</a> to have a line of code run while the mouse is pressed. In contrast, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function only runs once when a button is pressed. This makes it useful when a mouse click is used to trigger an action, such as clearing the screen. In the following example, the background value becomes lighter each time a mouse button is pressed. Run the example on your computer to see the change in response to your finger.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let gray = 0;
function setup() {
createCanvas(100, 100);
}
function draw() {
background(gray);
}
function mousePressed() {
gray += 20;
}
</script>
<p>The following example is the same as the one above, but the gray variable is set in the <a href="/reference/#/p5/mouseReleased">mouseReleased()</a> event function, which is called once every time a button is released. This difference can be seen only by running the program and clicking the mouse button. Keep the mouse button pressed for a long time and notice that the background value changes only when the button is released.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let gray = 0;
function setup() {
createCanvas(100, 100);
}
function draw() {
background(gray);
}
function mouseReleased() {
gray += 20;
}
</script>
<!-- mouseClicked() example added-->
<p>Similarly, the gray variable is set in the <a href="/reference/#/p5/mouseClicked">mouseClicked()</a> event function, which is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, use <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>. </p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let gray = 0;
function setup() {
createCanvas(100, 100);
}
function draw() {
background(gray);
}
function mouseClicked() {
gray += 20;
}
</script>
<p>It is generally not a good idea to draw inside an event function, but it can be done under certain conditions. Before drawing inside these functions, it's important to think about the flow of the program. In this example, squares are drawn inside <a href="/reference/#/p5/mousePressed">mousePressed()</a> and they remain on screen because there is no <a href="/reference/#/p5/background">background()</a> inside <a href="/reference/#/p5/draw">draw()</a>. But if <a href="/reference/#/p5/background">background()</a> is used, visual elements drawn within one of the mouse event functions will appear on screen for only a single frame, or, by default, 1/60th of a second. In fact, you'll notice this example has nothing at all inside <a href="/reference/#/p5/draw">draw()</a>, but it needs to be there to force P5 to keep listening for the events. If a <a href="/reference/#/p5/background">background()</a> function were run inside <a href="/reference/#/p5/draw">draw()</a>, the rectangles would flash onto the screen and disappear.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
fill(0, 102);
background(204); // Draw once to give a little color
}
function draw() {
} // Empty draw() keeps the program running
function mousePressed() {
rect(mouseX, mouseY, 33, 33);
}
</script>
<p>The code inside the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> and <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> event functions are run when there is a change in the mouse position. The code in the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> block is run at the end of each frame when the mouse moves and no button is pressed. The code in the <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> block does the same when the mouse button is pressed. If the mouse stays in the same position from frame to frame, the code inside these functions does not run. In this example, the gray circle follows the mouse when the button is not pressed, and the black circle follows the mouse when a mouse button is pressed.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let dragX, dragY, moveX, moveY;
function setup() {
createCanvas(100, 100);
noStroke();
}
function draw() {
background(204);
fill(0);
ellipse(dragX, dragY, 33, 33); // Black circle
fill(153);
ellipse(moveX, moveY, 33, 33); // Gray circle
}
function mouseMoved() { // Move gray circle
moveX = mouseX;
moveY = mouseY;
}
function mouseDragged() { // Move black circle
dragX = mouseX;
dragY = mouseY;
}
</script>
<!-- examples added for mouseOut() and mouseOver() -->
<p>The <a href="/reference/#/p5/mouseOver">.mouseOver()</a> function is called once after every time a mouse moves onto the element. In this example, the diameter of the ellipse increase by 10 every time the mouse moves onto the canvas.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let cnv;
let d;
function setup() {
cnv = createCanvas(100, 100);
cnv.mouseOver(changeD);
d = 10;
}
function draw() {
ellipse(width / 2, height / 2, d, d);
}
function changeD() {
d = d + 10;
}
</script>
<p>The <a href="/reference/#/p5/mouseOut">.mouseOut()</a> function is called once after every time a mouse moves off the element. Similar to the above example, the diameter of the ellipse increase by 10 every time the mouse moves out of the canvas.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let cnv;
let d;
function setup() {
cnv = createCanvas(100, 100);
cnv.mouseOut(changeD);
d = 10;
}
function draw() {
ellipse(width / 2, height / 2, d, d);
}
function changeD() {
d = d + 10;
}
</script>
<h2>Wheel Events</h2>
<p>The <a href="/reference/#/p5/mouseWheel">.mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners. The function accepts a callback function as argument which will be executed when the wheel event is triggered on the element. The <a href="/reference/#/p5/deltaY">event.deltaY</a> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <a href="/reference/#/p5/deltaX">event.deltaX</a> does the same as <a href="/reference/#/p5/deltaY">event.deltaY</a> except it reads the horizontal wheel scroll of the mouse wheel. On OS X with "natural" scrolling enabled, the <a href="/reference/#/p5/deltaY">event.deltaY</a> values are reversed.</p>
<p>In this example, an event listener is attached to the canvas element, and function changeSize() would run when scrolling is performed on canvas. By using the <a href="/reference/#/p5/deltaY">event.deltaY</a> variable, scrolling up on canvas would increase the diameter of the ellipse and scrolling down would decrease the diameter. If scrolling is performed anywhere in any direction, the background is going to be darker.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let cnv;
let d;
let g;
function setup() {
cnv = createCanvas(100, 100);
cnv.mouseWheel(changeSize); // attach listener for activity on canvas only
d = 10;
g = 100;
}
function draw() {
background(g);
ellipse(width / 2, height / 2, d, d);
}
// this function fires with mousewheel movement anywhere on screen
function mouseWheel() {
g = g + 10;
}
// this function fires with mousewheel movement over canvas only
function changeSize(event) {
if (event.deltaY > 0) {
d = d + 10;
}
else {
d = d - 10;
}
}
</script>
<h2>Key events</h2>
<!-- keyTyped() added -->
<p>Each key press is registered through the keyboard event functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyPressed">keyTyped()</a> and <a href="/reference/#/p5/keyReleased">keyReleased()</a>:</p>
<ul class="list_view">
<li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block is run one time when any key is pressed</li>
<li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is run one time when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
<li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is run one time when any key is released</li>
</ul>
<p>Each time a key is pressed, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block is run once. Within this block, it's possible to test which key has been pressed and to use this value for any purpose. If a key is held down for an extended time, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block might run many times in a rapid succession because most operating systems will take over and repeatedly call the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. The amount of time it takes to start repeating and the rate of repetitions will be different from computer to computer, depending on the keyboard preference settings. In this example, the value of the boolean variable drawT is set from false to true when the T key is pressed; this causes the lines of code to render the rectangles in <a href="/reference/#/p5/draw">draw()</a> to start running.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let drawT = false;
function setup() {
createCanvas(100, 100);
noStroke();
}
function draw() {
background(204);
if (drawT == true) {
rect(20, 20, 60, 20);
rect(39, 40, 22, 45);
}
}
function keyPressed() {
if ((key == 'T') || (key == 't')) {
drawT = true;
}
}
</script>
<!-- added this information to distinguish keyPressed() and keyTyped() -->
<p>When ASCII keys are pressed, the character is stored in the <a href="https://p5js.org/reference/#/p5/key">key </a>variable. However, this variable does not distinguish between uppercase and lowercase when used with the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. For this reason, it is recommended to use <a href="/reference/#/p5/keyTyped">keyTyped()</a>. When used with the <a href="/reference/#/p5/key">key</a> variable this function will recognize case. </p>
<p>Each time a key is released, the code inside the <a href="/reference/#/p5/keyReleased">keyReleased()</a> block is run once. The following example builds on the previous code; each time the key is released the boolean variable drawT is set back to false to stop the shape from displaying within <a href="/reference/#/p5/draw">draw()</a>.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let drawT = false;
function setup() {
createCanvas(100, 100);
noStroke();
}
function draw() {
background(204);
if (drawT == true) {
rect(20, 20, 60, 20);
rect(39, 40, 22, 45);
}
}
function keyPressed() {
if ((key == 'T') || (key == 't')) {
drawT = true;
}
}
function keyReleased() {
drawT = false;
}
</script>
<h2>Event flow</h2>
<p>As discussed previously, programs written with <a href="/reference/#/p5/draw">draw()</a> display frames to the screen sixty frames each second. The <a href="/reference/#/p5/frameRate">frameRate()</a> function is used to set a limit on the number of frames that will display each second, and the <a href="/reference/#/p5/noLoop">noLoop()</a> function can be used to stop draw() from looping. The additional functions <a href="/reference/#/p5/loop">loop()</a> and <a href="/reference/#/p5/redraw">redraw()</a> provide more options when used in combination with the mouse and keyboard event functions. If a program has been paused with <a href="/reference/#/p5/noLoop">noLoop()</a>, running <a href="/reference/#/p5/loop">loop()</a> resumes its action. Because the event functions are the only elements that continue to run when a program is paused with noLoop(), the loop() function can be used within these events to continue running the code in draw(). The following example runs the draw() function for about two seconds each time a mouse button is pressed and then pauses the program after that time has elapsed.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let frame = 0;
function setup() {
createCanvas(100, 100);
}
function draw() {
if (frame > 120) { // If 120 frames since the mouse
noLoop(); // was pressed, stop the program
background(0); // and turn the background black.
}
else { // Otherwise, set the background
background(204); // to light gray and draw lines
line(mouseX, 0, mouseX, 100); // at the mouse position
line(0, mouseY, 100, mouseY);
frame++;
}
}
function mousePressed() {
frame = 0;
loop();
}
</script>
<p>The <a href="/reference/#/p5/redraw">redraw()</a> function runs the code in draw() one time and then halts the execution. It's helpful when the display needn't be updated continuously. The following example runs the code in draw() once each time a mouse button is pressed.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noLoop();
}
function draw() {
background(204);
line(mouseX, 0, mouseX, 100);
line(0, mouseY, 100, mouseY);
}
function mousePressed() {
redraw(); // Run the code in draw one time
}
</script>
<!-- event listener and callback functions explained??? -->
<!-- This should probably be explained in a another tutorial more in-depth -->
<!-- Functions like mousePressed(), mouseClicked(), mouseReleased(), mouseMoved(), mouseOver(), and mouseOut() can be used as event listeners. They can be attached to certain elements</p>
<p>Function|Boolean: function to be fired when mouse is pressed over the element. if false is passed instead, the previously firing function will no longer fire.</p>
<p>In this example</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
let cnv;
let d;
let g;
function setup() {
cnv = createCanvas(100, 100);
cnv.mousePressed(changeGray); // attach listener for canvas click only
d = 10;
g = 100;
}
function draw() {
background(g);
ellipse(width / 2, height / 2, d, d);
}
// this function fires with any click anywhere
function mousePressed() {
d = d + 10;
}
// this function fires only when cnv is clicked
function changeGray() {
g = random(0, 255);
}
</script>
-->
<h2>Cursor icon</h2>
<p>The cursor can be hidden with the <a href="/reference/#/p5/noCursor">noCursor()</a> function and can be set to appear as a different icon or image with the <a href="/reference/#/p5/cursor">cursor()</a> function. When the noCursor() function is run, the cursor icon disappears as it moves into the display window. To give feedback about the location of the cursor within the software, a custom cursor can be drawn and controlled with the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
strokeWeight(7);
noCursor();
}
function draw() {
background(204);
ellipse(mouseX, mouseY, 10, 10);
}
</script>
<p>If <a href="/reference/#/p5/noCursor">noCursor()</a> is run, the cursor will be hidden while the program is running until the <a href="/reference/#/p5/cursor">cursor()</a> function is run to reveal it.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
}
function draw() {
background(204);
if (mouseIsPressed == true) {
cursor();
}
else {
noCursor();
}
}
</script>
<p>Add a parameter to the cursor() function to change it to another icon or image. Either load and use image, or use the self-descriptive options are ARROW, CROSS, HAND, MOVE, TEXT, and WAIT.</p>
<script type="text/p5" data-autoplay data-p5-version="{{ version }}">
function setup() {
createCanvas(100, 100);
noCursor();
}
function draw() {
background(204);
if (mouseIsPressed == true) {
cursor(HAND); // Draw cursor as hand
}
else {
cursor(CROSS); // Draw cursor as cross
}
line(mouseX, 0, mouseX, height);
line(0, mouseY, height, mouseY);
}
</script>
<p>These cursor icons are part of your computer's operating system and will appear different on different machines.</p>
</main>
{{> footer}}
</div>
<!-- end column-span -->
{{> asterisk}}
</div>
<!-- end id="get-started-page" -->