From f5b832159d3e55461b2105d81d3c96ee44e3c1ff Mon Sep 17 00:00:00 2001 From: Jerome Wang <39065949+immjs@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:03:17 +0100 Subject: [PATCH 1/2] Initial commit --- src/element.ts | 20 ++++++++++++++++++-- src/filters.ts | 5 +++++ src/groupInterface.ts | 43 +++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 2 ++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/groupInterface.ts diff --git a/src/element.ts b/src/element.ts index cb97a87..6eee6f6 100644 --- a/src/element.ts +++ b/src/element.ts @@ -21,6 +21,8 @@ export default (p5: P5SVG) => { p5.SVGElement = class SVGElement extends p5.Element { public elt: Element + public isUserInstanciated: boolean + /** * Returns an Array of children of current SVG Element matching given selector * @@ -50,13 +52,27 @@ export default (p5: P5SVG) => { * Create SVGElement * */ - static create(nodeName: string, attributes: { [key: string]: string }) { + static create(nodeName: string, attributes: { [key: string]: string }, isUserInstanciated: boolean?) { attributes = attributes || {} const elt = document.createElementNS('http://www.w3.org/2000/svg', nodeName) Object.keys(attributes).forEach(function (k) { elt.setAttribute(k, attributes[k]) }) - return new SVGElement(elt as any) + const svgEl = new SVGElement(elt as any) + svgEl.isUserInstanciated = isUserInstanciated; + return svgEl; + } + + /** + * Check if any group above is user instanciated + * Will also return true if oneself is user instanciated + * + */ + isWithinUserInstanciated() { + if (this.isUserInstanciated) return true; + if (!(this.parentNode instanceof SVGElement)) return false; + + return this.parentNode.isWithinUserInstanciated(); } /** diff --git a/src/filters.ts b/src/filters.ts index aa0acd2..21b4a36 100644 --- a/src/filters.ts +++ b/src/filters.ts @@ -55,6 +55,11 @@ export default function (p5: P5SVG) { // create new so that new element won't be influenced by the filter g = p5.SVGElement.create('g') rootGroup.appendChild(g.elt) + + if (ctx.__currentElement.isWithinUserInstanciated()) { + console.warn('Filter will promptly exit out of any instanciated group. Please make sure you\'ve exited them before filtering'); + } + ctx.__currentElement = g.elt } else { _filter.apply(this, [operation, value]) diff --git a/src/groupInterface.ts b/src/groupInterface.ts new file mode 100644 index 0000000..6345eb5 --- /dev/null +++ b/src/groupInterface.ts @@ -0,0 +1,43 @@ +import p5RendererSVG from "./p5.RendererSVG"; +import { P5SVG, SVGElement, p5SVG } from "./types"; + +export default function (p5: P5SVG) { + p5.prototype.pushSVGGroup = function (this: p5SVG) { + if (!(this._renderer instanceof p5RendererSVG)) { + console.warn('Attempted to push SVG group in non-svg canvas'); + return null; + } + + const group = p5.SVGElement.create('g', {}, true); + + const currEl = this._renderer.drawingContext.__currentElement; + + if (currEl.tagName !== 'g' && currEl.tagName) { + console.warn('Attempted to pop SVG group whilst not in g, svg'); + return; + } + + currEl.append(group); + + this._renderer.drawingContext.__currentElement = group; + + return group; + } + + p5.prototype.popSVGGroup = function (this: p5SVG, group: SVGElement) { + if (!(this._renderer instanceof p5RendererSVG)) { + console.warn('Attempted to pop SVG group in non-svg canvas'); + return null; + } + + const currEl = this._renderer.drawingContext.__currentElement; + + if (currEl !== group) { + return; // Silently fail: the warning has already been given by filter + } + + this._renderer.drawingContext.__currentElement = currEl.parentNode(); + + return; + } +} diff --git a/src/index.ts b/src/index.ts index ed4b151..31eddda 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ import IO from './io' import Image from './image' import Element from './element' import Filters from './filters' +import GroupInterface from '' import constants from './constants' function init(p5: P5) { @@ -19,6 +20,7 @@ function init(p5: P5) { Filters(p5svg) Element(p5svg) + // attach constants to p5 instance p5svg.prototype['SVG'] = constants.SVG From 4325389141c4825c29d09681019d048112b770fb Mon Sep 17 00:00:00 2001 From: Jerome Wang <39065949+immjs@users.noreply.github.com> Date: Mon, 26 Feb 2024 19:37:43 +0100 Subject: [PATCH 2/2] Call groupinterface on init --- src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 31eddda..05689e0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import IO from './io' import Image from './image' import Element from './element' import Filters from './filters' -import GroupInterface from '' +import GroupInterface from './groupInterface' import constants from './constants' function init(p5: P5) { @@ -19,6 +19,7 @@ function init(p5: P5) { Image(p5svg) Filters(p5svg) Element(p5svg) + GroupInterface(p5svg) // attach constants to p5 instance