diff --git a/src/library/core.ts b/src/library/core.ts index e0b9bbd..0c6c932 100644 --- a/src/library/core.ts +++ b/src/library/core.ts @@ -45,6 +45,7 @@ export class Waveform { protected _latestRange: number | null = null protected _plugins: [] = [] protected _waveClickCallback: IWaveClickCallback | null = null + protected _boundCanvasElementClick: ((event: MouseEvent) => void) | null = null constructor(waveCoreOptions?: IWaveCoreOptions) { @@ -130,13 +131,24 @@ export class Waveform { protected _addClickWaveListener(): void { - this._canvasElement.addEventListener('click', this._canvasElementClick.bind(this)) + // store the bound handler so removeEventListener can reference the + // exact same function; binding again on removal (as before) creates a + // new function reference and the listener is never actually removed + this._boundCanvasElementClick = this._canvasElementClick.bind(this) + + this._canvasElement.addEventListener('click', this._boundCanvasElementClick) } protected _removeClickWaveListener(): void { - this._canvasElement.removeEventListener('click', this._canvasElementClick.bind(this)) + if (this._boundCanvasElementClick !== null) { + + this._canvasElement.removeEventListener('click', this._boundCanvasElementClick) + + this._boundCanvasElementClick = null + + } } @@ -147,8 +159,19 @@ export class Waveform { event.preventDefault() const canvasHorizontalPositionInPixel = this._getMouseHorizontalPosition(event) - const pixelsPerPercent = this._canvasElement.width / 100 - const clickHorizontalPositionInPercent = canvasHorizontalPositionInPixel / pixelsPerPercent + + // the click position must be relative to the rendered (CSS) width + // of the canvas and not to canvas.width, which is the internal + // pixel resolution set during draw(); when the canvas is scaled + // via CSS (e.g. width: 100%) the two differ and dividing by + // canvas.width makes the error grow towards the right edge + const renderedWidth = this._canvasElement.getBoundingClientRect().width + + if (renderedWidth === 0) { + return + } + + const clickHorizontalPositionInPercent = (canvasHorizontalPositionInPixel / renderedWidth) * 100 this._waveClickCallback(clickHorizontalPositionInPercent)