From 36f3c0a970fed545f954c7268fddfd61c5b906bb Mon Sep 17 00:00:00 2001 From: Om <144691499+ombalgude@users.noreply.github.com> Date: Sat, 11 Oct 2025 18:34:49 +0530 Subject: [PATCH 1/2] refactor: Move setViewport to standalone addon in lib/addons --- lib/addons/p5.viewport.js | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 lib/addons/p5.viewport.js diff --git a/lib/addons/p5.viewport.js b/lib/addons/p5.viewport.js new file mode 100644 index 0000000000..1b80caad65 --- /dev/null +++ b/lib/addons/p5.viewport.js @@ -0,0 +1,50 @@ +/** + * @module p5.viewport + * @submodule p5.viewport + * @for p5 + * @version 0.0.1 + * @author om balgude + * @description This addon provides a setViewport function to remap the canvas coordinate system. + * + */ + +(function() { + /** + * The viewportAddon function is automatically called by p5.js to add the addon + * functionality to the p5.js library. + * + * @private + * @param {Object} p5 - The p5.js instance. + * @param {Object} fn - The p5.js prototype object. + * @param {Object} lifecycles - The p5.js lifecycle hooks. + */ + function viewportAddon(p5, fn, lifecycles) { + /** + * Sets the coordinate system to a new viewport. + * + * Calling `setViewport(xmin, xmax, ymin, ymax)` remaps the canvas's + * coordinate system. The top-left corner of the canvas will be `(xmin, ymin)` + * and the bottom-right corner will be `(xmax, ymax)`. + * + * @method setViewport + * @param {Number} xmin The minimum x-value of the viewport. + * @param {Number} xmax The maximum x-value of the viewport. + * @param {Number} ymin The minimum y-value of the viewport. + * @param {Number} ymax The maximum y-value of the viewport. + * @chainable + */ + fn.setViewport = function(xmin, xmax, ymin, ymax) { + this.resetMatrix(); + const scaleX = this.width / (xmax - xmin); + const scaleY = this.height / (ymax - ymin); + this.scale(scaleX, scaleY); + this.translate(-xmin, -ymin); + return this; + }; + } + + // Register the addon with p5.js + if (typeof p5 !== 'undefined') { + p5.registerAddon(viewportAddon); + } +})(); From f4e381c0cf3f3a439492a2aa01356c23fbe16b39 Mon Sep 17 00:00:00 2001 From: Om <144691499+ombalgude@users.noreply.github.com> Date: Fri, 28 Nov 2025 11:25:34 +0530 Subject: [PATCH 2/2] Add activeCamera() joint getter/setter for camera access --- src/webgl/p5.Camera.js | 119 +++++++++++++++++++++++++++++++++++ test/unit/webgl/p5.Camera.js | 46 ++++++++++++++ 2 files changed, 165 insertions(+) diff --git a/src/webgl/p5.Camera.js b/src/webgl/p5.Camera.js index b687f916c5..e1cb9332f8 100644 --- a/src/webgl/p5.Camera.js +++ b/src/webgl/p5.Camera.js @@ -3822,6 +3822,116 @@ function camera(p5, fn){ this._renderer.setCamera(cam); }; + /** + * Returns or sets the current (active) camera of a 3D sketch. + * + * `activeCamera()` provides a standard way to access and modify the active + * camera. When called with no arguments, it returns the current active camera. + * When called with a camera argument, it sets that camera as the active camera. + * + * This function works alongside setCamera() and + * provides a joint getter/setter pattern that's consistent with other p5.js + * functions. + * + * Note: `activeCamera()` can only be used in WebGL mode. + * + * @method activeCamera + * @param {p5.Camera} [cam] camera that should be made active. If omitted, returns the current active camera. + * @return {p5.Camera|p5} the current active camera (when called with no arguments) or the p5 instance (for chaining when setting). + * @for p5 + * + * @example + *
+ * // Get the current active camera.
+ *
+ * let cam1;
+ * let cam2;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create two cameras.
+ * cam1 = createCamera();
+ * cam2 = createCamera();
+ * cam2.setPosition(400, -400, 800);
+ * cam2.lookAt(0, 0, 0);
+ *
+ * // Set cam1 as active.
+ * activeCamera(cam1);
+ *
+ * describe('A white cube on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Get the current active camera.
+ * let currentCam = activeCamera();
+ *
+ * // Draw the box.
+ * box();
+ * }
+ *
+ *
+ * // Double-click to toggle between cameras.
+ *
+ * let cam1;
+ * let cam2;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Create the first camera.
+ * cam1 = createCamera();
+ *
+ * // Create the second camera.
+ * cam2 = createCamera();
+ * cam2.setPosition(400, -400, 800);
+ * cam2.lookAt(0, 0, 0);
+ *
+ * // Set the current camera to cam1.
+ * activeCamera(cam1);
+ *
+ * describe('A white cube on a gray background. The camera toggles between frontal and aerial views when the user double-clicks.');
+ * }
+ *
+ * function draw() {
+ * background(200);
+ *
+ * // Draw the box.
+ * box();
+ * }
+ *
+ * // Toggle the current camera when the user double-clicks.
+ * function doubleClicked() {
+ * // Get the current camera.
+ * let currentCam = activeCamera();
+ *
+ * // Switch to the other camera.
+ * if (currentCam === cam1) {
+ * activeCamera(cam2);
+ * } else {
+ * activeCamera(cam1);
+ * }
+ * }
+ *
+ *