From 04d90f24eb637c4b1bc47822ebf8eff4c348aff0 Mon Sep 17 00:00:00 2001 From: ffd8 Date: Mon, 19 Jun 2023 02:35:23 +0200 Subject: [PATCH 1/5] Initial implementation of existing html canvas for createGraphics within p5.js 1.6.0 codebase --- src/core/p5.Graphics.js | 20 +++++++++++++++----- src/core/rendering.js | 5 +++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/core/p5.Graphics.js b/src/core/p5.Graphics.js index 8d7c00eb74..f4d9c557ac 100644 --- a/src/core/p5.Graphics.js +++ b/src/core/p5.Graphics.js @@ -21,16 +21,26 @@ import * as constants from './constants'; * @param {Number} h height * @param {Constant} renderer the renderer to use, either P2D or WEBGL * @param {p5} [pInst] pointer to p5 instance + * @param {Object} [canvas] existing html canvas element */ p5.Graphics = class extends p5.Element { - constructor(w, h, renderer, pInst) { - let canvas = document.createElement('canvas'); - super(canvas, pInst); + constructor(w, h, renderer, pInst, canvas) { + let canvasTemp; + if (canvas) { + canvasTemp = canvas; + } else { + canvasTemp = document.createElement('canvas'); + } + + super(canvasTemp, pInst); + this.canvas = canvasTemp; + const r = renderer || constants.P2D; - this.canvas = canvas; const node = pInst._userNode || document.body; - node.appendChild(this.canvas); + if (!canvas) { + node.appendChild(this.canvas); + } // bind methods and props of p5 to the new object for (const p in p5.prototype) { diff --git a/src/core/rendering.js b/src/core/rendering.js index 6c2cc167fd..4b5c1f49be 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -221,6 +221,7 @@ p5.prototype.noCanvas = function() { * @param {Number} h height of the offscreen graphics buffer * @param {Constant} [renderer] either P2D or WEBGL * undefined defaults to p2d + * @param {Object} [canvas] existing html canvas element * @return {p5.Graphics} offscreen graphics buffer * @example *
@@ -245,9 +246,9 @@ p5.prototype.noCanvas = function() { * @alt * 4 grey squares alternating light and dark grey. White quarter circle mid-left. */ -p5.prototype.createGraphics = function(w, h, renderer) { +p5.prototype.createGraphics = function(w, h, renderer, canvas) { p5._validateParameters('createGraphics', arguments); - return new p5.Graphics(w, h, renderer, this); + return new p5.Graphics(w, h, renderer, this, canvas); }; /** From 926b93413bf580ec57bd347b65032f69eb9edab0 Mon Sep 17 00:00:00 2001 From: ffd8 Date: Tue, 20 Jun 2023 14:02:31 +0200 Subject: [PATCH 2/5] existing-canvas docs example and methods --- src/core/rendering.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/core/rendering.js b/src/core/rendering.js index 4b5c1f49be..44e6c06983 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -242,11 +242,39 @@ p5.prototype.noCanvas = function() { * } * *
+ *
+ * + * let ar; + * function setup() { + * createCanvas(100, 100); + * ar = createGraphics(100, 100, document.getElementById('canvas-ar')); + * } + * + * function draw() { + * circle(random(width), random(height), random(15)); + * + * // grab visuals and pass to ar layer + * ar.image(get(0, 0, width, height), 0, 0, ar.width, ar.height); + * } + * + *
* * @alt * 4 grey squares alternating light and dark grey. White quarter circle mid-left. + * Random circles across the page. + */ +/** + * @method createGraphics + * @param {Number} w + * @param {Number} h + * @param {Object} [canvas] + * @return {p5.Graphics} offscreen graphics buffer */ p5.prototype.createGraphics = function(w, h, renderer, canvas) { + if (arguments[2] instanceof HTMLCanvasElement) { + renderer = constants.P2D; + canvas = arguments[2]; + } p5._validateParameters('createGraphics', arguments); return new p5.Graphics(w, h, renderer, this, canvas); }; From a3eb3de15c83823fa31f9c115abc8e6c9265c93f Mon Sep 17 00:00:00 2001 From: ffd8 Date: Wed, 21 Jun 2023 01:42:04 +0200 Subject: [PATCH 3/5] Added existing canvas to createCanvas() --- src/core/rendering.js | 116 ++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 49 deletions(-) diff --git a/src/core/rendering.js b/src/core/rendering.js index 44e6c06983..ea5c5c4570 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -34,6 +34,8 @@ const defaultClass = 'p5Canvas'; * function. If createCanvas() is not used, the * window will be given a default size of 100×100 pixels. * + * Optionally, an existing canvas can be passed using a selector, ie. document.getElementById(''). + * * For more ways to position the canvas, see the * * positioning the canvas wiki page. @@ -42,6 +44,7 @@ const defaultClass = 'p5Canvas'; * @param {Number} w width of the canvas * @param {Number} h height of the canvas * @param {Constant} [renderer] either P2D or WEBGL + * @param {Object} [canvas] existing html canvas element * @return {p5.Renderer} pointer to p5.Renderer holding canvas * @example *
@@ -57,56 +60,84 @@ const defaultClass = 'p5Canvas'; * @alt * Black line extending from top-left of canvas to bottom right. */ -p5.prototype.createCanvas = function(w, h, renderer) { +/** + * @method createCanvas + * @param {Number} w + * @param {Number} h + * @param {Object} [canvas] + * @return {p5.Renderer} pointer to p5.Renderer holding canvas + */ +p5.prototype.createCanvas = function(w, h, renderer, canvas) { p5._validateParameters('createCanvas', arguments); //optional: renderer, otherwise defaults to p2d - const r = renderer || constants.P2D; + + let r; + if (arguments[2] instanceof HTMLCanvasElement) { + renderer = constants.P2D; + canvas = arguments[2]; + } else { + r = renderer || constants.P2D; + } + let c; - if (r === constants.WEBGL) { + if (canvas) { c = document.getElementById(defaultId); if (c) { - //if defaultCanvas already exists c.parentNode.removeChild(c); //replace the existing defaultCanvas - const thisRenderer = this._renderer; - this._elements = this._elements.filter(e => e !== thisRenderer); } - c = document.createElement('canvas'); - c.id = defaultId; - c.classList.add(defaultClass); + c = canvas; + this._defaultGraphicsCreated = false; } else { - if (!this._defaultGraphicsCreated) { - c = document.createElement('canvas'); - let i = 0; - while (document.getElementById(`defaultCanvas${i}`)) { - i++; + if (r === constants.WEBGL) { + c = document.getElementById(defaultId); + if (c) { + //if defaultCanvas already exists + c.parentNode.removeChild(c); //replace the existing defaultCanvas + const thisRenderer = this._renderer; + this._elements = this._elements.filter(e => e !== thisRenderer); } - defaultId = `defaultCanvas${i}`; + c = document.createElement('canvas'); c.id = defaultId; c.classList.add(defaultClass); } else { - // resize the default canvas if new one is created - c = this.canvas; + if (!this._defaultGraphicsCreated) { + if (canvas) { + c = canvas; + } else { + c = document.createElement('canvas'); + } + let i = 0; + while (document.getElementById(`defaultCanvas${i}`)) { + i++; + } + defaultId = `defaultCanvas${i}`; + c.id = defaultId; + c.classList.add(defaultClass); + } else { + // resize the default canvas if new one is created + c = this.canvas; + } } - } - // set to invisible if still in setup (to prevent flashing with manipulate) - if (!this._setupDone) { - c.dataset.hidden = true; // tag to show later - c.style.visibility = 'hidden'; - } + // set to invisible if still in setup (to prevent flashing with manipulate) + if (!this._setupDone) { + c.dataset.hidden = true; // tag to show later + c.style.visibility = 'hidden'; + } - if (this._userNode) { - // user input node case - this._userNode.appendChild(c); - } else { - //create main element - if (document.getElementsByTagName('main').length === 0) { - let m = document.createElement('main'); - document.body.appendChild(m); + if (this._userNode) { + // user input node case + this._userNode.appendChild(c); + } else { + //create main element + if (document.getElementsByTagName('main').length === 0) { + let m = document.createElement('main'); + document.body.appendChild(m); + } + //append canvas to main + document.getElementsByTagName('main')[0].appendChild(c); } - //append canvas to main - document.getElementsByTagName('main')[0].appendChild(c); } // Init our graphics renderer @@ -216,6 +247,9 @@ p5.prototype.noCanvas = function() { * to check what version is being used, or call pg.setAttributes({ version: 1 }) * to create a WebGL1 context. * + * Optionally, an existing canvas can be passed using a selector, ie. document.getElementById(''). + * By default this canvas will be hidden (offscreen buffer), to make visible, set element's style to display:block; + * * @method createGraphics * @param {Number} w width of the offscreen graphics buffer * @param {Number} h height of the offscreen graphics buffer @@ -242,22 +276,6 @@ p5.prototype.noCanvas = function() { * } * *
- *
- * - * let ar; - * function setup() { - * createCanvas(100, 100); - * ar = createGraphics(100, 100, document.getElementById('canvas-ar')); - * } - * - * function draw() { - * circle(random(width), random(height), random(15)); - * - * // grab visuals and pass to ar layer - * ar.image(get(0, 0, width, height), 0, 0, ar.width, ar.height); - * } - * - *
* * @alt * 4 grey squares alternating light and dark grey. White quarter circle mid-left. From 1b3f3b33dc55d60362be0992173d3b493886faa0 Mon Sep 17 00:00:00 2001 From: ffd8 Date: Tue, 27 Jun 2023 09:34:46 +0200 Subject: [PATCH 4/5] Update rendering.js - removing old example alt-text Forgot to remove the alt-text of an example that was never added. --- src/core/rendering.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/rendering.js b/src/core/rendering.js index ea5c5c4570..d9fe9670b6 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -279,7 +279,6 @@ p5.prototype.noCanvas = function() { * * @alt * 4 grey squares alternating light and dark grey. White quarter circle mid-left. - * Random circles across the page. */ /** * @method createGraphics From affc51080d56fd93bbef18604e18cc1b14104019 Mon Sep 17 00:00:00 2001 From: Qianqian Ye Date: Fri, 30 Jun 2023 15:19:03 -0700 Subject: [PATCH 5/5] Update src/core/rendering.js Co-authored-by: Dave Pagurek --- src/core/rendering.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/rendering.js b/src/core/rendering.js index d9fe9670b6..31448ac7a9 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -34,7 +34,8 @@ const defaultClass = 'p5Canvas'; * function. If createCanvas() is not used, the * window will be given a default size of 100×100 pixels. * - * Optionally, an existing canvas can be passed using a selector, ie. document.getElementById(''). + * Optionally, an existing canvas can be passed using a selector, ie. `document.getElementById('')`. + * If specified, avoid using `setAttributes()` afterwards, as this will remove and recreate the existing canvas. * * For more ways to position the canvas, see the *