Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: scroll when dragging #3417

Merged
merged 1 commit into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class RecordPlugin extends BasePlugin<RecordPluginEvents, RecordPluginOptions> {
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
Expand Down
53 changes: 26 additions & 27 deletions src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,38 +597,37 @@ class Renderer extends EventEmitter<RendererEvents> {
}

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)
}
}
Expand Down