From 6de9c1d77d2173d181dbd969912f6d8fae9fc0f3 Mon Sep 17 00:00:00 2001 From: katspaugh Date: Sun, 17 Dec 2023 13:38:54 +0100 Subject: [PATCH] Fix: scroll when dragging --- examples/zoom.js | 1 + src/plugins/record.ts | 2 +- src/renderer.ts | 53 +++++++++++++++++++++---------------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/examples/zoom.js b/examples/zoom.js index 50eba83f6..66f69b805 100644 --- a/examples/zoom.js +++ b/examples/zoom.js @@ -8,6 +8,7 @@ const wavesurfer = WaveSurfer.create({ progressColor: 'rgb(100, 0, 100)', url: '/examples/audio/audio.wav', minPxPerSec: 100, + dragToSeek: true, }) // Create a simple slider diff --git a/src/plugins/record.ts b/src/plugins/record.ts index 196956e3f..c46397169 100644 --- a/src/plugins/record.ts +++ b/src/plugins/record.ts @@ -104,7 +104,7 @@ class RecordPlugin extends BasePlugin { if (this.wavesurfer) { this.originalOptions ??= { cursorWidth: this.wavesurfer.options.cursorWidth, - interact: this.wavesurfer.options.interact + interact: this.wavesurfer.options.interact, } this.wavesurfer.options.cursorWidth = 0 this.wavesurfer.options.interact = false diff --git a/src/renderer.ts b/src/renderer.ts index 1f7fc84f8..67d411fcd 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -597,38 +597,37 @@ class Renderer extends EventEmitter { } private scrollIntoView(progress: number, isPlaying = false) { - const { clientWidth, scrollLeft, scrollWidth } = this.scrollContainer - const progressWidth = scrollWidth * progress - const center = clientWidth / 2 - const minScroll = isPlaying && this.options.autoCenter && !this.isDragging ? center : clientWidth - - if (progressWidth > scrollLeft + minScroll || progressWidth < scrollLeft) { - // Scroll to the center - if (this.options.autoCenter && !this.isDragging) { - // If the cursor is in viewport but not centered, scroll to the center slowly - const minDiff = center / 20 - if (progressWidth - (scrollLeft + center) >= minDiff && progressWidth < scrollLeft + clientWidth) { - this.scrollContainer.scrollLeft += minDiff - } else { - // Otherwise, scroll to the center immediately - this.scrollContainer.scrollLeft = progressWidth - center - } - } else if (this.isDragging) { - // Scroll just a little bit to allow for some space between the cursor and the edge - const gap = 10 - this.scrollContainer.scrollLeft = - progressWidth < scrollLeft ? progressWidth - gap : progressWidth - clientWidth + gap - } else { - // Scroll to the beginning - this.scrollContainer.scrollLeft = progressWidth + const { scrollLeft, scrollWidth, clientWidth } = this.scrollContainer + const progressWidth = progress * scrollWidth + const startEdge = scrollLeft + const endEdge = scrollLeft + clientWidth + const middle = clientWidth / 2 + + if (this.isDragging) { + // Scroll when dragging close to the edge of the viewport + const minGap = 30 + if (progressWidth + minGap > endEdge) { + this.scrollContainer.scrollLeft += minGap + } else if (progressWidth - minGap < startEdge) { + this.scrollContainer.scrollLeft -= minGap + } + } else { + if (progressWidth < startEdge || progressWidth > endEdge) { + this.scrollContainer.scrollLeft = progressWidth - (this.options.autoCenter ? middle : 0) + } + + // Keep the cursor centered when playing + const center = progressWidth - scrollLeft - middle + if (isPlaying && this.options.autoCenter && center > 0) { + this.scrollContainer.scrollLeft += Math.min(center, 10) } } // Emit the scroll event { - const { scrollLeft } = this.scrollContainer - const startX = scrollLeft / scrollWidth - const endX = (scrollLeft + clientWidth) / scrollWidth + const newScroll = this.scrollContainer.scrollLeft + const startX = newScroll / scrollWidth + const endX = (newScroll + clientWidth) / scrollWidth this.emit('scroll', startX, endX) } }