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
This commit is contained in:
@@ -233,7 +233,7 @@ class RegularShape extends ImageStyle {
|
|||||||
renderOptions.size * pixelRatio || 1
|
renderOptions.size * pixelRatio || 1
|
||||||
);
|
);
|
||||||
|
|
||||||
this.draw_(renderOptions, context, 0, 0, pixelRatio || 1);
|
this.draw_(renderOptions, context, pixelRatio || 1);
|
||||||
|
|
||||||
this.canvas_[pixelRatio || 1] = context.canvas;
|
this.canvas_[pixelRatio || 1] = context.canvas;
|
||||||
}
|
}
|
||||||
@@ -403,7 +403,7 @@ class RegularShape extends ImageStyle {
|
|||||||
renderOptions.size
|
renderOptions.size
|
||||||
);
|
);
|
||||||
|
|
||||||
this.draw_(renderOptions, context, 0, 0, 1);
|
this.draw_(renderOptions, context, 1);
|
||||||
|
|
||||||
this.canvas_ = {};
|
this.canvas_ = {};
|
||||||
this.canvas_[1] = context.canvas;
|
this.canvas_[1] = context.canvas;
|
||||||
@@ -425,46 +425,14 @@ class RegularShape extends ImageStyle {
|
|||||||
* @private
|
* @private
|
||||||
* @param {RenderOptions} renderOptions Render options.
|
* @param {RenderOptions} renderOptions Render options.
|
||||||
* @param {CanvasRenderingContext2D} context The rendering context.
|
* @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.
|
* @param {number} pixelRatio The pixel ratio.
|
||||||
*/
|
*/
|
||||||
draw_(renderOptions, context, x, y, pixelRatio) {
|
draw_(renderOptions, context, pixelRatio) {
|
||||||
let i, angle0, radiusC;
|
context.scale(pixelRatio, pixelRatio);
|
||||||
|
// set origin to canvas center
|
||||||
|
context.translate(renderOptions.size / 2, renderOptions.size / 2);
|
||||||
|
|
||||||
// reset transform
|
this.createPath_(context);
|
||||||
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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.fill_) {
|
if (this.fill_) {
|
||||||
let color = this.fill_.getColor();
|
let color = this.fill_.getColor();
|
||||||
@@ -486,7 +454,6 @@ class RegularShape extends ImageStyle {
|
|||||||
context.miterLimit = renderOptions.miterLimit;
|
context.miterLimit = renderOptions.miterLimit;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
}
|
}
|
||||||
context.closePath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -516,7 +483,7 @@ class RegularShape extends ImageStyle {
|
|||||||
);
|
);
|
||||||
this.hitDetectionCanvas_ = context.canvas;
|
this.hitDetectionCanvas_ = context.canvas;
|
||||||
|
|
||||||
this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);
|
this.drawHitDetectionCanvas_(renderOptions, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.hitDetectionCanvas_) {
|
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
|
* @private
|
||||||
* @param {RenderOptions} renderOptions Render options.
|
* @param {RenderOptions} renderOptions Render options.
|
||||||
* @param {CanvasRenderingContext2D} context The context.
|
* @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) {
|
drawHitDetectionCanvas_(renderOptions, context) {
|
||||||
// move to (x, y)
|
// set origin to canvas center
|
||||||
context.translate(x, y);
|
context.translate(renderOptions.size / 2, renderOptions.size / 2);
|
||||||
|
|
||||||
context.beginPath();
|
this.createPath_(context);
|
||||||
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context.fillStyle = defaultFillStyle;
|
context.fillStyle = defaultFillStyle;
|
||||||
context.fill();
|
context.fill();
|
||||||
@@ -575,7 +538,6 @@ class RegularShape extends ImageStyle {
|
|||||||
}
|
}
|
||||||
context.stroke();
|
context.stroke();
|
||||||
}
|
}
|
||||||
context.closePath();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user