jerosoler / Drawflow

Simple flow library 🖥️🖱️
https://jerosoler.github.io/Drawflow/
MIT License
4.65k stars 722 forks source link

during panning, editor does not follow mouse cursor when it's outside of the element #443

Open m-t-chang opened 2 years ago

m-t-chang commented 2 years ago

See the screen recording below. Perhaps this could be fixed by using setPointerCapture() when dragging begins?

https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture

https://user-images.githubusercontent.com/93272954/171086151-e9661fbb-13ad-4cc6-9af1-fba5669c63e4.mov

jerosoler commented 2 years ago

Other solutions stop de Drag on outside.

jerosoler commented 2 years ago

Wow! Work correct! ;)

I did not know this method. It is very simple to implement:

    editor.pointerdown = (e) => {
        editor.container.onpointermove = editor.position(e);
        editor.container.setPointerCapture(e.pointerId);
    } 
    editor.pointerup = (e) => {
        editor.container.onpointermove = null;
        editor.container.releasePointerCapture(e.pointerId);
    } 

    editor.container.addEventListener('pointerdown', editor.pointerdown);
    editor.container.addEventListener('pointerup', editor.pointerup); 
m-t-chang commented 2 years ago

Awesome, thanks!

m-t-chang commented 2 years ago

I added a line to check for event target, since setPointerCapture can interfere with other custom events. (this is CoffeeScript syntax)

        editor.container.addEventListener('pointerdown', (e) ->
            if e.target.matches('.parent-drawflow, .drawflow')
                editor.container.onpointermove = editor.position(e)
                editor.container.setPointerCapture(e.pointerId)
        )
        editor.container.addEventListener('pointerup', (e) ->
            editor.container.onpointermove = null
            editor.container.releasePointerCapture(e.pointerId)
        )
gpack commented 2 years ago

@m-t-chang m-t-chang

Do you have a plain Javascript version of that code above that checks for event targets?

thanks.

m-t-chang commented 2 years ago

@gpack Try this:

editor.container.addEventListener('pointerdown', function(e) {
  if (e.target.matches('.parent-drawflow, .drawflow')) {
    editor.container.onpointermove = editor.position(e);
    return editor.container.setPointerCapture(e.pointerId);
  }
});

editor.container.addEventListener('pointerup', function(e) {
  editor.container.onpointermove = null;
  return editor.container.releasePointerCapture(e.pointerId);
});
gpack commented 2 years ago

@m-t-chang Thank you so much for that kind sir. And for your very quick reply too 👍

jerosoler commented 2 years ago

This way it only affects the canvas.

In the previous way it also works for nodes and canvas.

Since it runs in editor.container it shouldn't affect other applications.

MatthewAlner commented 1 year ago

Hey, what's actually going on here? editor.container.onpointermove = editor.position(e); the editor.position function has a return type of void? so we are effectively setting editor.container.onpointermove to undefined? if this is intended it would be clearer to do it over 2 lines, and set it to null like the lines below.

    editor.pointerdown = (e) => {
        editor.position(e);
        editor.container.onpointermove = null;
        editor.container.setPointerCapture(e.pointerId);
    } 
    editor.pointerup = (e) => {
        editor.container.onpointermove = null;
        editor.container.releasePointerCapture(e.pointerId);
    } 

    editor.container.addEventListener('pointerdown', editor.pointerdown);
    editor.container.addEventListener('pointerup', editor.pointerup); 

like this? it seems to work but so does

    editor.pointerdown = (e) => {
        editor.position(e);
        editor.container.setPointerCapture(e.pointerId);
    } 
    editor.pointerup = (e) => {
        editor.container.releasePointerCapture(e.pointerId);
    } 

    editor.container.addEventListener('pointerdown', editor.pointerdown);
    editor.container.addEventListener('pointerup', editor.pointerup); 

so why are we nulling out editor.container.onpointermove?

jerosoler commented 1 year ago

so why are we nulling out editor.container.onpointermove?

It is passed to null. Because once the mouse is up there is no reason to pass the position function.

You can see more at https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture