Skip to content

fix: correct click percentage and listener removal#13

Open
chrisweb wants to merge 1 commit into
mainfrom
fix/click-position-and-listener-removal
Open

fix: correct click percentage and listener removal#13
chrisweb wants to merge 1 commit into
mainfrom
fix/click-position-and-listener-removal

Conversation

@chrisweb

Copy link
Copy Markdown
Owner

Summary

Fixes two bugs in the waveform canvas click handling (src/library/core.ts).

1. Click percentage is wrong on a CSS-scaled canvas

_canvasElementClick measured the click offset in CSS pixels (getBoundingClientRect()) but divided by canvas.width, which is the internal pixel resolution set in draw() (e.g. 200 * 2 + 199 * 1 = 599px for 200 peaks).

When the canvas is scaled with CSS (e.g. width: 100%), the rendered width and canvas.width differ, so the reported percentage is off and the error grows toward the right edge — a click at the far right of a 300px-wide canvas reports 300 / (599/100) ≈ 50% instead of 100%.

The fix divides by the rendered width from getBoundingClientRect().width, which matches the README's stated behaviour (position relative to the rendered canvas width) and is correct regardless of internal resolution / devicePixelRatio. Guards against a zero rendered width.

2. Click listener is never removed on destroy()

_removeClickWaveListener() called this._canvasElementClick.bind(this) again — a new function reference — so removeEventListener never matched the listener added by _addClickWaveListener(). The listener leaked, and consumers that re-create a Waveform on the same canvas accumulated handlers.

The bound handler is now stored once (_boundCanvasElementClick) and reused for both add and remove.

Testing

  • npm run lint passes
  • tsc --noEmit on src/index.ts (strict) passes

(npm run build fails locally on a missing tslib, unrelated to this change.)

Two bugs in the waveform click handling:

1. Click position used canvas.width (the internal pixel resolution set
   in draw(), e.g. 599px for 200 peaks) as the divisor while measuring
   the click offset in CSS pixels via getBoundingClientRect(). When the
   canvas is scaled with CSS (e.g. width: 100%) the two units differ, so
   the reported percent is wrong and the error grows toward the right
   edge. Now divides by the rendered width from getBoundingClientRect().

2. _removeClickWaveListener() called .bind(this) again, producing a new
   function reference, so removeEventListener never matched the listener
   added in _addClickWaveListener() and the listener leaked on destroy().
   The bound handler is now stored and reused for add and remove.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant