diff --git a/src/Brush.ts b/src/Brush.ts index ce1c4e6..abf4ba1 100644 --- a/src/Brush.ts +++ b/src/Brush.ts @@ -1,12 +1,33 @@ export default class Brush { readonly ctx: CanvasRenderingContext2D; + private clippingPath?: Path2D; public mouseX: number; public mouseY: number; - constructor (ctx: CanvasRenderingContext2D, mouseX: number, mouseY: number) { + constructor (ctx: CanvasRenderingContext2D, mouseX: number, mouseY: number, clippingPath?: Path2D) { this.ctx = ctx; this.mouseX = mouseX; this.mouseY = mouseY; + this.clippingPath = clippingPath; + } + + startClipping() { + if (!this.clippingPath) { + return; + } + + this.ctx.save(); + + this.ctx.beginPath(); + this.ctx.clip(this.clippingPath); + } + + endClipping() { + if (!this.clippingPath) { + return; + } + + this.ctx.restore(); } updateMousePosition (x: number, y: number) { @@ -15,11 +36,15 @@ export default class Brush { } circle (r: number) { + this.startClipping(); + this.ctx.beginPath(); this.ctx.arc(this.mouseX + r, this.mouseY + r, r, 0, Math.PI * 2, false); this.ctx.fillStyle = '#000000'; this.ctx.fill(); this.ctx.closePath(); + + this.endClipping(); } /** @@ -52,11 +77,16 @@ export default class Brush { for (i; i < dropsCount; i++) { let points = this.clearPoint(area / 2); + + this.startClipping(); + this.ctx.beginPath(); this.ctx.arc(points[0] + (area / 2), points[1] + (area / 2), dropsSize / 2, 0, Math.PI * 2, false); this.ctx.fillStyle = '#000000'; this.ctx.fill(); this.ctx.closePath(); + + this.endClipping(); } } @@ -71,10 +101,15 @@ export default class Brush { return; } let angle = Math.atan2(this.mouseY, this.mouseX); + + this.startClipping(); + this.ctx.save(); this.ctx.translate(this.mouseX, this.mouseY); this.ctx.rotate(angle); this.ctx.drawImage(img, -(img.width / 2), -(img.height / 2)); + + this.endClipping(); } } diff --git a/src/ScratchCard.ts b/src/ScratchCard.ts index d429bdd..3ae4938 100644 --- a/src/ScratchCard.ts +++ b/src/ScratchCard.ts @@ -34,6 +34,7 @@ class ScratchCard { brushSrc: '', imageForwardSrc: './images/scratchcard.png', imageBackgroundSrc: './images/scratchcard-background.svg', + imageBackgroundClippingPath: undefined, htmlBackground: '', clearZoneRadius: 0, enabledPercentUpdate: true, @@ -53,7 +54,7 @@ class ScratchCard { this.ctx = this.canvas.getContext('2d'); // Init the brush instance - this.brush = new Brush(this.ctx, this.position[0], this.position[1]); + this.brush = new Brush(this.ctx, this.position[0], this.position[1], this.config.imageBackgroundClippingPath); // Init the brush if necessary if (this.config.scratchType === SCRATCH_TYPE.BRUSH) { diff --git a/src/ScratchCardConfig.ts b/src/ScratchCardConfig.ts index e91139d..7a32aac 100644 --- a/src/ScratchCardConfig.ts +++ b/src/ScratchCardConfig.ts @@ -10,6 +10,7 @@ export interface SC_CONFIG { containerHeight: number, imageForwardSrc: string, imageBackgroundSrc: string, + imageBackgroundClippingPath?: Path2D, htmlBackground: string, clearZoneRadius: number, nPoints: number, @@ -17,10 +18,10 @@ export interface SC_CONFIG { percentToFinish: number callback ?: () => void, brushSrc: string, - cursor: { + cursor?: { cur: string, png: string, poosition: number[] }, - enabledPercentUpdate: boolean + enabledPercentUpdate?: boolean } \ No newline at end of file