From 1cd041738a1b06d76809392df9e2ea570a1482fe Mon Sep 17 00:00:00 2001 From: kunstewi Date: Sun, 22 Feb 2026 00:11:47 +0530 Subject: [PATCH 01/12] added keyboard compatibility --- .gitignore | 3 +- README.md | 2 +- src/data.js | 102 ++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 99 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 8aab17a..3ad9d08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.DS_Store node_modules/* !*.gitkeep -dist/ \ No newline at end of file +dist/ +test.html \ No newline at end of file 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..71d281f 100644 --- a/src/data.js +++ b/src/data.js @@ -1,4 +1,4 @@ -function addData(p5, fn){ +function addData(p5, fn) { fn.touchStarted = function (...args) { return this.mousePressed(...args); }; @@ -97,15 +97,15 @@ function addData(p5, fn){ } }; - fn.join = function(list, separator) { + fn.join = function (list, separator) { return list.join(separator); }; - fn.match = function(str, reg) { + fn.match = function (str, reg) { return str.match(reg); }; - fn.matchAll = function(str, reg) { + fn.matchAll = function (str, reg) { const re = new RegExp(reg, 'g'); let match = re.exec(str); const matches = []; @@ -119,11 +119,11 @@ function addData(p5, fn){ return matches; }; - fn.split = function(str, delim) { + fn.split = function (str, delim) { return str.split(delim); }; - fn.trim = function(str) { + fn.trim = function (str) { if (str instanceof Array) { return str.map(this.trim); } else { @@ -328,6 +328,96 @@ function addData(p5, fn){ return this._keyTest(-1); } }; + + // ============================================================ + // Keyboard Events & KeyCode Backward Compatibility (1.x → 2.x) + // ============================================================ + // + // In p5.js 2.x, keyboard constants changed from numeric values + // (e.g. UP_ARROW = 38) to strings (e.g. UP_ARROW = 'ArrowUp'). + // The code below restores 1.x numeric behavior so that legacy + // sketches using `keyCode === LEFT_ARROW` continue to work. + + // 1. Restore 1.x numeric keyCode constants + 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; + + // 2. Mapping from KeyboardEvent.code strings → 1.x numeric keyCodes + // Only includes keys that have corresponding p5.prototype constants. + // For all other keys, the browser's event.keyCode (still universally + // supported despite being deprecated) provides the numeric value. + 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, + }; + + // 4. Internal set to track which numeric keyCodes are currently pressed + const _pressedKeyCodes = new Set(); + + // 5. Override key event handlers to set numeric keyCode from event.keyCode + // and maintain the pressed-keys set. + const _origOnKeyDown = fn._onkeydown; + fn._onkeydown = function (e) { + // Set the numeric keyCode from the browser's (deprecated but available) event.keyCode + const numericCode = e.keyCode || CODE_TO_KEYCODE[e.code] || 0; + this.keyCode = numericCode; + _pressedKeyCodes.add(numericCode); + + // Call original handler + if (typeof _origOnKeyDown === 'function') { + _origOnKeyDown.call(this, e); + } + }; + + 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); + } + }; + + // 6. Wrap keyIsDown() to accept numeric keyCodes + // In 2.x, keyIsDown() expects a string (e.g. 'ArrowUp'). + // With this wrapper, keyIsDown(38) and keyIsDown(UP_ARROW) both work + // with the restored numeric constant. + const _origKeyIsDown = fn.keyIsDown; + fn.keyIsDown = function (code) { + if (typeof code === 'number') { + // Check our internal pressed-keys set for numeric codes + return _pressedKeyCodes.has(code); + } + // For string args, delegate to the original 2.x implementation + if (typeof _origKeyIsDown === 'function') { + return _origKeyIsDown.call(this, code); + } + return false; + }; } if (typeof p5 !== undefined) { From d7a2ca7d1cc378840cafdfde250cfee43a251b30 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Sun, 22 Feb 2026 11:16:45 +0530 Subject: [PATCH 02/12] reverted unnecessary changes --- src/data.js | 170 +++++++++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 90 deletions(-) diff --git a/src/data.js b/src/data.js index 71d281f..2b3bafd 100644 --- a/src/data.js +++ b/src/data.js @@ -1,4 +1,84 @@ function addData(p5, fn) { + // 1. Restore 1.x numeric keyCode constants + 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; + + 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, + }; + + // Internal set to track which numeric keyCodes are currently pressed + const _pressedKeyCodes = new Set(); + + // Override key event handlers to set numeric keyCode from event.keyCode and maintain the pressed-keys set. + const _origOnKeyDown = fn._onkeydown; + + fn._onkeydown = function (e) { + // Set the numeric keyCode from the browser's (deprecated but available) event.keyCode + const numericCode = e.keyCode || CODE_TO_KEYCODE[e.code] || 0; + this.keyCode = numericCode; + _pressedKeyCodes.add(numericCode); + + // Call original handler + if (typeof _origOnKeyDown === "function") { + _origOnKeyDown.call(this, e); + } + }; + + 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); + } + }; + + // 6. Wrap keyIsDown() to accept numeric keyCodes + // In 2.x, keyIsDown() expects a string (e.g. 'ArrowUp'). + // With this wrapper, keyIsDown(38) and keyIsDown(UP_ARROW) both work + // with the restored numeric constant. + const _origKeyIsDown = fn.keyIsDown; + fn.keyIsDown = function (code) { + if (typeof code === "number") { + // Check our internal pressed-keys set for numeric codes + return _pressedKeyCodes.has(code); + } + // For string args, delegate to the original 2.x implementation + if (typeof _origKeyIsDown === "function") { + return _origKeyIsDown.call(this, code); + } + return false; + }; + fn.touchStarted = function (...args) { return this.mousePressed(...args); }; @@ -328,96 +408,6 @@ function addData(p5, fn) { return this._keyTest(-1); } }; - - // ============================================================ - // Keyboard Events & KeyCode Backward Compatibility (1.x → 2.x) - // ============================================================ - // - // In p5.js 2.x, keyboard constants changed from numeric values - // (e.g. UP_ARROW = 38) to strings (e.g. UP_ARROW = 'ArrowUp'). - // The code below restores 1.x numeric behavior so that legacy - // sketches using `keyCode === LEFT_ARROW` continue to work. - - // 1. Restore 1.x numeric keyCode constants - 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; - - // 2. Mapping from KeyboardEvent.code strings → 1.x numeric keyCodes - // Only includes keys that have corresponding p5.prototype constants. - // For all other keys, the browser's event.keyCode (still universally - // supported despite being deprecated) provides the numeric value. - 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, - }; - - // 4. Internal set to track which numeric keyCodes are currently pressed - const _pressedKeyCodes = new Set(); - - // 5. Override key event handlers to set numeric keyCode from event.keyCode - // and maintain the pressed-keys set. - const _origOnKeyDown = fn._onkeydown; - fn._onkeydown = function (e) { - // Set the numeric keyCode from the browser's (deprecated but available) event.keyCode - const numericCode = e.keyCode || CODE_TO_KEYCODE[e.code] || 0; - this.keyCode = numericCode; - _pressedKeyCodes.add(numericCode); - - // Call original handler - if (typeof _origOnKeyDown === 'function') { - _origOnKeyDown.call(this, e); - } - }; - - 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); - } - }; - - // 6. Wrap keyIsDown() to accept numeric keyCodes - // In 2.x, keyIsDown() expects a string (e.g. 'ArrowUp'). - // With this wrapper, keyIsDown(38) and keyIsDown(UP_ARROW) both work - // with the restored numeric constant. - const _origKeyIsDown = fn.keyIsDown; - fn.keyIsDown = function (code) { - if (typeof code === 'number') { - // Check our internal pressed-keys set for numeric codes - return _pressedKeyCodes.has(code); - } - // For string args, delegate to the original 2.x implementation - if (typeof _origKeyIsDown === 'function') { - return _origKeyIsDown.call(this, code); - } - return false; - }; } if (typeof p5 !== undefined) { From c29e66802ba14fb693d7118b8cf86e413f38fd71 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Sun, 22 Feb 2026 14:17:41 +0530 Subject: [PATCH 03/12] added jsdoc explanations --- src/data.js | 73 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/src/data.js b/src/data.js index 2b3bafd..6c2487d 100644 --- a/src/data.js +++ b/src/data.js @@ -1,5 +1,8 @@ function addData(p5, fn) { - // 1. Restore 1.x numeric keyCode constants + /** + * 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; @@ -15,6 +18,10 @@ function addData(p5, fn) { 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, @@ -33,24 +40,33 @@ function addData(p5, fn) { Delete: 46, }; - // Internal set to track which numeric keyCodes are currently pressed + /** + * _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(); - - // Override key event handlers to set numeric keyCode from event.keyCode and maintain the pressed-keys 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) { - // Set the numeric keyCode from the browser's (deprecated but available) event.keyCode + const numericCode = e.keyCode || CODE_TO_KEYCODE[e.code] || 0; this.keyCode = numericCode; _pressedKeyCodes.add(numericCode); - // Call original handler 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; @@ -62,17 +78,14 @@ function addData(p5, fn) { } }; - // 6. Wrap keyIsDown() to accept numeric keyCodes - // In 2.x, keyIsDown() expects a string (e.g. 'ArrowUp'). - // With this wrapper, keyIsDown(38) and keyIsDown(UP_ARROW) both work - // with the restored numeric constant. + /** + * 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") { - // Check our internal pressed-keys set for numeric codes return _pressedKeyCodes.has(code); } - // For string args, delegate to the original 2.x implementation if (typeof _origKeyIsDown === "function") { return _origKeyIsDown.call(this, code); } @@ -115,12 +128,12 @@ function addData(p5, fn) { let start; let end; - if (typeof length !== 'undefined') { + if (typeof length !== "undefined") { end = Math.min(length, src.length); start = dstPosition; src = src.slice(srcPosition, end + srcPosition); } else { - if (typeof dst !== 'undefined') { + if (typeof dst !== "undefined") { // src, dst, length // rename so we don't get confused end = dst; @@ -144,7 +157,7 @@ function addData(p5, fn) { fn.concat = (list0, list1) => list0.concat(list1); - fn.reverse = list => list.reverse(); + fn.reverse = (list) => list.reverse(); fn.shorten = function (list) { list.pop(); @@ -154,7 +167,7 @@ function addData(p5, fn) { fn.sort = function (list, count) { let arr = count ? list.slice(0, Math.min(count, list.length)) : list; const rest = count ? list.slice(Math.min(count, list.length)) : []; - if (typeof arr[0] === 'string') { + if (typeof arr[0] === "string") { arr = arr.sort(); } else { arr = arr.sort((a, b) => a - b); @@ -170,7 +183,7 @@ function addData(p5, fn) { }; fn.subset = function (list, start, count) { - if (typeof count !== 'undefined') { + if (typeof count !== "undefined") { return list.slice(start, start + count); } else { return list.slice(start, list.length); @@ -186,7 +199,7 @@ function addData(p5, fn) { }; fn.matchAll = function (str, reg) { - const re = new RegExp(reg, 'g'); + const re = new RegExp(reg, "g"); let match = re.exec(str); const matches = []; while (match !== null) { @@ -250,7 +263,7 @@ function addData(p5, fn) { if (this._validate(value)) { this.data[key] = value; } else { - console.log('Those values dont work for this dictionary type.'); + console.log("Those values dont work for this dictionary type."); } } @@ -261,14 +274,14 @@ function addData(p5, fn) { } create(key, value) { - if (key instanceof Object && typeof value === 'undefined') { + if (key instanceof Object && typeof value === "undefined") { this._addObj(key); - } else if (typeof key !== 'undefined') { + } else if (typeof key !== "undefined") { this.set(key, value); } else { console.log( - 'In order to create a new Dictionary entry you must pass ' + - 'an object or a key, value pair' + "In order to create a new Dictionary entry you must pass " + + "an object or a key, value pair", ); } } @@ -292,14 +305,14 @@ function addData(p5, fn) { } saveTable(filename) { - let output = ''; + let output = ""; for (const key in this.data) { output += `${key},${this.data[key]}\n`; } - const blob = new Blob([output], { type: 'text/csv' }); - fn.downloadFile(blob, filename || 'mycsv', 'csv'); + const blob = new Blob([output], { type: "text/csv" }); + fn.downloadFile(blob, filename || "mycsv", "csv"); } saveJSON(filename, opt) { @@ -317,7 +330,7 @@ function addData(p5, fn) { } _validate(value) { - return typeof value === 'string'; + return typeof value === "string"; } }; @@ -327,7 +340,7 @@ function addData(p5, fn) { } _validate(value) { - return typeof value === 'number'; + return typeof value === "number"; } add(key, amount) { @@ -361,7 +374,7 @@ function addData(p5, fn) { _valueTest(flip) { if (Object.keys(this.data).length === 0) { throw new Error( - 'Unable to search for a minimum or maximum value on an empty NumberDict' + "Unable to search for a minimum or maximum value on an empty NumberDict", ); } else if (Object.keys(this.data).length === 1) { return this.data[Object.keys(this.data)[0]]; @@ -386,7 +399,7 @@ function addData(p5, fn) { _keyTest(flip) { if (Object.keys(this.data).length === 0) { - throw new Error('Unable to use minValue on an empty NumberDict'); + throw new Error("Unable to use minValue on an empty NumberDict"); } else if (Object.keys(this.data).length === 1) { return Object.keys(this.data)[0]; } else { From 7bfafcd1014c30dd972209e411dbd93cc974a023 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Sun, 22 Feb 2026 14:47:21 +0530 Subject: [PATCH 04/12] removed unncessary changes --- src/data.js | 56 ++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/data.js b/src/data.js index 6c2487d..e791a52 100644 --- a/src/data.js +++ b/src/data.js @@ -1,5 +1,5 @@ -function addData(p5, fn) { - /** +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). */ @@ -69,6 +69,7 @@ function addData(p5, fn) { */ const _origOnKeyUp = fn._onkeyup; fn._onkeyup = function (e) { + const numericCode = e.keyCode || CODE_TO_KEYCODE[e.code] || 0; this.keyCode = numericCode; _pressedKeyCodes.delete(numericCode); @@ -82,10 +83,13 @@ function addData(p5, fn) { * 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); } @@ -128,12 +132,12 @@ function addData(p5, fn) { let start; let end; - if (typeof length !== "undefined") { + if (typeof length !== 'undefined') { end = Math.min(length, src.length); start = dstPosition; src = src.slice(srcPosition, end + srcPosition); } else { - if (typeof dst !== "undefined") { + if (typeof dst !== 'undefined') { // src, dst, length // rename so we don't get confused end = dst; @@ -157,7 +161,7 @@ function addData(p5, fn) { fn.concat = (list0, list1) => list0.concat(list1); - fn.reverse = (list) => list.reverse(); + fn.reverse = list => list.reverse(); fn.shorten = function (list) { list.pop(); @@ -167,7 +171,7 @@ function addData(p5, fn) { fn.sort = function (list, count) { let arr = count ? list.slice(0, Math.min(count, list.length)) : list; const rest = count ? list.slice(Math.min(count, list.length)) : []; - if (typeof arr[0] === "string") { + if (typeof arr[0] === 'string') { arr = arr.sort(); } else { arr = arr.sort((a, b) => a - b); @@ -183,23 +187,23 @@ function addData(p5, fn) { }; fn.subset = function (list, start, count) { - if (typeof count !== "undefined") { + if (typeof count !== 'undefined') { return list.slice(start, start + count); } else { return list.slice(start, list.length); } }; - fn.join = function (list, separator) { + fn.join = function(list, separator) { return list.join(separator); }; - fn.match = function (str, reg) { + fn.match = function(str, reg) { return str.match(reg); }; - fn.matchAll = function (str, reg) { - const re = new RegExp(reg, "g"); + fn.matchAll = function(str, reg) { + const re = new RegExp(reg, 'g'); let match = re.exec(str); const matches = []; while (match !== null) { @@ -212,11 +216,11 @@ function addData(p5, fn) { return matches; }; - fn.split = function (str, delim) { + fn.split = function(str, delim) { return str.split(delim); }; - fn.trim = function (str) { + fn.trim = function(str) { if (str instanceof Array) { return str.map(this.trim); } else { @@ -263,7 +267,7 @@ function addData(p5, fn) { if (this._validate(value)) { this.data[key] = value; } else { - console.log("Those values dont work for this dictionary type."); + console.log('Those values dont work for this dictionary type.'); } } @@ -274,14 +278,14 @@ function addData(p5, fn) { } create(key, value) { - if (key instanceof Object && typeof value === "undefined") { + if (key instanceof Object && typeof value === 'undefined') { this._addObj(key); - } else if (typeof key !== "undefined") { + } else if (typeof key !== 'undefined') { this.set(key, value); } else { console.log( - "In order to create a new Dictionary entry you must pass " + - "an object or a key, value pair", + 'In order to create a new Dictionary entry you must pass ' + + 'an object or a key, value pair' ); } } @@ -305,14 +309,14 @@ function addData(p5, fn) { } saveTable(filename) { - let output = ""; + let output = ''; for (const key in this.data) { output += `${key},${this.data[key]}\n`; } - const blob = new Blob([output], { type: "text/csv" }); - fn.downloadFile(blob, filename || "mycsv", "csv"); + const blob = new Blob([output], { type: 'text/csv' }); + fn.downloadFile(blob, filename || 'mycsv', 'csv'); } saveJSON(filename, opt) { @@ -330,7 +334,7 @@ function addData(p5, fn) { } _validate(value) { - return typeof value === "string"; + return typeof value === 'string'; } }; @@ -340,7 +344,7 @@ function addData(p5, fn) { } _validate(value) { - return typeof value === "number"; + return typeof value === 'number'; } add(key, amount) { @@ -374,7 +378,7 @@ function addData(p5, fn) { _valueTest(flip) { if (Object.keys(this.data).length === 0) { throw new Error( - "Unable to search for a minimum or maximum value on an empty NumberDict", + 'Unable to search for a minimum or maximum value on an empty NumberDict' ); } else if (Object.keys(this.data).length === 1) { return this.data[Object.keys(this.data)[0]]; @@ -399,7 +403,7 @@ function addData(p5, fn) { _keyTest(flip) { if (Object.keys(this.data).length === 0) { - throw new Error("Unable to use minValue on an empty NumberDict"); + throw new Error('Unable to use minValue on an empty NumberDict'); } else if (Object.keys(this.data).length === 1) { return Object.keys(this.data)[0]; } else { @@ -425,4 +429,4 @@ function addData(p5, fn) { if (typeof p5 !== undefined) { p5.registerAddon(addData); -} +} \ No newline at end of file From ade15e28de091369a9be964c64fcca6d52b0e1f9 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Sun, 22 Feb 2026 15:17:21 +0530 Subject: [PATCH 05/12] final changes --- .gitignore | 2 +- src/data.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3ad9d08..3669c06 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ node_modules/* !*.gitkeep dist/ -test.html \ No newline at end of file +test.html diff --git a/src/data.js b/src/data.js index e791a52..106ba42 100644 --- a/src/data.js +++ b/src/data.js @@ -429,4 +429,4 @@ function addData(p5, fn){ if (typeof p5 !== undefined) { p5.registerAddon(addData); -} \ No newline at end of file +} From 81362474cb10c2c334a43b83e295c9b8090e7b89 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Sun, 22 Feb 2026 15:34:17 +0530 Subject: [PATCH 06/12] removed test.html --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3669c06..395f87f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ node_modules/* !*.gitkeep dist/ -test.html From 70efa36251f4755cf838c6ebd6dd60a0f2a7c4f2 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Sun, 22 Feb 2026 15:42:02 +0530 Subject: [PATCH 07/12] unchanged gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 395f87f..8aab17a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ *.DS_Store node_modules/* !*.gitkeep -dist/ +dist/ \ No newline at end of file From 7be309b668c8f7c89522a0d8f169d63e82f9f8b8 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Wed, 15 Apr 2026 15:06:36 +0530 Subject: [PATCH 08/12] added requested changes --- README.md | 12 +++-- src/data.js | 123 -------------------------------------------------- src/events.js | 101 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 128 deletions(-) create mode 100644 src/events.js diff --git a/README.md b/README.md index ae84a50..a126eb9 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,15 @@ Even as p5.js 2.0 becomes more stable, p5.js 1.x will continue to be supported until August, 2026. Between 1.x and 2.0, there are many additions, and some breaking changes. In addition to making p5.js 2.0 available as a library, we are working on preparing several compatibility add-on libraries that would make it possible to keep using 1.x features that are no longer part of 2.0. -We are working on three compatibility add-on libraries which will make these 1.x features available for 2.0: +We are working on four compatibility add-on libraries which will make these 1.x features available for 2.0: 1. [preload.js](https://github.com/processing/p5.js-compatibility/blob/main/src/preload.js) 2. [shapes.js](https://github.com/processing/p5.js-compatibility/blob/main/src/shapes.js) -3. [data.js](https://github.com/processing/p5.js-compatibility/blob/main/src/data.js) +3. [events.js](https://github.com/processing/p5.js-compatibility/blob/main/src/events.js) + +4. [data.js](https://github.com/processing/p5.js-compatibility/blob/main/src/data.js) These add-on libraries are available in the **p5.js Editor** in the Settings > Library Management modal: @@ -26,7 +28,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 [data.js](https://github.com/processing/p5.js-compatibility/blob/main/src/data.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 [events.js](https://github.com/processing/p5.js-compatibility/blob/main/src/events.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) @@ -555,7 +557,7 @@ function draw() { Notice that when you press multiple buttons at the same time, multiple shapes can be obtained. -Finally, touch and mouse event handling has been combined to improve sketch consistency across devices. 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`](https://beta.p5js.org/reference/p5/touches/) array to see what pointers are active for multitouch support! +Finally, touch and mouse event handling has been combined to improve sketch consistency across devices. 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`](https://beta.p5js.org/reference/p5/touches/) array to see what pointers are active for multitouch support! The legacy touch event aliases remain available with the [events.js](https://github.com/processing/p5.js-compatibility/blob/main/src/events.js) compatibility add-on library. @@ -593,7 +595,7 @@ function draw() {
p5.js 1.xp5.js 2.x
-## ...using keyCode events: +## ...using keyCode events (`events.js`): The sketch below works in both versions, but try to use it while quickly pressing different arrow keys - you will notice that the event handling in p5.js 2.x is smoother: diff --git a/src/data.js b/src/data.js index 106ba42..8192e08 100644 --- a/src/data.js +++ b/src/data.js @@ -1,127 +1,4 @@ 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); - }; - fn.touchEnded = function (...args) { - return this.mouseReleased(...args); - }; - fn.touchMoved = function (...args) { - return this.mouseDragged(...args); - }; - p5.Element.prototype.touchStarted = function (cb) { - return this.mousePressed(cb); - }; - p5.Element.prototype.touchEnded = function (cb) { - return this.mouseReleased(cb); - }; - p5.Element.prototype.touchMoved = function (cb) { - if (cb === false) { - return this.mouseMoved(false); - } - return this.mouseMoved(function (event) { - if ((event.buttons & 1) !== 0) { - return cb(event); - } - }); - }; - fn.append = function (array, value) { array.push(value); return array; diff --git a/src/events.js b/src/events.js new file mode 100644 index 0000000..ea873bc --- /dev/null +++ b/src/events.js @@ -0,0 +1,101 @@ +function addEvents(p5, fn) { + 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; + + const codeToKeyCode = { + 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, + }; + + const pressedKeyCodes = new Set(); + const oldOnKeyDown = fn._onkeydown; + const oldOnKeyUp = fn._onkeyup; + const oldKeyIsDown = fn.keyIsDown; + + fn._onkeydown = function (e) { + const numericCode = e.keyCode || codeToKeyCode[e.code] || 0; + this.keyCode = numericCode; + pressedKeyCodes.add(numericCode); + + if (typeof oldOnKeyDown === 'function') { + oldOnKeyDown.call(this, e); + } + }; + + fn._onkeyup = function (e) { + const numericCode = e.keyCode || codeToKeyCode[e.code] || 0; + this.keyCode = numericCode; + pressedKeyCodes.delete(numericCode); + + if (typeof oldOnKeyUp === 'function') { + oldOnKeyUp.call(this, e); + } + }; + + fn.keyIsDown = function (code) { + if (typeof code === 'number') { + return pressedKeyCodes.has(code); + } + + if (typeof oldKeyIsDown === 'function') { + return oldKeyIsDown.call(this, code); + } + return false; + }; + + fn.touchStarted = function (...args) { + return this.mousePressed(...args); + }; + fn.touchEnded = function (...args) { + return this.mouseReleased(...args); + }; + fn.touchMoved = function (...args) { + return this.mouseDragged(...args); + }; + + p5.Element.prototype.touchStarted = function (cb) { + return this.mousePressed(cb); + }; + p5.Element.prototype.touchEnded = function (cb) { + return this.mouseReleased(cb); + }; + p5.Element.prototype.touchMoved = function (cb) { + if (cb === false) { + return this.mouseMoved(false); + } + return this.mouseMoved(function (event) { + if ((event.buttons & 1) !== 0) { + return cb(event); + } + }); + }; +} + +if (typeof p5 !== undefined) { + p5.registerAddon(addEvents); +} From 5f34b73df6b56125e8c056eb3fde0769577dc7dd Mon Sep 17 00:00:00 2001 From: kunstewi Date: Wed, 15 Apr 2026 15:14:03 +0530 Subject: [PATCH 09/12] unchanged data.js --- README.md | 2 +- src/data.js | 26 ++++++++++++++++++++++++++ src/events.js | 27 --------------------------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index a126eb9..3e37fc7 100644 --- a/README.md +++ b/README.md @@ -557,7 +557,7 @@ function draw() { Notice that when you press multiple buttons at the same time, multiple shapes can be obtained. -Finally, touch and mouse event handling has been combined to improve sketch consistency across devices. 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`](https://beta.p5js.org/reference/p5/touches/) array to see what pointers are active for multitouch support! The legacy touch event aliases remain available with the [events.js](https://github.com/processing/p5.js-compatibility/blob/main/src/events.js) compatibility add-on library. +Finally, touch and mouse event handling has been combined to improve sketch consistency across devices. 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`](https://beta.p5js.org/reference/p5/touches/) array to see what pointers are active for multitouch support! The legacy touch event aliases remain available with the [data.js](https://github.com/processing/p5.js-compatibility/blob/main/src/data.js) compatibility add-on library. diff --git a/src/data.js b/src/data.js index 8192e08..77bbe60 100644 --- a/src/data.js +++ b/src/data.js @@ -1,4 +1,30 @@ function addData(p5, fn){ + fn.touchStarted = function (...args) { + return this.mousePressed(...args); + }; + fn.touchEnded = function (...args) { + return this.mouseReleased(...args); + }; + fn.touchMoved = function (...args) { + return this.mouseDragged(...args); + }; + p5.Element.prototype.touchStarted = function (cb) { + return this.mousePressed(cb); + }; + p5.Element.prototype.touchEnded = function (cb) { + return this.mouseReleased(cb); + }; + p5.Element.prototype.touchMoved = function (cb) { + if (cb === false) { + return this.mouseMoved(false); + } + return this.mouseMoved(function (event) { + if ((event.buttons & 1) !== 0) { + return cb(event); + } + }); + }; + fn.append = function (array, value) { array.push(value); return array; diff --git a/src/events.js b/src/events.js index ea873bc..087ba78 100644 --- a/src/events.js +++ b/src/events.js @@ -67,33 +67,6 @@ function addEvents(p5, fn) { } return false; }; - - fn.touchStarted = function (...args) { - return this.mousePressed(...args); - }; - fn.touchEnded = function (...args) { - return this.mouseReleased(...args); - }; - fn.touchMoved = function (...args) { - return this.mouseDragged(...args); - }; - - p5.Element.prototype.touchStarted = function (cb) { - return this.mousePressed(cb); - }; - p5.Element.prototype.touchEnded = function (cb) { - return this.mouseReleased(cb); - }; - p5.Element.prototype.touchMoved = function (cb) { - if (cb === false) { - return this.mouseMoved(false); - } - return this.mouseMoved(function (event) { - if ((event.buttons & 1) !== 0) { - return cb(event); - } - }); - }; } if (typeof p5 !== undefined) { From 534be16411a24150d0d7bddc74379b83c60f0b34 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Wed, 15 Apr 2026 15:18:04 +0530 Subject: [PATCH 10/12] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e37fc7..d5c68cb 100644 --- a/README.md +++ b/README.md @@ -557,7 +557,7 @@ function draw() { Notice that when you press multiple buttons at the same time, multiple shapes can be obtained. -Finally, touch and mouse event handling has been combined to improve sketch consistency across devices. 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`](https://beta.p5js.org/reference/p5/touches/) array to see what pointers are active for multitouch support! The legacy touch event aliases remain available with the [data.js](https://github.com/processing/p5.js-compatibility/blob/main/src/data.js) compatibility add-on library. +Finally, touch and mouse event handling has been combined to improve sketch consistency across devices. 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`](https://beta.p5js.org/reference/p5/touches/) array to see what pointers are active for multitouch support!
p5.js 1.xp5.js 2.x
From ea2e053404de35eac0da2c4d833e7af0f1f266c2 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Wed, 15 Apr 2026 16:51:52 +0530 Subject: [PATCH 11/12] removed accidental keyIsDown(0) value --- src/events.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/events.js b/src/events.js index 087ba78..e83a890 100644 --- a/src/events.js +++ b/src/events.js @@ -40,7 +40,9 @@ function addEvents(p5, fn) { fn._onkeydown = function (e) { const numericCode = e.keyCode || codeToKeyCode[e.code] || 0; this.keyCode = numericCode; - pressedKeyCodes.add(numericCode); + if (numericCode !== 0) { + pressedKeyCodes.add(numericCode); + } if (typeof oldOnKeyDown === 'function') { oldOnKeyDown.call(this, e); @@ -50,7 +52,9 @@ function addEvents(p5, fn) { fn._onkeyup = function (e) { const numericCode = e.keyCode || codeToKeyCode[e.code] || 0; this.keyCode = numericCode; - pressedKeyCodes.delete(numericCode); + if (numericCode !== 0) { + pressedKeyCodes.delete(numericCode); + } if (typeof oldOnKeyUp === 'function') { oldOnKeyUp.call(this, e); From 5e8a61e221bcd3fdd1c6ff321244d35156155046 Mon Sep 17 00:00:00 2001 From: kunstewi Date: Wed, 15 Apr 2026 17:01:55 +0530 Subject: [PATCH 12/12] fixed typeof checks to return the expected answer --- src/events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events.js b/src/events.js index e83a890..9791d62 100644 --- a/src/events.js +++ b/src/events.js @@ -73,6 +73,6 @@ function addEvents(p5, fn) { }; } -if (typeof p5 !== undefined) { +if (typeof p5 !== 'undefined' && typeof p5.registerAddon === 'function') { p5.registerAddon(addEvents); }
p5.js 1.xp5.js 2.x