jgraph / mxgraph

mxGraph is a fully client side JavaScript diagramming library
Other
6.83k stars 2.06k forks source link

Zoom to cursor position using mousewheel #418

Closed emcodem closed 4 years ago

emcodem commented 4 years ago

Dears, i hope i am right opening this issue here but when trying to implement "zoom to cursor position", on draw.io this is done using ctrl+mousewheel. I faced lots of same people asking similar questions.. unfortunately the possibilities seem to be overwhelming and when searching the net, one can find the question but no really good answers. How could i reproduce the mousewheel zoom behaviour that happens on draw.io when using ctrl+wheel in a custom mxgraph without scrollbars?

Thanks!

emcodem commented 4 years ago

Not perfect but kind of works for me: In the addMouseWheelListener event, insert a "fake node", then zoom and get the position delta for the fake node. Then move the graph by this delta.

var allcells = m_graph.getChildVertices(graph.getDefaultParent());                        
var v1 = m_graph.insertVertex(m_graph.getDefaultParent(), "zoom", 'zoom', mousepointer_coordinates.x, mousepointer_coordinates.y, 100, 100, 'strokeColor=rgb(85,85,85,0);fillColor=rgb(184,184,184,0)');

                        var old_x = m_graph.view.getState(v1).x;
                        var old_y = m_graph.view.getState(v1).y;
                            m_graph.zoomIn();
                            var new_x = m_graph.view.getState(v1).x;
                            var new_y = m_graph.view.getState(v1).y;
                            //move graph by delta of zoomnode position
                            m_graph.moveCells(allcells, (old_x-new_x), (old_y-new_y), false);
                           m_graph.removeCells([v1]);
mareksidlo commented 4 years ago

In case that somebody come here like i did today, here is my solution which is reproducing draw.io zoom behaviour (thanks for inspiration, your solution helped me a lot :))

var pX = (evt.x / graph.view.scale) - graph.view.translate.x; var pY = (evt.y / graph.view.scale) - graph.view.translate.y; var v1 = graph.insertVertex(graph.getDefaultParent(), null, null, pX, pY, 1, 1, 'strokeColor=rgb(85,85,85,0);fillColor=rgb(184,184,184,0)'); var old_x = graph.view.getState(v1).x; var old_y = graph.view.getState(v1).y;

if (evt.wheelDelta > 0) { graph.zoomIn(); } else { graph.zoomOut(); }

var new_x = graph.view.getState(v1).x; var new_y = graph.view.getState(v1).y;

var deltaX = (old_x - new_x) / graph.view.scale; var deltaY = (old_y - new_y) / graph.view.scale;

graph.view.setTranslate(graph.view.translate.x + deltaX, graph.view.translate.y + deltaY); graph.removeCells([v1]);

igisev commented 4 years ago

Correct solution:

mxEvent.addMouseWheelListener((evt, up) => {
  if (mxEvent.isConsumed(evt)) {
    return;
  }

  let gridEnabled = graph.gridEnabled;

  // disable snapping
  graph.gridEnabled = false;

  let p1 = graph.getPointForEvent(evt, false);

  if (up) {
    graph.zoomIn();
  } else {
    graph.zoomOut();
  }

  let p2 = graph.getPointForEvent(evt, false);
  let deltaX = p2.x - p1.x;
  let deltaY = p2.y - p1.y;
  let view = graph.view;

  view.setTranslate(view.translate.x + deltaX, view.translate.y + deltaY);

  graph.gridEnabled = gridEnabled;

  mxEvent.consume(evt);
}, container);
dazed19 commented 4 years ago

@igisev thanks for that

One thing - I had to add a view.validateBackgroundPage(); to avoid losing my grid background on zoom.

      view.setTranslate(view.translate.x + deltaX, view.translate.y + deltaY);

      graph.gridEnabled = gridEnabled;

      view.validateBackgroundPage();      
emcodem commented 4 years ago

@igisev Thanks again, i was able to use your code unmodified (except change let to var) and now my zoom is working perfectly