diff --git a/src/core/graphics/canvas/CanvasGraphicsRenderer.js b/src/core/graphics/canvas/CanvasGraphicsRenderer.js index 47412af..09ce451 100644 --- a/src/core/graphics/canvas/CanvasGraphicsRenderer.js +++ b/src/core/graphics/canvas/CanvasGraphicsRenderer.js @@ -75,11 +75,64 @@ { context.beginPath(); - this.renderPolygon(shape.points, shape.closed, context); + let points = shape.points; + const holes = data.holes; + let outerArea; + let innerArea; - for (let j = 0; j < data.holes.length; j++) + context.moveTo(points[0], points[1]); + + for (let j = 2; j < points.length; j += 2) { - this.renderPolygon(data.holes[j].points, true, context); + context.lineTo(points[j], points[j + 1]); + } + + // if the first and last point are the same close the path - much neater :) + if (shape.closed) + { + context.closePath(); + } + + if (holes.length > 0) + { + outerArea = 0; + for (let j = 0; j < points.length; j += 2) + { + outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + } + + for (let k = 0; k < holes.length; k++) + { + points = holes[k].points; + + innerArea = 0; + for (let j = 0; j < points.length; j += 2) + { + innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + } + + context.moveTo(points[0], points[1]); + + if (innerArea * outerArea < 0) + { + for (let j = 2; j < points.length; j += 2) + { + context.lineTo(points[j], points[j + 1]); + } + } + else + { + for (let j = points.length - 2; j >= 2; j -= 2) + { + context.lineTo(points[j], points[j + 1]); + } + } + + if (holes[k].closed) + { + context.closePath(); + } + } } if (data.fill) diff --git a/src/core/graphics/canvas/CanvasGraphicsRenderer.js b/src/core/graphics/canvas/CanvasGraphicsRenderer.js index 47412af..09ce451 100644 --- a/src/core/graphics/canvas/CanvasGraphicsRenderer.js +++ b/src/core/graphics/canvas/CanvasGraphicsRenderer.js @@ -75,11 +75,64 @@ { context.beginPath(); - this.renderPolygon(shape.points, shape.closed, context); + let points = shape.points; + const holes = data.holes; + let outerArea; + let innerArea; - for (let j = 0; j < data.holes.length; j++) + context.moveTo(points[0], points[1]); + + for (let j = 2; j < points.length; j += 2) { - this.renderPolygon(data.holes[j].points, true, context); + context.lineTo(points[j], points[j + 1]); + } + + // if the first and last point are the same close the path - much neater :) + if (shape.closed) + { + context.closePath(); + } + + if (holes.length > 0) + { + outerArea = 0; + for (let j = 0; j < points.length; j += 2) + { + outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + } + + for (let k = 0; k < holes.length; k++) + { + points = holes[k].points; + + innerArea = 0; + for (let j = 0; j < points.length; j += 2) + { + innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + } + + context.moveTo(points[0], points[1]); + + if (innerArea * outerArea < 0) + { + for (let j = 2; j < points.length; j += 2) + { + context.lineTo(points[j], points[j + 1]); + } + } + else + { + for (let j = points.length - 2; j >= 2; j -= 2) + { + context.lineTo(points[j], points[j + 1]); + } + } + + if (holes[k].closed) + { + context.closePath(); + } + } } if (data.fill) diff --git a/src/core/renderers/canvas/utils/CanvasMaskManager.js b/src/core/renderers/canvas/utils/CanvasMaskManager.js index e3e52d4..daf6078 100644 --- a/src/core/renderers/canvas/utils/CanvasMaskManager.js +++ b/src/core/renderers/canvas/utils/CanvasMaskManager.js @@ -75,13 +75,16 @@ if (data.type === SHAPES.POLY) { - const points = shape.points; + let points = shape.points; + const holes = data.holes; + let outerArea; + let innerArea; context.moveTo(points[0], points[1]); - for (let j = 1; j < points.length / 2; j++) + for (let j = 2; j < points.length; j += 2) { - context.lineTo(points[j * 2], points[(j * 2) + 1]); + context.lineTo(points[j], points[j + 1]); } // if the first and last point are the same close the path - much neater :) @@ -89,6 +92,43 @@ { context.closePath(); } + + if (holes.length > 0) + { + outerArea = 0; + for (let j = 0; j < points.length; j += 2) + { + outerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + } + + for (let k = 0; k < holes.length; k++) + { + points = holes[k].points; + + innerArea = 0; + for (let j = 0; j < points.length; j += 2) + { + innerArea += (points[j] * points[j + 3]) - (points[j + 1] * points[j + 2]); + } + + context.moveTo(points[0], points[1]); + + if (innerArea * outerArea < 0) + { + for (let j = 2; j < points.length; j += 2) + { + context.lineTo(points[j], points[j + 1]); + } + } + else + { + for (let j = points.length - 2; j >= 2; j -= 2) + { + context.lineTo(points[j], points[j + 1]); + } + } + } + } } else if (data.type === SHAPES.RECT) {