@@ -25,8 +25,8 @@ p5.Renderer2D = function(elt, pInst, isMainCanvas){
2525p5 . Renderer2D . prototype = Object . create ( p5 . Renderer . prototype ) ;
2626
2727p5 . Renderer2D . prototype . _applyDefaults = function ( ) {
28- this . drawingContext . fillStyle = constants . _DEFAULT_FILL ;
29- this . drawingContext . strokeStyle = constants . _DEFAULT_STROKE ;
28+ this . _setFill ( constants . _DEFAULT_FILL ) ;
29+ this . _setStroke ( constants . _DEFAULT_STROKE ) ;
3030 this . drawingContext . lineCap = constants . ROUND ;
3131 this . drawingContext . font = 'normal 12px sans-serif' ;
3232} ;
@@ -50,14 +50,14 @@ p5.Renderer2D.prototype.background = function() {
5050 if ( arguments [ 0 ] instanceof p5 . Image ) {
5151 this . _pInst . image ( arguments [ 0 ] , 0 , 0 , this . width , this . height ) ;
5252 } else {
53- var curFill = this . drawingContext . fillStyle ;
53+ var curFill = this . _getFill ( ) ;
5454 // create background rect
5555 var color = this . _pInst . color . apply ( this , arguments ) ;
5656 var newFill = color . toString ( ) ;
57- this . drawingContext . fillStyle = newFill ;
57+ this . _setFill ( newFill ) ;
5858 this . drawingContext . fillRect ( 0 , 0 , this . width , this . height ) ;
5959 // reset fill
60- this . drawingContext . fillStyle = curFill ;
60+ this . _setFill ( curFill ) ;
6161 }
6262 this . drawingContext . restore ( ) ;
6363} ;
@@ -67,16 +67,13 @@ p5.Renderer2D.prototype.clear = function() {
6767} ;
6868
6969p5 . Renderer2D . prototype . fill = function ( ) {
70-
71- var ctx = this . drawingContext ;
7270 var color = this . _pInst . color . apply ( this , arguments ) ;
73- ctx . fillStyle = color . toString ( ) ;
71+ this . _setFill ( color . toString ( ) ) ;
7472} ;
7573
7674p5 . Renderer2D . prototype . stroke = function ( ) {
77- var ctx = this . drawingContext ;
7875 var color = this . _pInst . color . apply ( this , arguments ) ;
79- ctx . strokeStyle = color . toString ( ) ;
76+ this . _setStroke ( color . toString ( ) ) ;
8077} ;
8178
8279//////////////////////////////////////////////
@@ -453,11 +450,11 @@ p5.Renderer2D.prototype.ellipse = function(args) {
453450 w = args [ 2 ] ,
454451 h = args [ 3 ] ;
455452 if ( doFill && ! doStroke ) {
456- if ( ctx . fillStyle === styleEmpty ) {
453+ if ( this . _getFill ( ) === styleEmpty ) {
457454 return this ;
458455 }
459456 } else if ( ! doFill && doStroke ) {
460- if ( ctx . strokeStyle === styleEmpty ) {
457+ if ( this . _getStroke ( ) === styleEmpty ) {
461458 return this ;
462459 }
463460 }
@@ -487,7 +484,7 @@ p5.Renderer2D.prototype.line = function(x1, y1, x2, y2) {
487484 var ctx = this . drawingContext ;
488485 if ( ! this . _doStroke ) {
489486 return this ;
490- } else if ( ctx . strokeStyle === styleEmpty ) {
487+ } else if ( this . _getStroke ( ) === styleEmpty ) {
491488 return this ;
492489 }
493490 // Translate the line by (0.5, 0.5) to draw it crisp
@@ -506,16 +503,13 @@ p5.Renderer2D.prototype.line = function(x1, y1, x2, y2) {
506503
507504p5 . Renderer2D . prototype . point = function ( x , y ) {
508505 var ctx = this . drawingContext ;
509- var s = ctx . strokeStyle ;
510- var f = ctx . fillStyle ;
511506 if ( ! this . _doStroke ) {
512507 return this ;
513- } else if ( ctx . strokeStyle === styleEmpty ) {
508+ } else if ( this . _getStroke ( ) === styleEmpty ) {
514509 return this ;
515510 }
516511 x = Math . round ( x ) ;
517512 y = Math . round ( y ) ;
518- ctx . fillStyle = s ;
519513 if ( ctx . lineWidth > 1 ) {
520514 ctx . beginPath ( ) ;
521515 ctx . arc (
@@ -530,19 +524,18 @@ p5.Renderer2D.prototype.point = function(x, y) {
530524 } else {
531525 ctx . fillRect ( x , y , 1 , 1 ) ;
532526 }
533- ctx . fillStyle = f ;
534527} ;
535528
536529p5 . Renderer2D . prototype . quad =
537530 function ( x1 , y1 , x2 , y2 , x3 , y3 , x4 , y4 ) {
538531 var ctx = this . drawingContext ;
539532 var doFill = this . _doFill , doStroke = this . _doStroke ;
540533 if ( doFill && ! doStroke ) {
541- if ( ctx . fillStyle === styleEmpty ) {
534+ if ( this . _getFill ( ) === styleEmpty ) {
542535 return this ;
543536 }
544537 } else if ( ! doFill && doStroke ) {
545- if ( ctx . strokeStyle === styleEmpty ) {
538+ if ( this . _getStroke ( ) === styleEmpty ) {
546539 return this ;
547540 }
548541 }
@@ -573,11 +566,11 @@ p5.Renderer2D.prototype.rect = function(args) {
573566 var ctx = this . drawingContext ;
574567 var doFill = this . _doFill , doStroke = this . _doStroke ;
575568 if ( doFill && ! doStroke ) {
576- if ( ctx . fillStyle === styleEmpty ) {
569+ if ( this . _getFill ( ) === styleEmpty ) {
577570 return this ;
578571 }
579572 } else if ( ! doFill && doStroke ) {
580- if ( ctx . strokeStyle === styleEmpty ) {
573+ if ( this . _getStroke ( ) === styleEmpty ) {
581574 return this ;
582575 }
583576 }
@@ -638,11 +631,11 @@ p5.Renderer2D.prototype.triangle = function(args) {
638631 var x2 = args [ 2 ] , y2 = args [ 3 ] ;
639632 var x3 = args [ 4 ] , y3 = args [ 5 ] ;
640633 if ( doFill && ! doStroke ) {
641- if ( ctx . fillStyle === styleEmpty ) {
634+ if ( this . _getFill ( ) === styleEmpty ) {
642635 return this ;
643636 }
644637 } else if ( ! doFill && doStroke ) {
645- if ( ctx . strokeStyle === styleEmpty ) {
638+ if ( this . _getStroke ( ) === styleEmpty ) {
646639 return this ;
647640 }
648641 }
@@ -798,31 +791,35 @@ function (mode, vertices, isCurve, isBezier,
798791 }
799792 } else if ( shapeKind === constants . TRIANGLE_FAN ) {
800793 if ( numVerts > 2 ) {
794+ // For performance reasons, try to batch as many of the
795+ // fill and stroke calls as possible.
801796 this . drawingContext . beginPath ( ) ;
802- this . drawingContext . moveTo ( vertices [ 0 ] [ 0 ] , vertices [ 0 ] [ 1 ] ) ;
803- this . drawingContext . lineTo ( vertices [ 1 ] [ 0 ] , vertices [ 1 ] [ 1 ] ) ;
804- this . drawingContext . lineTo ( vertices [ 2 ] [ 0 ] , vertices [ 2 ] [ 1 ] ) ;
805- if ( this . _doFill ) {
806- this . _pInst . fill ( vertices [ 2 ] [ 5 ] ) ;
807- }
808- if ( this . _doStroke ) {
809- this . _pInst . stroke ( vertices [ 2 ] [ 6 ] ) ;
810- }
811- this . _doFillStrokeClose ( ) ;
812- for ( i = 3 ; i < numVerts ; i ++ ) {
797+ for ( i = 2 ; i < numVerts ; i ++ ) {
813798 v = vertices [ i ] ;
814- this . drawingContext . beginPath ( ) ;
815799 this . drawingContext . moveTo ( vertices [ 0 ] [ 0 ] , vertices [ 0 ] [ 1 ] ) ;
816800 this . drawingContext . lineTo ( vertices [ i - 1 ] [ 0 ] , vertices [ i - 1 ] [ 1 ] ) ;
817801 this . drawingContext . lineTo ( v [ 0 ] , v [ 1 ] ) ;
818- if ( this . _doFill ) {
819- this . _pInst . fill ( v [ 5 ] ) ;
820- }
821- if ( this . _doStroke ) {
822- this . _pInst . stroke ( v [ 6 ] ) ;
802+ this . drawingContext . lineTo ( vertices [ 0 ] [ 0 ] , vertices [ 0 ] [ 1 ] ) ;
803+ // If the next colour is going to be different, stroke / fill now
804+ if ( i < numVerts - 1 ) {
805+ if ( ( this . _doFill && v [ 5 ] !== vertices [ i + 1 ] [ 5 ] ) ||
806+ ( this . _doStroke && v [ 6 ] !== vertices [ i + 1 ] [ 6 ] ) ) {
807+ if ( this . _doFill ) {
808+ this . _pInst . fill ( v [ 5 ] ) ;
809+ this . drawingContext . fill ( ) ;
810+ this . _pInst . fill ( vertices [ i + 1 ] [ 5 ] ) ;
811+ }
812+ if ( this . _doStroke ) {
813+ this . _pInst . stroke ( v [ 6 ] ) ;
814+ this . drawingContext . stroke ( ) ;
815+ this . _pInst . stroke ( vertices [ i + 1 ] [ 6 ] ) ;
816+ }
817+ this . drawingContext . closePath ( ) ;
818+ this . drawingContext . beginPath ( ) ; // Begin the next one
819+ }
823820 }
824- this . _doFillStrokeClose ( ) ;
825821 }
822+ this . _doFillStrokeClose ( ) ;
826823 }
827824 } else if ( shapeKind === constants . QUADS ) {
828825 for ( i = 0 ; i + 3 < numVerts ; i += 4 ) {
@@ -954,13 +951,29 @@ p5.Renderer2D.prototype.strokeWeight = function(w) {
954951} ;
955952
956953p5 . Renderer2D . prototype . _getFill = function ( ) {
957- return this . drawingContext . fillStyle ;
954+ return this . _cachedFillStyle ;
955+ } ;
956+
957+ p5 . Renderer2D . prototype . _setFill = function ( fillStyle ) {
958+ if ( fillStyle !== this . _cachedFillStyle ) {
959+ this . drawingContext . fillStyle = fillStyle ;
960+ this . _cachedFillStyle = fillStyle ;
961+ }
958962} ;
959963
960964p5 . Renderer2D . prototype . _getStroke = function ( ) {
961- return this . drawingContext . strokeStyle ;
965+ return this . _cachedStrokeStyle ;
962966} ;
963967
968+ p5 . Renderer2D . prototype . _setStroke = function ( strokeStyle ) {
969+ if ( strokeStyle !== this . _cachedStrokeStyle ) {
970+ this . drawingContext . strokeStyle = strokeStyle ;
971+ this . _cachedStrokeStyle = strokeStyle ;
972+ }
973+ } ;
974+
975+
976+
964977//////////////////////////////////////////////
965978// SHAPE | Curves
966979//////////////////////////////////////////////
@@ -1187,8 +1200,9 @@ p5.Renderer2D.prototype._renderText = function(p, line, x, y, maxY) {
11871200 if ( this . _doFill ) {
11881201
11891202 // if fill hasn't been set by user, use default text fill
1190- this . drawingContext . fillStyle = this . _fillSet ?
1191- this . drawingContext . fillStyle : constants . _DEFAULT_TEXT_FILL ;
1203+ if ( ! this . _fillSet ) {
1204+ this . _setFill ( constants . _DEFAULT_TEXT_FILL ) ;
1205+ }
11921206
11931207 this . drawingContext . fillText ( line , x , y ) ;
11941208 }
@@ -1287,6 +1301,9 @@ p5.Renderer2D.prototype.push = function() {
12871301
12881302p5 . Renderer2D . prototype . pop = function ( ) {
12891303 this . drawingContext . restore ( ) ;
1304+ // Re-cache the fill / stroke state
1305+ this . _cachedFillStyle = this . drawingContext . fillStyle ;
1306+ this . _cachedStrokeStyle = this . drawingContext . strokeStyle ;
12901307} ;
12911308
12921309module . exports = p5 . Renderer2D ;
0 commit comments