From 741f71cf69b413343453bdf6395e1141054ff10a Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:10:20 +0200 Subject: [PATCH] Refactor: optimize Timeline virtual rendering (#3748) --- src/plugins/timeline.ts | 19 +++++++++++++------ src/renderer.ts | 6 +++--- src/wavesurfer.ts | 6 +++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/plugins/timeline.ts b/src/plugins/timeline.ts index 13fa3f7e0..712489fde 100644 --- a/src/plugins/timeline.ts +++ b/src/plugins/timeline.ts @@ -144,12 +144,15 @@ class TimelinePlugin extends BasePlugin { + let wasVisible = false + + const renderIfVisible = (scrollLeft: number, scrollRight: number) => { if (!this.wavesurfer) return - const clientWidth = this.wavesurfer.getWidth() - const scrollLeft = this.wavesurfer.getScroll() const width = element.clientWidth - const isVisible = start + width > scrollLeft && start < scrollLeft + clientWidth + const isVisible = start > scrollLeft && start + width < scrollRight + + if (isVisible === wasVisible) return + wasVisible = isVisible if (isVisible) { container.appendChild(element) @@ -160,8 +163,12 @@ class TimelinePlugin extends BasePlugin { if (!this.wavesurfer) return - renderIfVisible() - this.subscriptions.push(this.wavesurfer.on('scroll', renderIfVisible)) + renderIfVisible(0, this.wavesurfer?.getWidth() || 0) + this.subscriptions.push( + this.wavesurfer.on('scroll', (_start, _end, scrollLeft, scrollRight) => { + renderIfVisible(scrollLeft, scrollRight) + }), + ) }, 0) } diff --git a/src/renderer.ts b/src/renderer.ts index 9cc1b6a12..d668ff831 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -8,7 +8,7 @@ type RendererEvents = { drag: [relativeX: number] dragstart: [relativeX: number] dragend: [relativeX: number] - scroll: [relativeStart: number, relativeEnd: number] + scroll: [relativeStart: number, relativeEnd: number, scrollLeft: number, scrollRight: number] render: [] rendered: [] } @@ -105,7 +105,7 @@ class Renderer extends EventEmitter { const { scrollLeft, scrollWidth, clientWidth } = this.scrollContainer const startX = scrollLeft / scrollWidth const endX = (scrollLeft + clientWidth) / scrollWidth - this.emit('scroll', startX, endX) + this.emit('scroll', startX, endX, scrollLeft, scrollLeft + clientWidth) }) // Re-render the waveform on container resize @@ -730,7 +730,7 @@ class Renderer extends EventEmitter { const newScroll = this.scrollContainer.scrollLeft const startX = newScroll / scrollWidth const endX = (newScroll + clientWidth) / scrollWidth - this.emit('scroll', startX, endX) + this.emit('scroll', startX, endX, newScroll, newScroll + clientWidth) } } diff --git a/src/wavesurfer.ts b/src/wavesurfer.ts index c5a0b9243..0a1abf888 100644 --- a/src/wavesurfer.ts +++ b/src/wavesurfer.ts @@ -131,7 +131,7 @@ export type WaveSurferEvents = { /** When the user ends dragging the cursor */ dragend: [relativeX: number] /** When the waveform is scrolled (panned) */ - scroll: [visibleStartTime: number, visibleEndTime: number] + scroll: [visibleStartTime: number, visibleEndTime: number, scrollLeft: number, scrollRight: number] /** When the zoom level changes */ zoom: [minPxPerSec: number] /** Just before the waveform is destroyed so you can clean up your events */ @@ -275,9 +275,9 @@ class WaveSurfer extends Player { }), // Scroll - this.renderer.on('scroll', (startX, endX) => { + this.renderer.on('scroll', (startX, endX, scrollLeft, scrollRight) => { const duration = this.getDuration() - this.emit('scroll', startX * duration, endX * duration) + this.emit('scroll', startX * duration, endX * duration, scrollLeft, scrollRight) }), // Redraw