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

Timeline disappear when zooming #3782

Closed
SectionSoutienAnalytique opened this issue Jul 12, 2024 · 4 comments · Fixed by #3918
Closed

Timeline disappear when zooming #3782

SectionSoutienAnalytique opened this issue Jul 12, 2024 · 4 comments · Fixed by #3918
Labels

Comments

@SectionSoutienAnalytique
Copy link

SectionSoutienAnalytique commented Jul 12, 2024

Bug description

In the Timeline plugin, when zooming in, the timeline disappears. It does not update correctly. However, as soon as the scrollbar is moved, the timeline updates properly.

Environment

  • Browser: Firefox

Minimal code snippet

// Customized Timeline plugin

import WaveSurfer from 'wavesurfer.js'
import TimelinePlugin from 'wavesurfer.js/dist/plugins/timeline.esm.js'
import ZoomPlugin from 'wavesurfer.js/dist/plugins/zoom.esm.js'

// Create a timeline plugin instance with custom options
const topTimeline = TimelinePlugin.create({
  height: 20,
  insertPosition: 'beforebegin',
  timeInterval: 0.2,
  primaryLabelInterval: 5,
  secondaryLabelInterval: 1,
  style: {
    fontSize: '20px',
    color: '#FFFFFF',
  },
})

// Create a second timeline
const bottomTimeline = TimelinePlugin.create({
  height: 10,
  timeInterval: 0.1,
  primaryLabelInterval: 1,
  style: {
    fontSize: '10px',
    color: '#6A3274',
  },
})

// Create an instance of WaveSurfer
const wavesurfer = WaveSurfer.create({
  container: '#waveform',
  waveColor: 'rgb(200, 0, 200)',
  progressColor: 'rgb(100, 0, 100)',
  url: '/examples/audio/audio.wav',
  minPxPerSec: 100,
  plugins: [topTimeline, bottomTimeline],
})

wavesurfer.registerPlugin(ZoomPlugin.create())

// Play on click
wavesurfer.once('interaction', () => {
  wavesurfer.play()
})

/*
<html>
  <div id="waveform"></div>
  <p>
    📖 <a href="https://wavesurfer.xyz/docs/classes/plugins_timeline.TimelinePlugin">Timeline plugin docs</a>
  </p>
</html>
*/

Expected result

GoodTimeline.mp4

Obtained result

BadTimeline.mp4

PR

I fix the issue (like you can see in the Expected result) but I do not know how to create PR

@rk9155
Copy link

rk9155 commented Jul 17, 2024

@SectionSoutienAnalytique
I solved this issue by wrapping the container of waveform to timeline plugin
wavesurfer.registerPlugin( TimelinePlugin.create({ height: 18, insertPosition: 'beforebegin', style: { fontSize: '12px', color: '#000', }, container: this.wavesurfer.getWrapper(), }), );
This resolves the issue for me

@amblamps
Copy link

amblamps commented Sep 26, 2024

Bug description

In the Timeline plugin, when zooming in, the timeline disappears. It does not update correctly. However, as soon as the scrollbar is moved, the timeline updates properly.

Environment

  • Browser: Firefox

Minimal code snippet

// Customized Timeline plugin

import WaveSurfer from 'wavesurfer.js'
import TimelinePlugin from 'wavesurfer.js/dist/plugins/timeline.esm.js'
import ZoomPlugin from 'wavesurfer.js/dist/plugins/zoom.esm.js'

// Create a timeline plugin instance with custom options
const topTimeline = TimelinePlugin.create({
  height: 20,
  insertPosition: 'beforebegin',
  timeInterval: 0.2,
  primaryLabelInterval: 5,
  secondaryLabelInterval: 1,
  style: {
    fontSize: '20px',
    color: '#FFFFFF',
  },
})

// Create a second timeline
const bottomTimeline = TimelinePlugin.create({
  height: 10,
  timeInterval: 0.1,
  primaryLabelInterval: 1,
  style: {
    fontSize: '10px',
    color: '#6A3274',
  },
})

// Create an instance of WaveSurfer
const wavesurfer = WaveSurfer.create({
  container: '#waveform',
  waveColor: 'rgb(200, 0, 200)',
  progressColor: 'rgb(100, 0, 100)',
  url: '/examples/audio/audio.wav',
  minPxPerSec: 100,
  plugins: [topTimeline, bottomTimeline],
})

wavesurfer.registerPlugin(ZoomPlugin.create())

// Play on click
wavesurfer.once('interaction', () => {
  wavesurfer.play()
})

/*
<html>
  <div id="waveform"></div>
  <p>
    📖 <a href="https://wavesurfer.xyz/docs/classes/plugins_timeline.TimelinePlugin">Timeline plugin docs</a>
  </p>
</html>
*/

Expected result

GoodTimeline.mp4

Obtained result

BadTimeline.mp4

PR

I fix the issue (like you can see in the Expected result) but I do not know how to create PR

How did you fix the timeline flashing/disappearing? The suggestion from @rk9155 does not work for me using wavesurfer/react

@SectionSoutienAnalytique
Copy link
Author

It does not work for me neither.

I do not know if it's good but i do not see any problem with another plugin. There is my modification :

//timeline.js

//line 94 add
this.subscriptions.push(this.wavesurfer.on('zoom', () => this.initTimeline()))

// delete line 146 to 174

  private virtualAppend(start: number, container: HTMLElement, element: HTMLElement) {
    let wasVisible = false

    const renderIfVisible = (scrollLeft: number, scrollRight: number) => {
      if (!this.wavesurfer) return
      const width = element.clientWidth
      const isVisible = start > scrollLeft && start + width < scrollRight

      if (isVisible === wasVisible) return
      wasVisible = isVisible

      if (isVisible) {
        container.appendChild(element)
      } else {
        element.remove()
      }
    }

    setTimeout(() => {
      if (!this.wavesurfer) return
      renderIfVisible(0, this.wavesurfer?.getWidth() || 0)
      this.subscriptions.push(
        this.wavesurfer.on('scroll', (_start, _end, scrollLeft, scrollRight) => {
          renderIfVisible(scrollLeft, scrollRight)
        }),
      )
    }, 0)
  }
  
  //line 251 replace this.virtualAppend(offset, timeline, notch)
  //display directly notch
  timeline.appendChild(notch)
  

With this you can see result on the video

@acieslewicz
Copy link
Contributor

I've looked into this a bit myself. This seems to happen when you zoom with a shifted cursor position. From what I can tell, the issue comes from the fact that the wave is reRendered on zoom which causes the timeline plugin to be reinitialized. It seems that the rerender adjusts the scroll window to account for the cursor position but the timeline assumes a 0 starting position and as a result the incorrect notches are rendered.

A change like this fixes the issue without having to remove virtualAppend:

//timeline.js

//Replace line 166: renderIfVisible(0, this.wavesurfer?.getWidth() || 0) with
const leftScroll = this.wavesurfer.getScroll()
const rightScroll = leftScroll + this.wavesurfer.getWidth()
renderIfVisible(leftScroll, rightScroll)

This does seem to fix the issue on my end, however it does cause some flickering due to the deferred execution. Removing the timeout does solve the flickering issue, but I am unsure if this is safe to do.

acieslewicz added a commit to acieslewicz/wavesurfer.js that referenced this issue Oct 22, 2024
Uses current scroll position instead of 0 when initially rendering timeline. Previously, the initial render
would show ticks starting from 0 regardless of scroll position.

Closes katspaugh#3782
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants