Skip to content

Transition guide for using mouse/touch events from 1.x to 2.x. #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 158 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ All of the above usages in p5.js 1.x remain available with the [preload.js](http

## …using registerPreloadMethod in an add-on libraries

Under to hood, returns a **Promise** from each loadImage, loadSound, and similar functions. Promises are widely used in JavaScript, so it is possible to use a callback in p5.js 1.x to create a Promise, but p5.js 1.x doesn't expect promises to be used, so you have to ensure yourself that, for example, your draw function doesn't start running before loading is done. For an example of a Promise using a callback, check out the example below that makes p5.sound.js compatible with both 1.x and 2.0:
Under the hood, returns a **Promise** from each loadImage, loadSound, and similar functions. Promises are widely used in JavaScript, so it is possible to use a callback in p5.js 1.x to create a Promise, but p5.js 1.x doesn't expect promises to be used, so you have to ensure yourself that, for example, your draw function doesn't start running before loading is done. For an example of a Promise using a callback, check out the example below that makes p5.sound.js compatible with both 1.x and 2.0:

If your add-on library built with p5.js 1.x uses `registerPreloadMethod` such as in this example from [p5.sound.js](https://github.com/processing/p5.sound.js):

Expand Down Expand Up @@ -431,3 +431,160 @@ Finally, touch and mouse event handling has been combined to improve sketch cons
In p5.js 2.0, instead of having separate methods for mouse and touch, we now use the browser's pointer API to handle both simultaneously. Try defining mouse functions as usual and accessing the global touches array to see what pointers are active for multitouch support!

All of the above usages in p5.js 1.x remain available with the [data.js](https://github.com/processing/p5.js-compatibility/blob/main/src/data.js) compatibility add-on library.

## …using mouseButton

In 2.X, the `mouseButton` is now an object with props: `left`, `right` and `center`, which are booleans indicating whether each button has been pressed respectively.

```js
function setup() {
createCanvas(100, 100);

describe(
"A gray square. Different shapes appear at its center depending on the mouse button that's clicked."
);
}
```

<table>
<tr><th>p5.js 1.x</th><th>p5.js 2.x</th></tr>
<tr><td>

```js
function draw() {
background(200);

if (mouseIsPressed === true) {
if (mouseButton === LEFT) {
circle(50, 50, 50);
}
if (mouseButton === RIGHT) {
square(25, 25, 50);
}
if (mouseButton === CENTER) {
triangle(23, 75, 50, 20, 78, 75);
}
}
}
```

</td><td>


```js
function draw() {
background(200);

if (mouseIsPressed === true) {
if (mouseButton.left) {
circle(50, 50, 50);
}
if (mouseButton.right) {
square(25, 25, 50);
}
if (mouseButton.center) {
triangle(23, 75, 50, 20, 78, 75);
}
}
}
```

</td></tr>
</table>

## …using keyCode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here: minor suggestion to add "events" to the heading

`keyCode` is still a `Number` system variable in 2.x.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could benefit from an introduction. The important message here is that: "In 2.x, p5.js introduces code as a way to get keyboard information. This is a string that reflects the physical key, like ArrowLeft or keyF. The values of this variable are based on KeyboardEvent.code. This additional also included some changes to how key and keyCode can be used, compared to 1.x"

Maybe the table I suggested below could be useful here?

```js
if (keyCode === 13) {
// Code to run if the enter key was pressed.
}
```

However, system variables like "ENTER" cannot be used like in 1.x, for example:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System variables remain, but they can be used with code. Eg., this would work: if (key === ENTER) {

```js
if (keyCode === ENTER) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really confusing change for many people, so I wonder if it would be useful to make something like a table:

variable p5.js 1.x p5.js 2.x
key Text String (e.g.: "ArrowUp") Text String (e.g.: "ArrowUp", "f" or "F")
code Not supported Text String (e.g.: "ArrowUp", "KeyF")
keyCode Number Number (e.g., 70)
System variables Number Text String (e.g: "ArrowUp")

All the system variables are still supported: BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW

The difference between key and code is that the key reflects the value: for example, when you type letter, the key value will include capitalization if you also use Shift or Caps Lock: could be "f" or "F". This reflects the intent of what the user is typing when it's text. However, code reflects the physical key, and would always be the same in this case: KeyF - so it can be easily used in designing an interaction where capitalization doesn't matter. In 1.x, you could compare keyCode to 70 (the f/F key), so code is a more readable version of that informaiton.

// Code to run if the enter key was pressed.
}
```

Instead, in 2.x you can use the key function to directly compare the key value.
```js
if (key === 'Enter') { // Enter key
// Code to run if the Enter key was pressed.
}
```

A more detailed comparison.

```js
let x = 50;
let y = 50;

function setup() {
createCanvas(100, 100);

background(200);

describe(
'A gray square with a black circle at its center. The circle moves when the user presses an arrow key. It leaves a trail as it moves.'
);
}
```

<table>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: key event handling is much smoother. In your example, try to quickly switch keys; in 1.x, it's easy to get "stuck" which is difficult for game design. In 2.x, it is handles smoothly. I'm not sure how best to describe this behavior, but if you have an idea, that would be welcome!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a sketch that shows this: https://editor.p5js.org/ksen0/sketches/vrMANhunx - you can switch the versions, it's backwards compatible, and try to key-smash the arrow keys. If the if (keyIsPressed === true) condition is removed, then in both cases it never gets "stuck."

<tr><th>p5.js 1.x</th><th>p5.js 2.x</th></tr>
<tr><td>

```js
function draw() {
// Update x and y if an arrow key is pressed.
if (keyIsPressed === true) {
if (keyCode === UP_ARROW) {
y -= 1;
} else if (keyCode === DOWN_ARROW) {
y += 1;
} else if (keyCode === LEFT_ARROW) {
x -= 1;
} else if (keyCode === RIGHT_ARROW) {
x += 1;
}
}

// Style the circle.
fill(0);

// Draw the circle at (x, y).
circle(x, y, 5);
}
```

</td><td>


```js
function draw() {
// Update x and y if an arrow key is pressed.
if (keyIsPressed === true) {
if (key === 'ArrowUp') { // Up arrow key
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use system variables here, as in: key === ARROW_UP

y -= 1;
} else if (key === 'ArrowDown') { // Down arrow key
y += 1;
} else if (key === 'ArrowLeft') { // Left arrow key
x -= 1;
} else if (key === 'ArrowRight') { // Right arrow key
x += 1;
}
}

// Style the circle.
fill(0);

// Draw the circle at (x, y).
circle(x, y, 5);
}
```

</td></tr>
</table>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a full version of your example above but with keyIsDown please? That would work with system variables in both versions, so it's recommended.

More key codes can be found at websites such as [keycode.info](https://www.toptal.com/developers/keycode)