From ae13902fbf28276398c8e6193228004c15ef59a7 Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Sat, 21 Oct 2023 14:35:01 +0200 Subject: [PATCH] Fix: avoid color bleed behind progress canvas (#3285) --- src/renderer.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/renderer.ts b/src/renderer.ts index 6c1405a8a..1144cc45f 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -432,17 +432,17 @@ class Renderer extends EventEmitter { ) // Draw a progress canvas - const progressCanvas = canvas.cloneNode() as HTMLCanvasElement - progressContainer.appendChild(progressCanvas) - const progressCtx = progressCanvas.getContext('2d') as CanvasRenderingContext2D if (canvas.width > 0 && canvas.height > 0) { + const progressCanvas = canvas.cloneNode() as HTMLCanvasElement + const progressCtx = progressCanvas.getContext('2d') as CanvasRenderingContext2D progressCtx.drawImage(canvas, 0, 0) + // Set the composition method to draw only where the waveform is drawn + progressCtx.globalCompositeOperation = 'source-in' + progressCtx.fillStyle = this.convertColorValues(options.progressColor) + // This rectangle acts as a mask thanks to the composition method + progressCtx.fillRect(0, 0, canvas.width, canvas.height) + progressContainer.appendChild(progressCanvas) } - // Set the composition method to draw only where the waveform is drawn - progressCtx.globalCompositeOperation = 'source-in' - progressCtx.fillStyle = this.convertColorValues(options.progressColor) - // This rectangle acts as a mask thanks to the composition method - progressCtx.fillRect(0, 0, canvas.width, canvas.height) } private renderChannel(channelData: Array, options: WaveSurferOptions, width: number) { @@ -632,9 +632,11 @@ class Renderer extends EventEmitter { renderProgress(progress: number, isPlaying?: boolean) { if (isNaN(progress)) return - this.progressWrapper.style.width = `${progress * 100}%` - this.cursor.style.left = `${progress * 100}%` - this.cursor.style.marginLeft = Math.round(progress * 100) === 100 ? `-${this.options.cursorWidth}px` : '' + const percents = progress * 100 + this.canvasWrapper.style.clipPath = `polygon(${percents}% 0, 100% 0, 100% 100%, ${percents}% 100%)` + this.progressWrapper.style.width = `${percents}%` + this.cursor.style.left = `${percents}%` + this.cursor.style.marginLeft = Math.round(percents) === 100 ? `-${this.options.cursorWidth}px` : '' if (this.isScrolling && this.options.autoScroll) { this.scrollIntoView(progress, isPlaying)