Skip to content

Commit 5a49130

Browse files
committed
implement clipping with transform support for all 2D shapes
1 parent fc826d4 commit 5a49130

1 file changed

Lines changed: 86 additions & 19 deletions

File tree

src/core/p5.Renderer2D.js

Lines changed: 86 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ class Renderer2D extends Renderer {
656656
* start <= stop < start + TWO_PI
657657
*/
658658
arc(x, y, w, h, start, stop, mode) {
659-
const ctx = this.clipPa || this.drawingContext;
659+
const ctx = this.drawingContext;
660660
const rx = w / 2.0;
661661
const ry = h / 2.0;
662662
const epsilon = 0.00001; // Smallest visible angle on displays up to 4K.
@@ -667,7 +667,14 @@ class Renderer2D extends Renderer {
667667
centerY = y + h / 2,
668668
radiusX = w / 2,
669669
radiusY = h / 2;
670-
670+
if (this._clipping) {
671+
const tempPath = new Path2D();
672+
tempPath.ellipse(centerX, centerY, radiusX, radiusY, 0, start, stop);
673+
const currentTransform = this.drawingContext.getTransform();
674+
const ClipBaseTransform = this._clipBaseTransform.inverse();
675+
const relativeTransform = ClipBaseTransform.multiply(currentTransform);
676+
this.clipPath.addPath(tempPath, relativeTransform);
677+
}
671678
// Determines whether to add a line to the center, which should be done
672679
// when the mode is PIE or default; as well as when the start and end
673680
// angles do not form a full circle.
@@ -753,28 +760,48 @@ class Renderer2D extends Renderer {
753760
}
754761

755762
line(x1, y1, x2, y2) {
756-
const ctx = this.clipPath || this.drawingContext;
763+
const ctx = this.drawingContext;
757764
if (!this.states.strokeColor) {
758765
return this;
759766
} else if (this._getStroke() === styleEmpty) {
760767
return this;
761768
}
769+
if (this._clipping) {
770+
const tempPath = new Path2D();
771+
tempPath.moveTo(x1, y1);
772+
tempPath.lineTo(x2, y2);
773+
const currentTransform = this.drawingContext.getTransform();
774+
const ClipBaseTransform = this._clipBaseTransform.inverse();
775+
const relativeTransform = ClipBaseTransform.multiply(currentTransform);
776+
this.clipPath.addPath(tempPath, relativeTransform);
777+
return this;
778+
}
762779
if (!this._clipping) ctx.beginPath();
763780
ctx.moveTo(x1, y1);
764781
ctx.lineTo(x2, y2);
765-
ctx.stroke();
782+
if (!this._clipping) ctx.stroke();
766783
return this;
767784
}
768785

769786
point(x, y) {
770-
const ctx = this.clipPath || this.drawingContext;
787+
const ctx = this.drawingContext;
771788
if (!this.states.strokeColor) {
772789
return this;
773790
} else if (this._getStroke() === styleEmpty) {
774791
return this;
775792
}
776793
const s = this._getStroke();
777794
const f = this._getFill();
795+
if (this._clipping) {
796+
const tempPath = new Path2D();
797+
const drawingContextWidth = this.drawingContext.lineWidth;
798+
tempPath.arc(x, y, drawingContextWidth / 2, 0, constants.TWO_PI);
799+
const currentTransform = this.drawingContext.getTransform();
800+
const ClipBaseTransform = this._clipBaseTransform.inverse();
801+
const relativeTransform = ClipBaseTransform.multiply(currentTransform);
802+
this.clipPath.addPath(tempPath, relativeTransform);
803+
return this;
804+
}
778805
if (!this._clipping) {
779806
// swapping fill color to stroke and back after for correct point rendering
780807
this._setFill(s);
@@ -785,10 +812,11 @@ class Renderer2D extends Renderer {
785812
ctx.fill();
786813
this._setFill(f);
787814
}
815+
return this;
788816
}
789817

790818
quad(x1, y1, x2, y2, x3, y3, x4, y4) {
791-
const ctx = this.clipPath || this.drawingContext;
819+
const ctx = this.drawingContext;
792820
const doFill = !!this.states.fillColor,
793821
doStroke = this.states.strokeColor;
794822
if (doFill && !doStroke) {
@@ -800,17 +828,30 @@ class Renderer2D extends Renderer {
800828
return this;
801829
}
802830
}
803-
if (!this._clipping) ctx.beginPath();
804-
ctx.moveTo(x1, y1);
805-
ctx.lineTo(x2, y2);
806-
ctx.lineTo(x3, y3);
807-
ctx.lineTo(x4, y4);
808-
ctx.closePath();
809-
if (!this._clipping && doFill) {
810-
ctx.fill();
811-
}
812-
if (!this._clipping && doStroke) {
813-
ctx.stroke();
831+
if (this._clipping) {
832+
const tempPath = new Path2D();
833+
tempPath.moveTo(x1, y1);
834+
tempPath.lineTo(x2, y2);
835+
tempPath.lineTo(x3, y3);
836+
tempPath.lineTo(x4, y4);
837+
tempPath.closePath();
838+
const currentTransform = this.drawingContext.getTransform();
839+
const ClipBaseTransform = this._clipBaseTransform.inverse();
840+
const relativeTransform = ClipBaseTransform.multiply(currentTransform);
841+
this.clipPath.addPath(tempPath, relativeTransform);
842+
} else{
843+
ctx.beginPath();
844+
ctx.moveTo(x1, y1);
845+
ctx.lineTo(x2, y2);
846+
ctx.lineTo(x3, y3);
847+
ctx.lineTo(x4, y4);
848+
ctx.closePath();
849+
if (!this._clipping && doFill) {
850+
ctx.fill();
851+
}
852+
if (!this._clipping && doStroke) {
853+
ctx.stroke();
854+
}
814855
}
815856
return this;
816857
}
@@ -824,7 +865,7 @@ class Renderer2D extends Renderer {
824865
let tr = args[5];
825866
let br = args[6];
826867
let bl = args[7];
827-
const ctx = this.clipPath || this.drawingContext;
868+
const ctx = this.drawingContext;
828869
const doFill = !!this.states.fillColor,
829870
doStroke = this.states.strokeColor;
830871
if (doFill && !doStroke) {
@@ -836,6 +877,19 @@ class Renderer2D extends Renderer {
836877
return this;
837878
}
838879
}
880+
if (this._clipping) {
881+
const tempPath = new Path2D();
882+
if (typeof tl === 'undefined') {
883+
tempPath.rect(x, y, w, h);
884+
} else {
885+
tempPath.roundRect(x, y, w, h, [tl, tr, br, bl]);
886+
}
887+
const currentTransform = this.drawingContext.getTransform();
888+
const ClipBaseTransform = this._clipBaseTransform.inverse();
889+
const relativeTransform = ClipBaseTransform.multiply(currentTransform);
890+
this.clipPath.addPath(tempPath, relativeTransform);
891+
return this;
892+
}
839893
if (!this._clipping) ctx.beginPath();
840894

841895
if (typeof tl === 'undefined') {
@@ -899,7 +953,7 @@ class Renderer2D extends Renderer {
899953

900954

901955
triangle(args) {
902-
const ctx = this.clipPath || this.drawingContext;
956+
const ctx = this.drawingContext;
903957
const doFill = !!this.states.fillColor,
904958
doStroke = this.states.strokeColor;
905959
const x1 = args[0],
@@ -917,6 +971,18 @@ class Renderer2D extends Renderer {
917971
return this;
918972
}
919973
}
974+
if (this._clipping) {
975+
const tempPath = new Path2D();
976+
tempPath.moveTo(x1, y1);
977+
tempPath.lineTo(x2, y2);
978+
tempPath.lineTo(x3, y3);
979+
tempPath.closePath();
980+
const currentTransform = this.drawingContext.getTransform();
981+
const ClipBaseTransform = this._clipBaseTransform.inverse();
982+
const relativeTransform = ClipBaseTransform.multiply(currentTransform);
983+
this.clipPath.addPath(tempPath, relativeTransform);
984+
return this;
985+
}
920986
if (!this._clipping) ctx.beginPath();
921987
ctx.moveTo(x1, y1);
922988
ctx.lineTo(x2, y2);
@@ -928,6 +994,7 @@ class Renderer2D extends Renderer {
928994
if (!this._clipping && doStroke) {
929995
ctx.stroke();
930996
}
997+
return this;
931998
}
932999

9331000
//////////////////////////////////////////////

0 commit comments

Comments
 (0)