Timeline disappear when zooming
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
https://github.com/user-attachments/assets/171a6c8c-7319-4217-9552-f6f8632d5867
Obtained result
https://github.com/user-attachments/assets/3f561308-1aab-4e2c-b779-3bb528db9bd9
PR
I fix the issue (like you can see in the Expected result) but I do not know how to create PR
@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
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
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
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.