Page Index Toggle Pages: 1 Send TopicPrint
Hot Topic (More than 10 Replies) JavaScript Diagramming zoom to mouse position on scroll wheel (Read 8702 times)
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
JavaScript Diagramming zoom to mouse position on scroll wheel
Aug 9th, 2021 at 10:14am
Print Post  
Hi,

I am trying to figure out how to zoom into the diagram and out from the diagram from the cursor position using the scroll wheel. I have tried a few things but cannot get it to work at the moment.

Iam using the Javscript sdk and have found examples in c# and other languages but even trying to convert them into js does not seem to be working.

Any help would be appreciated

Thank you.

  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #1 - Aug 9th, 2021 at 10:15am
Print Post  
I have tried converting the method in the link below into js but cannot get it to work as the js scrollwheel event is not giving a start and end position.

https://www.mindfusion.eu/Forum/YaBB.pl?board=fcnet_disc;action=display;num=1165...
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3148
Joined: Oct 19th, 2005
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #2 - Aug 9th, 2021 at 11:25am
Print Post  
Hi,

You can find code snippet that zooms using mouse wheel here -
https://mindfusion.eu/Forum/YaBB.pl?num=1507268096/1#1

Try calling Diagram.setZoomFactorPivot method to zoom around specific point e.g. the center of current viewport, or the cached mouse cursor position stored in diagram.pointerPosition field.

Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #3 - Aug 9th, 2021 at 3:55pm
Print Post  
Hi,

thank you very much for the reply.

Unfortunately this did not work either. I have tried implementing the zooming inside the a scrollwheel event listener like your example link, I have also tried implementing the zooming inside the onMouseWheel function inside MouseEventHandler.js.

I have tried implementing the behaviour like this:

----------------------------
document.body.addEventListener('wheel', function(e)
{
     var zoom = diagram.getZoomFactor();
     zoom -= e.deltaY / 100;
     if (zoom > 10)
           diagram.setZoomFactorPivot(zoom, diagram.pointerPosition);

     e.preventDefault(); // do not scroll
});

---------------------------


and also like this inside MouseEventHandler.js


--------------------------

onMouseWheel: function (e) {
    var view = this.view;
    if (!view.enabled || !view.getVirtualScroll())
        return;

        e.preventDefault();
        var wheelEvent = e;
        // JQ and Ajax
        if (e.originalEvent instanceof WheelEvent) wheelEvent = e.originalEvent;
     if (e.rawEvent instanceof WheelEvent) wheelEvent = e.rawEvent;

    //removing scroll behavior to add zooming instead
    var zoom = diagram.getZoomFactor();
    zoom -= e.deltaY / 100;
    if (zoom > 10)
        diagram.setZoomFactorPivot(zoom, view.pointerPosition);
},


At the moment it seems like the diagram just zooms in but not into the cursor position.

Thank you
Danesh
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3148
Joined: Oct 19th, 2005
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #4 - Aug 10th, 2021 at 8:38am
Print Post  
Hi,

setZoomFactorPivot zooms at specified point for me, but it seems cached diagram.pointerPosition starts lagging after a few wheel zooms. You can get most current position as below. The code snippet also shows how to prevent default wheel handler we've added recently for virtual scroll mode.

Code
Select All
// remove default scrolling in virtual scroll mode
mflayer.removeHandler(diagram.get_element(), "wheel",
	mflayer.getEvent(diagram.get_element(), "wheel")[0]);
mflayer.removeHandler(diagram.get_element().parentNode, "wheel",
	mflayer.getEvent(diagram.get_element().parentNode, "wheel")[0]);

document.body.addEventListener('wheel', function (e)
{
	var position = MindFusion.Diagramming.Utils.
		getCursorPos(e, diagram.get_element());
	position = diagram.clientToDoc(position);

	var zoom = diagram.getZoomFactor();
	zoom -= e.deltaY / 100;
	if (zoom > 10)
		diagram.setZoomFactorPivot(zoom, position);

	e.preventDefault(); // prevent scroll in div-overflow scrolling mode
}); 



Regards,
Slavcho
Mindfusion
  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #5 - Aug 10th, 2021 at 9:46am
Print Post  
Hi,

Thank you for the reply again, I appreciate the help.

Unfortunately this is also not working for me, I have added an attachment to this reply which hopefully can show how my diagram is behaving when setZoomFactorPivot is called in the wheel listener. It still seems to zoom in to the diagram but does not keep the diagram point in view where the cursor is.



Thank you
Danesh
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3148
Joined: Oct 19th, 2005
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #6 - Aug 10th, 2021 at 12:48pm
Print Post  
Hi,

The scroll method called internally by setZoomPivot won't work if diagram's bounds is smaller than current viewport. E.g. copy last code to the anchor points example from distribution (it shows diagram's bounds in a different color). If you zoom in from initial state when diagram covers whole viewport, it will preserve pivot point position successfully. If you first zoom out enough to see the diagram smaller than viewport, then zooming-in will not preserve pivot position until diagram covers viewport again.

If you need this to work from a small starting zoom level, you will have to make sure your diagram is larger than the viewport (e.g. call setBounds with values larger than diagram.getViewport after initializing with small zoom level).

Regards,
Slavcho
  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #7 - Aug 12th, 2021 at 10:41am
Print Post  
Hi,

Thank you, your explanation has helped me understand the setZoomPivot behaviour better. I was able to see it working on the anchors sample and I was able to get this semi-working on my implementation too.

At the moment though the problem I am facing is that when I set the diagram bounds I have to always set the x and y to 0, 0 for the setZoomPivot function to work. If I set the x and y in diagram.setBounds to anything else then it stops zooming into the pivot and instead scrolls the diagram. I have attached 2 examples of this behaviour, Example 1 shows the pivot function working and Example 2 is the pivot behaviour broken.


Running this allows setZoomPivot to work

//set diagram bounds bigger than viewport with {x: 0, y:0}
diagram.setBounds(new MindFusion.Drawing.Rect(0,0, (diagram.getViewport().width * 4), (diagram.getViewport().height * 4)));
//update canvas size
diagram.updateCanvasSize();

Example 1 working zoom:



Running this will break setZoomPivot

I called zoomToFit() and this function changed the bounds of the diagram so I ran the code below again so that I could make the diagram bigger than the viewport again however this breaks the setZoomPivot functionality.

diagram bounds on load using diagram.getBounds();
{x: 485.99781092056395, y: 273.6348706185983, width: 90, height: 70}

//set diagram bounds bigger than viewport at the
diagram.setBounds(new MindFusion.Drawing.Rect(diagram.getBounds().x,diagram.getBounds().y, (diagram.getViewport().width * 4), (diagram.getViewport().height * 4)));
//update canvas size
diagram.updateCanvasSize();

Example 2 broken zoom:



Thank you
Danesh
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3148
Joined: Oct 19th, 2005
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #8 - Aug 13th, 2021 at 7:55am
Print Post  
Hi,

Try that with these scripts -
https://mindfusion.eu/_temp/jsdiag_zoompivot.zip

Regards,
Slavcho
  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #9 - Aug 23rd, 2021 at 8:58am
Print Post  
Hi,

Thank you for that, I was able to diagnose the problem with the scripts that you provided. It turns out the diagram bounds x and y coordinates were being altered which was causing the issue. They were being set to negative numbers which would break the zoomToPivot function. Now that the diagram bounds x and y dont change the zoomToPivot works correctly.

Thank you very much for your help.

Kind regards
Danesh
  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #10 - Aug 24th, 2021 at 11:06am
Print Post  
Hi,

Im not sure if I should ask this as another question however is this also possible when using the touch events. For example can the pivot be set to the touch position. Example use case would be the user pinching in/out and the pivot would be the centre of the two fingers.

I have tried this however using the center.x and center.y returned in the touch event handler is not working for me at the moment.

Thank you
Danesh
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3148
Joined: Oct 19th, 2005
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #11 - Aug 24th, 2021 at 6:17pm
Print Post  
Hi,

It shouldn't matter where you call setZoomFactorPivot from, just make sure the pivot point is specified in diagram's coordinate system, and not in e.g. screen pixels. Following modification of MDN pinch example seems to work as expected for me.

https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events/Pinch_zoom_gestu...

Code
Select All
function pointermove_handler(ev)
{
    ev.preventDefault();

    // This function implements a 2-pointer horizontal pinch/zoom gesture.
    //
    // If the distance between the two pointers has increased (zoom in),
    // the taget element's background is changed to "pink" and if the
    // distance is decreasing (zoom out), the color is changed to "lightblue".
    //
    // This function sets the target element's border to "dashed" to visually
    // indicate the pointer's target received a move event.
    log("pointerMove", ev);
    ev.target.style.border = "dashed";

    // Find this event in the cache and update its record with this event
    for (var i = 0; i < evCache.length; i++)
    {
        if (ev.pointerId == evCache[i].pointerId)
        {
            evCache[i] = ev;
            break;
        }
    }

    // If two pointers are down, check for pinch gestures
    if (evCache.length == 2)
    {
        // Calculate the distance between the two pointers
        var curDiff = Math.abs(evCache[0].clientX - evCache[1].clientX);
        var position = {
            x: (evCache[0].clientX + evCache[1].clientX) / 2,
            y: (evCache[0].clientY + evCache[1].clientY) / 2
        };
        position = diagram.clientToDoc(position);

        if (prevDiff > 0)
        {
            if (curDiff > prevDiff)
            {
                // The distance between the two pointers has increased
                log("Pinch moving OUT -> Zoom in", ev);
                var zoom = diagram.getZoomFactor();
                    zoom += 5;
                if (zoom > 10)
                    diagram.setZoomFactorPivot(zoom, position);
            }
            if (curDiff < prevDiff)
            {
                // The distance between the two pointers has decreased
                log("Pinch moving IN -> Zoom out",ev);
                var zoom = diagram.getZoomFactor();
                    zoom -= 5;
                if (zoom > 10)
                    diagram.setZoomFactorPivot(zoom, position);
            }
        }

        // Cache the distance for the next move event
        prevDiff = curDiff;
    }
} 



Also had to add this to prevent whole page from zooming:

Code
Select All
function touchstart_handler(event)
{
    event.preventDefault();
    event.stopPropagation();
} 



Regards,
Slavcho
  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #12 - Aug 26th, 2021 at 1:20pm
Print Post  
Hi,

thank you very much for pointing out I need to use pointer events, that was great, I got that working with my implementation. I did however notice that the behaviour seems to have an unexpected result when the diagram behaviour is set to Pan using diagram.setBehavior(MindFusion.Diagramming.Behavior.Pan).

I have included demonstrations below which show the unexpected behaviour. In Demo 1 the behaviour works as expected as the diagram behaviour is set to MoveNodes. In demo 2 however the behaviour is set to Pan and the diagram seems to be panning and zooming to position at the same time.

In your example code, I added:

diagram.setBehavior(MindFusion.Diagramming.Behavior.Pan);

inside the if statement:

if (evCache.length == 2)


Example 1, Diagram behaviour = MoveNodes, working:



Example 2, Diagram behaviour = Pan, not working:


Thank you
Danesh
  
Back to top
 
IP Logged
 
Slavcho
YaBB Moderator
*****
Online


tech.support

Posts: 3148
Joined: Oct 19th, 2005
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #13 - Aug 27th, 2021 at 2:03pm
Print Post  
Hi,

You can cancel panning once user adds second touch like this:

Code
Select All
function pointermove_handler(ev)
{
    .....

    if (evCache.length == 2)
    {
        if (diagram.mouseInputDispatcher.currentController)
        {
            diagram.mouseInputDispatcher.currentController.cancel();
            diagram.mouseInputDispatcher.currentController = null;
        }
    ..... 



Regards,
Slavcho
  
Back to top
 
IP Logged
 
danesh
YaBB Newbies
*
Offline


I Love MindFusion!

Posts: 19
Joined: Aug 9th, 2021
Re: JavaScript Diagramming zoom to mouse position on scroll wheel
Reply #14 - Oct 11th, 2021 at 2:03pm
Print Post  
Thankyou I was able to fix this with your help

Kind regards
Danesh
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint