@@ -306,6 +306,7 @@ class Renderer2D extends Renderer {
306306 // Start a new path. Everything from here on out should become part of this
307307 // one path so that we can clip to the whole thing.
308308 this . clipPath = new Path2D ( ) ;
309+ this . _clipBaseTransform = this . drawingContext . getTransform ( ) ;
309310
310311 if ( this . _clipInvert ) {
311312 // Slight hack: draw a big rectangle over everything with reverse winding
@@ -331,7 +332,11 @@ class Renderer2D extends Renderer {
331332 }
332333
333334 endClip ( ) {
335+ const savedTransform = this . drawingContext . getTransform ( ) ;
336+ this . drawingContext . setTransform ( this . _clipBaseTransform ) ;
334337 this . drawingContext . clip ( this . clipPath ) ;
338+ this . drawingContext . setTransform ( savedTransform ) ;
339+
335340 this . clipPath = null ;
336341
337342 super . endClip ( ) ;
@@ -652,7 +657,7 @@ class Renderer2D extends Renderer {
652657 * start <= stop < start + TWO_PI
653658 */
654659 arc ( x , y , w , h , start , stop , mode ) {
655- const ctx = this . clipPa || this . drawingContext ;
660+ const ctx = this . drawingContext ;
656661 const rx = w / 2.0 ;
657662 const ry = h / 2.0 ;
658663 const epsilon = 0.00001 ; // Smallest visible angle on displays up to 4K.
@@ -663,7 +668,15 @@ class Renderer2D extends Renderer {
663668 centerY = y + h / 2 ,
664669 radiusX = w / 2 ,
665670 radiusY = h / 2 ;
666-
671+ if ( this . _clipping ) {
672+ const tempPath = new Path2D ( ) ;
673+ tempPath . ellipse ( centerX , centerY , radiusX , radiusY , 0 , start , stop ) ;
674+ const currentTransform = this . drawingContext . getTransform ( ) ;
675+ const clipBaseTransform = this . _clipBaseTransform . inverse ( ) ;
676+ const relativeTransform = clipBaseTransform . multiply ( currentTransform ) ;
677+ this . clipPath . addPath ( tempPath , relativeTransform ) ;
678+ return this ;
679+ }
667680 // Determines whether to add a line to the center, which should be done
668681 // when the mode is PIE or default; as well as when the start and end
669682 // angles do not form a full circle.
@@ -675,16 +688,16 @@ class Renderer2D extends Renderer {
675688
676689 // Fill curves
677690 if ( this . states . fillColor ) {
678- if ( ! this . _clipping ) ctx . beginPath ( ) ;
691+ ctx . beginPath ( ) ;
679692 ctx . ellipse ( centerX , centerY , radiusX , radiusY , 0 , start , stop ) ;
680693 if ( createPieSlice ) ctx . lineTo ( centerX , centerY ) ;
681694 ctx . closePath ( ) ;
682- if ( ! this . _clipping ) ctx . fill ( ) ;
695+ ctx . fill ( ) ;
683696 }
684697
685698 // Stroke curves
686699 if ( this . states . strokeColor ) {
687- if ( ! this . _clipping ) ctx . beginPath ( ) ;
700+ ctx . beginPath ( ) ;
688701 ctx . ellipse ( centerX , centerY , radiusX , radiusY , 0 , start , stop ) ;
689702
690703 if ( mode === constants . PIE && createPieSlice ) {
@@ -697,16 +710,15 @@ class Renderer2D extends Renderer {
697710 // Stroke connects back to path begin for both PIE and CHORD
698711 ctx . closePath ( ) ;
699712 }
700-
701- if ( ! this . _clipping ) ctx . stroke ( ) ;
713+ ctx . stroke ( ) ;
702714 }
703715
704716 return this ;
705717
706718 }
707719
708720 ellipse ( args ) {
709- const ctx = this . clipPath || this . drawingContext ;
721+ const ctx = this . drawingContext ;
710722 const doFill = ! ! this . states . fillColor ,
711723 doStroke = this . states . strokeColor ;
712724 const x = parseFloat ( args [ 0 ] ) ,
@@ -726,56 +738,83 @@ class Renderer2D extends Renderer {
726738 centerY = y + h / 2 ,
727739 radiusX = w / 2 ,
728740 radiusY = h / 2 ;
729- if ( ! this . _clipping ) ctx . beginPath ( ) ;
730-
741+ if ( this . _clipping ) {
742+ const tempPath = new Path2D ( ) ;
743+ tempPath . ellipse ( centerX , centerY , radiusX , radiusY , 0 , 0 , 2 * Math . PI ) ;
744+ const currentTransform = this . drawingContext . getTransform ( ) ;
745+ const clipBaseTransform = this . _clipBaseTransform . inverse ( ) ;
746+ const relativeTransform = clipBaseTransform . multiply ( currentTransform ) ;
747+ this . clipPath . addPath ( tempPath , relativeTransform ) ;
748+ return this ;
749+ }
750+ ctx . beginPath ( ) ;
731751 ctx . ellipse ( centerX , centerY , radiusX , radiusY , 0 , 0 , 2 * Math . PI ) ;
732752 ctx . closePath ( ) ;
733-
734- if ( ! this . _clipping && doFill ) {
753+ if ( doFill ) {
735754 ctx . fill ( ) ;
736755 }
737- if ( ! this . _clipping && doStroke ) {
756+ if ( doStroke ) {
738757 ctx . stroke ( ) ;
739758 }
759+
760+ return this ;
740761 }
741762
742763 line ( x1 , y1 , x2 , y2 ) {
743- const ctx = this . clipPath || this . drawingContext ;
764+ const ctx = this . drawingContext ;
744765 if ( ! this . states . strokeColor ) {
745766 return this ;
746767 } else if ( this . _getStroke ( ) === styleEmpty ) {
747768 return this ;
748769 }
749- if ( ! this . _clipping ) ctx . beginPath ( ) ;
770+ if ( this . _clipping ) {
771+ const tempPath = new Path2D ( ) ;
772+ tempPath . moveTo ( x1 , y1 ) ;
773+ tempPath . lineTo ( x2 , y2 ) ;
774+ const currentTransform = this . drawingContext . getTransform ( ) ;
775+ const clipBaseTransform = this . _clipBaseTransform . inverse ( ) ;
776+ const relativeTransform = clipBaseTransform . multiply ( currentTransform ) ;
777+ this . clipPath . addPath ( tempPath , relativeTransform ) ;
778+ return this ;
779+ }
780+ ctx . beginPath ( ) ;
750781 ctx . moveTo ( x1 , y1 ) ;
751782 ctx . lineTo ( x2 , y2 ) ;
752783 ctx . stroke ( ) ;
784+
753785 return this ;
754786 }
755787
756788 point ( x , y ) {
757- const ctx = this . clipPath || this . drawingContext ;
789+ const ctx = this . drawingContext ;
758790 if ( ! this . states . strokeColor ) {
759791 return this ;
760792 } else if ( this . _getStroke ( ) === styleEmpty ) {
761793 return this ;
762794 }
763795 const s = this . _getStroke ( ) ;
764796 const f = this . _getFill ( ) ;
765- if ( ! this . _clipping ) {
766- // swapping fill color to stroke and back after for correct point rendering
767- this . _setFill ( s ) ;
797+ if ( this . _clipping ) {
798+ const tempPath = new Path2D ( ) ;
799+ const drawingContextWidth = this . drawingContext . lineWidth ;
800+ tempPath . arc ( x , y , drawingContextWidth / 2 , 0 , constants . TWO_PI ) ;
801+ const currentTransform = this . drawingContext . getTransform ( ) ;
802+ const clipBaseTransform = this . _clipBaseTransform . inverse ( ) ;
803+ const relativeTransform = clipBaseTransform . multiply ( currentTransform ) ;
804+ this . clipPath . addPath ( tempPath , relativeTransform ) ;
805+ return this ;
768806 }
769- if ( ! this . _clipping ) ctx . beginPath ( ) ;
807+ this . _setFill ( s ) ;
808+ ctx . beginPath ( ) ;
770809 ctx . arc ( x , y , ctx . lineWidth / 2 , 0 , constants . TWO_PI , false ) ;
771- if ( ! this . _clipping ) {
772- ctx . fill ( ) ;
773- this . _setFill ( f ) ;
774- }
810+ ctx . fill ( ) ;
811+ this . _setFill ( f ) ;
812+
813+ return this ;
775814 }
776815
777816 quad ( x1 , y1 , x2 , y2 , x3 , y3 , x4 , y4 ) {
778- const ctx = this . clipPath || this . drawingContext ;
817+ const ctx = this . drawingContext ;
779818 const doFill = ! ! this . states . fillColor ,
780819 doStroke = this . states . strokeColor ;
781820 if ( doFill && ! doStroke ) {
@@ -787,16 +826,29 @@ class Renderer2D extends Renderer {
787826 return this ;
788827 }
789828 }
790- if ( ! this . _clipping ) ctx . beginPath ( ) ;
829+ if ( this . _clipping ) {
830+ const tempPath = new Path2D ( ) ;
831+ tempPath . moveTo ( x1 , y1 ) ;
832+ tempPath . lineTo ( x2 , y2 ) ;
833+ tempPath . lineTo ( x3 , y3 ) ;
834+ tempPath . lineTo ( x4 , y4 ) ;
835+ tempPath . closePath ( ) ;
836+ const currentTransform = this . drawingContext . getTransform ( ) ;
837+ const clipBaseTransform = this . _clipBaseTransform . inverse ( ) ;
838+ const relativeTransform = clipBaseTransform . multiply ( currentTransform ) ;
839+ this . clipPath . addPath ( tempPath , relativeTransform ) ;
840+ return this ;
841+ }
842+ ctx . beginPath ( ) ;
791843 ctx . moveTo ( x1 , y1 ) ;
792844 ctx . lineTo ( x2 , y2 ) ;
793845 ctx . lineTo ( x3 , y3 ) ;
794846 ctx . lineTo ( x4 , y4 ) ;
795847 ctx . closePath ( ) ;
796- if ( ! this . _clipping && doFill ) {
848+ if ( doFill ) {
797849 ctx . fill ( ) ;
798850 }
799- if ( ! this . _clipping && doStroke ) {
851+ if ( doStroke ) {
800852 ctx . stroke ( ) ;
801853 }
802854 return this ;
@@ -811,7 +863,7 @@ class Renderer2D extends Renderer {
811863 let tr = args [ 5 ] ;
812864 let br = args [ 6 ] ;
813865 let bl = args [ 7 ] ;
814- const ctx = this . clipPath || this . drawingContext ;
866+ const ctx = this . drawingContext ;
815867 const doFill = ! ! this . states . fillColor ,
816868 doStroke = this . states . strokeColor ;
817869 if ( doFill && ! doStroke ) {
@@ -823,8 +875,20 @@ class Renderer2D extends Renderer {
823875 return this ;
824876 }
825877 }
826- if ( ! this . _clipping ) ctx . beginPath ( ) ;
827-
878+ if ( this . _clipping ) {
879+ const tempPath = new Path2D ( ) ;
880+ if ( typeof tl === 'undefined' ) {
881+ tempPath . rect ( x , y , w , h ) ;
882+ } else {
883+ tempPath . roundRect ( x , y , w , h , [ tl , tr , br , bl ] ) ;
884+ }
885+ const currentTransform = this . drawingContext . getTransform ( ) ;
886+ const clipBaseTransform = this . _clipBaseTransform . inverse ( ) ;
887+ const relativeTransform = clipBaseTransform . multiply ( currentTransform ) ;
888+ this . clipPath . addPath ( tempPath , relativeTransform ) ;
889+ return this ;
890+ }
891+ ctx . beginPath ( ) ;
828892 if ( typeof tl === 'undefined' ) {
829893 // No rounded corners
830894 ctx . rect ( x , y , w , h ) ;
@@ -875,18 +939,18 @@ class Renderer2D extends Renderer {
875939
876940 ctx . roundRect ( x , y , w , h , [ tl , tr , br , bl ] ) ;
877941 }
878- if ( ! this . _clipping && this . states . fillColor ) {
942+ if ( doFill ) {
879943 ctx . fill ( ) ;
880944 }
881- if ( ! this . _clipping && this . states . strokeColor ) {
945+ if ( doStroke ) {
882946 ctx . stroke ( ) ;
883947 }
884948 return this ;
885949 }
886950
887951
888952 triangle ( args ) {
889- const ctx = this . clipPath || this . drawingContext ;
953+ const ctx = this . drawingContext ;
890954 const doFill = ! ! this . states . fillColor ,
891955 doStroke = this . states . strokeColor ;
892956 const x1 = args [ 0 ] ,
@@ -904,17 +968,31 @@ class Renderer2D extends Renderer {
904968 return this ;
905969 }
906970 }
907- if ( ! this . _clipping ) ctx . beginPath ( ) ;
971+ if ( this . _clipping ) {
972+ const tempPath = new Path2D ( ) ;
973+ tempPath . moveTo ( x1 , y1 ) ;
974+ tempPath . lineTo ( x2 , y2 ) ;
975+ tempPath . lineTo ( x3 , y3 ) ;
976+ tempPath . closePath ( ) ;
977+ const currentTransform = this . drawingContext . getTransform ( ) ;
978+ const clipBaseTransform = this . _clipBaseTransform . inverse ( ) ;
979+ const relativeTransform = clipBaseTransform . multiply ( currentTransform ) ;
980+ this . clipPath . addPath ( tempPath , relativeTransform ) ;
981+ return this ;
982+ }
983+ ctx . beginPath ( ) ;
908984 ctx . moveTo ( x1 , y1 ) ;
909985 ctx . lineTo ( x2 , y2 ) ;
910986 ctx . lineTo ( x3 , y3 ) ;
911987 ctx . closePath ( ) ;
912- if ( ! this . _clipping && doFill ) {
988+ if ( doFill ) {
913989 ctx . fill ( ) ;
914990 }
915- if ( ! this . _clipping && doStroke ) {
991+ if ( doStroke ) {
916992 ctx . stroke ( ) ;
917993 }
994+
995+ return this ;
918996 }
919997
920998 //////////////////////////////////////////////
0 commit comments