projectstorm / react-diagrams

a super simple, no-nonsense diagramming library written in react that just works
https://projectstorm.cloud/react-diagrams
MIT License
8.46k stars 1.16k forks source link

Debouncing in the engine sometimes locks pan in the CanvasWidget #896

Open aaron-michaux opened 2 years ago

aaron-michaux commented 2 years ago

When I create the engine like so...

  const engine = createEngine({
    repaintDebounceMs: 5
  })

Occasionally the pan stops working on the CanvasWidget. I jumped into the code, and figured out that the debounce function is created afresh during each "engine.repaintCanvas" call... thus effectively acting as a delay on execution, and not a debounce. When setting up the debounce correctly, redraw becomes jittery, and the "pan locking" issue becomes worse. (Still intermittent.)

It seems that the debounce function needs to execute on the leading edge.

  // Outside engine.repaintCanvas
  const repaint = () => {
    engine.iterateListeners((listener) => {
      if (listener.repaintCanvas) {
        listener.repaintCanvas()
      }
    })
  }
  const repaintFn = _.debounce(repaint, repaintDebounceMs, { leading: true })
aaron-michaux commented 2 years ago

The above actually does debouncing, but the "leading edge" trick doesn't work. My computer is fast enough that locking never happens, but it happens on other computers. As far as I can tell, debouncing breaks panning, and without debouncing, there's performance issues, because the render and devolve into a tight loop during panning.