diff --git a/README.md b/README.md index 4720e27..ae84a50 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ These changes affect authoring of p5.js sketches. Read on for more information o 1. Instead of `bezierVertex(x1, y1, x2, y2, x3, y3)` and `quadraticVertex(x1, y1, x2, y2)`, use multiple `bezierVertex(x, y)` calls, and set order with `bezierOrder` _(to revert to 1.x use, include [shapes.js](https://github.com/processing/p5.js-compatibility/blob/main/src/shapes.js))_ 2. Instead of `curveVertex`, use `splineVertex` - and expect `endShape(CLOSE)` to create a smoothly connected shape _(for 1.x usage, include [shapes.js](https://github.com/processing/p5.js-compatibility/blob/main/src/shapes.js))_ 3. The previous usage of of `textWidth(..)` is now covered by `fontWidth(..)` in 2.x. Use `textWidth(..)` to measure text *without* space (tight bounding box). In 2.x, `fontWidth(..)` measures text width including trailing space. -4. Instead of `keyCode === UP_ARROW` (and similar), use `keyIsDown(UP_ARROW)` (works in both versions) or `code === UP_ARROW` (works in 2.x). _(to revert to 1.x use, include [events.js](https://github.com/processing/p5.js-compatibility/blob/main/src/events.js))_ +4. Instead of `keyCode === UP_ARROW` (and similar), use `keyIsDown(UP_ARROW)` (works in both versions) or `code === UP_ARROW` (works in 2.x). _(to revert to 1.x use, include [data.js](https://github.com/processing/p5.js-compatibility/blob/main/src/data.js))_ 5. Instead of `mouseButton === RIGHT` (and similar), use `mouseButton.right` 6. Instead of `preload()`, `loadImage(...)`, `loadJSON(...)` and all other `load...` functions return **promises** can be used with `async/await` in `setup()` (or with callbacks) _(to revert to 1.x use, include [preload.js](https://github.com/processing/p5.js-compatibility/blob/main/src/preload.js))_ 7. Affecting only add-on libraries: read below how `registerPreloadMethod` can support both preload (1.x) and promises (2.x) diff --git a/src/data.js b/src/data.js index 77bbe60..106ba42 100644 --- a/src/data.js +++ b/src/data.js @@ -1,4 +1,101 @@ function addData(p5, fn){ + /** + * legacy keyboard constants — they map human-readable names to their corresponding numeric key codes. + * key codes - (the old event.keyCode values from the DOM API). + */ + p5.prototype.BACKSPACE = 8; + p5.prototype.DELETE = 46; + p5.prototype.ENTER = 13; + p5.prototype.RETURN = 13; + p5.prototype.TAB = 9; + p5.prototype.ESCAPE = 27; + p5.prototype.SHIFT = 16; + p5.prototype.CONTROL = 17; + p5.prototype.OPTION = 18; + p5.prototype.ALT = 18; + p5.prototype.UP_ARROW = 38; + p5.prototype.DOWN_ARROW = 40; + p5.prototype.LEFT_ARROW = 37; + p5.prototype.RIGHT_ARROW = 39; + + /** + * lookup table (a plain object used as a dictionary) + * it maps modern string-based key codes → old numeric key codes. + */ + const CODE_TO_KEYCODE = { + ArrowUp: 38, + ArrowDown: 40, + ArrowLeft: 37, + ArrowRight: 39, + ShiftLeft: 16, + ShiftRight: 16, + ControlLeft: 17, + ControlRight: 17, + AltLeft: 18, + AltRight: 18, + Backspace: 8, + Tab: 9, + Enter: 13, + Escape: 27, + Delete: 46, + }; + + /** + * _pressedKeyCodes - Internal set to track which numeric keyCodes are currently pressed. + * _origOnKeyDown - Override key event handlers to set numeric keyCode from event.keyCode and maintain the pressed-keys set. + */ + const _pressedKeyCodes = new Set(); + const _origOnKeyDown = fn._onkeydown; + + + /** + * custom override of p5.js's internal _onkeydown handler. + * It intercepts every keydown browser event to patch in backward-compatible behavior for p5.js v1.x sketches running on v2.x. + * @param {*} e + */ + fn._onkeydown = function (e) { + + const numericCode = e.keyCode || CODE_TO_KEYCODE[e.code] || 0; + this.keyCode = numericCode; + _pressedKeyCodes.add(numericCode); + + if (typeof _origOnKeyDown === "function") { + _origOnKeyDown.call(this, e); + } + }; + + /** + * keyup event override — the mirror image of the _onkeydown override + */ + const _origOnKeyUp = fn._onkeyup; + fn._onkeyup = function (e) { + + const numericCode = e.keyCode || CODE_TO_KEYCODE[e.code] || 0; + this.keyCode = numericCode; + _pressedKeyCodes.delete(numericCode); + + if (typeof _origOnKeyUp === "function") { + _origOnKeyUp.call(this, e); + } + }; + + /** + * This block wraps keyIsDown() to make it accept both the old numeric codes (v1.x) and the new string codes (v2.x). + */ + const _origKeyIsDown = fn.keyIsDown; + + fn.keyIsDown = function (code) { + + if (typeof code === "number") { + return _pressedKeyCodes.has(code); + } + + if (typeof _origKeyIsDown === "function") { + return _origKeyIsDown.call(this, code); + } + return false; + }; + fn.touchStarted = function (...args) { return this.mousePressed(...args); };