From 5716c614a8cf49222fc1e53f2601607611d8820c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Sun, 11 Jul 2021 04:24:10 +0200 Subject: [PATCH] Cleanup drawing of RegularShape Fixes missing miter/bevel line join because path was not closed before stroking. Reduce canvas context calls, skip beginPath, and instead of drawing the last point use closePath --- src/ol/style/RegularShape.js | 112 ++++++++++++----------------------- 1 file changed, 37 insertions(+), 75 deletions(-) diff --git a/src/ol/style/RegularShape.js b/src/ol/style/RegularShape.js index a5de79c5d8..969790c64d 100644 --- a/src/ol/style/RegularShape.js +++ b/src/ol/style/RegularShape.js @@ -233,7 +233,7 @@ class RegularShape extends ImageStyle { renderOptions.size * pixelRatio || 1 ); - this.draw_(renderOptions, context, 0, 0, pixelRatio || 1); + this.draw_(renderOptions, context, pixelRatio || 1); this.canvas_[pixelRatio || 1] = context.canvas; } @@ -403,7 +403,7 @@ class RegularShape extends ImageStyle { renderOptions.size ); - this.draw_(renderOptions, context, 0, 0, 1); + this.draw_(renderOptions, context, 1); this.canvas_ = {}; this.canvas_[1] = context.canvas; @@ -425,46 +425,14 @@ class RegularShape extends ImageStyle { * @private * @param {RenderOptions} renderOptions Render options. * @param {CanvasRenderingContext2D} context The rendering context. - * @param {number} x The origin for the symbol (x). - * @param {number} y The origin for the symbol (y). * @param {number} pixelRatio The pixel ratio. */ - draw_(renderOptions, context, x, y, pixelRatio) { - let i, angle0, radiusC; + draw_(renderOptions, context, pixelRatio) { + context.scale(pixelRatio, pixelRatio); + // set origin to canvas center + context.translate(renderOptions.size / 2, renderOptions.size / 2); - // reset transform - context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); - - // then move to (x, y) - context.translate(x, y); - - context.beginPath(); - - let points = this.points_; - if (points === Infinity) { - context.arc( - renderOptions.size / 2, - renderOptions.size / 2, - this.radius_, - 0, - 2 * Math.PI, - true - ); - } else { - const radius2 = - this.radius2_ !== undefined ? this.radius2_ : this.radius_; - if (radius2 !== this.radius_) { - points = 2 * points; - } - for (i = 0; i <= points; i++) { - angle0 = (i * 2 * Math.PI) / points - Math.PI / 2 + this.angle_; - radiusC = i % 2 === 0 ? this.radius_ : radius2; - context.lineTo( - renderOptions.size / 2 + radiusC * Math.cos(angle0), - renderOptions.size / 2 + radiusC * Math.sin(angle0) - ); - } - } + this.createPath_(context); if (this.fill_) { let color = this.fill_.getColor(); @@ -486,7 +454,6 @@ class RegularShape extends ImageStyle { context.miterLimit = renderOptions.miterLimit; context.stroke(); } - context.closePath(); } /** @@ -516,7 +483,7 @@ class RegularShape extends ImageStyle { ); this.hitDetectionCanvas_ = context.canvas; - this.drawHitDetectionCanvas_(renderOptions, context, 0, 0); + this.drawHitDetectionCanvas_(renderOptions, context); } } if (!this.hitDetectionCanvas_) { @@ -524,45 +491,41 @@ class RegularShape extends ImageStyle { } } + /** + * @private + * @param {CanvasRenderingContext2D} context The context to draw in. + */ + createPath_(context) { + let points = this.points_; + const radius = this.radius_; + if (points === Infinity) { + context.arc(0, 0, radius, 0, 2 * Math.PI); + } else { + const radius2 = this.radius2_ !== undefined ? this.radius2_ : radius; + if (radius2 !== radius) { + points *= 2; + } + const startAngle = this.angle_ - Math.PI / 2; + const step = (2 * Math.PI) / points; + for (let i = 0; i < points; i++) { + const angle0 = startAngle + i * step; + const radiusC = i % 2 === 0 ? radius : radius2; + context.lineTo(radiusC * Math.cos(angle0), radiusC * Math.sin(angle0)); + } + context.closePath(); + } + } + /** * @private * @param {RenderOptions} renderOptions Render options. * @param {CanvasRenderingContext2D} context The context. - * @param {number} x The origin for the symbol (x). - * @param {number} y The origin for the symbol (y). */ - drawHitDetectionCanvas_(renderOptions, context, x, y) { - // move to (x, y) - context.translate(x, y); + drawHitDetectionCanvas_(renderOptions, context) { + // set origin to canvas center + context.translate(renderOptions.size / 2, renderOptions.size / 2); - context.beginPath(); - - let points = this.points_; - if (points === Infinity) { - context.arc( - renderOptions.size / 2, - renderOptions.size / 2, - this.radius_, - 0, - 2 * Math.PI, - true - ); - } else { - const radius2 = - this.radius2_ !== undefined ? this.radius2_ : this.radius_; - if (radius2 !== this.radius_) { - points = 2 * points; - } - let i, radiusC, angle0; - for (i = 0; i <= points; i++) { - angle0 = (i * 2 * Math.PI) / points - Math.PI / 2 + this.angle_; - radiusC = i % 2 === 0 ? this.radius_ : radius2; - context.lineTo( - renderOptions.size / 2 + radiusC * Math.cos(angle0), - renderOptions.size / 2 + radiusC * Math.sin(angle0) - ); - } - } + this.createPath_(context); context.fillStyle = defaultFillStyle; context.fill(); @@ -575,7 +538,6 @@ class RegularShape extends ImageStyle { } context.stroke(); } - context.closePath(); } }