From a5e15232e63fbfe087df0e1e0f444f8abeb0c77a Mon Sep 17 00:00:00 2001 From: VANSH3104 Date: Thu, 6 Nov 2025 13:06:49 +0530 Subject: [PATCH 1/2] Fix transforms in clip() by using shape system for primitives using manual method --- src/core/p5.Renderer2D.js | 42 +++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js index 95286b0b51..f0889ac2f8 100644 --- a/src/core/p5.Renderer2D.js +++ b/src/core/p5.Renderer2D.js @@ -70,14 +70,18 @@ class Renderer2D extends Renderer { } this.scale(this._pixelDensity, this._pixelDensity); - if(!this.filterRenderer){ - this.filterRenderer = new FilterRenderer2D(this); - } // Set and return p5.Element this.wrappedElt = new Element(this.elt, this._pInst); this.clipPath = null; } + get filterRenderer() { + if (!this._filterRenderer) { + this._filterRenderer = new FilterRenderer2D(this); + } + return this._filterRenderer; + } + remove(){ this.wrappedElt.remove(); this.wrappedElt = null; @@ -301,6 +305,7 @@ class Renderer2D extends Renderer { // Start a new path. Everything from here on out should become part of this // one path so that we can clip to the whole thing. this.clipPath = new Path2D(); + this.initialClipTransform = this.drawingContext.getTransform().inverse(); if (this._clipInvert) { // Slight hack: draw a big rectangle over everything with reverse winding @@ -701,7 +706,7 @@ class Renderer2D extends Renderer { } ellipse(args) { - const ctx = this.clipPath || this.drawingContext; + const ctx = this.drawingContext; const doFill = !!this.states.fillColor, doStroke = this.states.strokeColor; const x = parseFloat(args[0]), @@ -721,17 +726,28 @@ class Renderer2D extends Renderer { centerY = y + h / 2, radiusX = w / 2, radiusY = h / 2; - if (!this._clipping) ctx.beginPath(); - - ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, 2 * Math.PI); - ctx.closePath(); + if (this._clipping) { + const tempPath = new Path2D(); + tempPath.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, 2 * Math.PI); - if (!this._clipping && doFill) { - ctx.fill(); - } - if (!this._clipping && doStroke) { - ctx.stroke(); + const currentTransform = this.drawingContext.getTransform(); + const initialClip = this.initialClipTransform; + const relativeTransform = initialClip.multiply(currentTransform); + this.clipPath.addPath(tempPath, relativeTransform); + } else { + // Normal drawing (existing code) + ctx.beginPath(); + ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, 2 * Math.PI); + ctx.closePath(); + if (doFill) { + ctx.fill(); + } + if (doStroke) { + ctx.stroke(); + } } + + return this; } line(x1, y1, x2, y2) { From cc98f19226242a80f86ccaac04b04483f10b6c91 Mon Sep 17 00:00:00 2001 From: VANSH3104 Date: Wed, 12 Nov 2025 18:27:10 +0530 Subject: [PATCH 2/2] Handle negative scales in clipping by using absolute values for scale components --- src/core/p5.Renderer2D.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js index f0889ac2f8..8cf36ae288 100644 --- a/src/core/p5.Renderer2D.js +++ b/src/core/p5.Renderer2D.js @@ -732,8 +732,19 @@ class Renderer2D extends Renderer { const currentTransform = this.drawingContext.getTransform(); const initialClip = this.initialClipTransform; - const relativeTransform = initialClip.multiply(currentTransform); - this.clipPath.addPath(tempPath, relativeTransform); + if (currentTransform.a < 0 || currentTransform.d < 0) { + const fixedTransform = new DOMMatrix([ + Math.abs(currentTransform.a), currentTransform.b, + currentTransform.c, Math.abs(currentTransform.d), + currentTransform.e, currentTransform.f + ]); + const relativeTransform = initialClip.multiply(fixedTransform); + this.clipPath.addPath(tempPath, relativeTransform); + } else { + // Normal case + const relativeTransform = initialClip.multiply(currentTransform); + this.clipPath.addPath(tempPath, relativeTransform); + } } else { // Normal drawing (existing code) ctx.beginPath();