Prevent scrollViewer onWheel event from "propagating" to camera zoom

I would like to stop the camera from zooming out/in when the UI scrollViewer is scrolling down/up. Is this possible? I could not see anything in the docs for scrollViewer. Thanks!

cc @DarraghBurke

1 Like

You could try to the scroll element using html / css on top of the canvas.
Also You access the scroll element in your Main JS using: document.getElementByID(“scroller”);

A simple Demo:

If you don’t need to have mouse wheel scrolling, you could just remove it:

camera.inputs.removeByType("ArcRotateCameraMouseWheelInput");

If you want to keep it when not hovering over the scrollViewer, you could try one of these two methods:

// Remove the mouse wheel input when inside and re-add it when outside
scroll_viewer.onPointerEnterObservable.add((ev) => {
    camera.inputs.removeByType("ArcRotateCameraMouseWheelInput");
});
scroll_viewer.onPointerOutObservable.add((ev) => {
    camera.inputs.addMouseWheel();
});

If you want to avoid creating objects, you could also try this approach:

// When inside of the scroll viewer object, just max out the precision to make the movement practically zero
scroll_viewer.onPointerEnterObservable.add((ev) => {
   camera.inputs.attached.mousewheel.wheelPrecision = Number.MAX_VALUE;
});
scroll_viewer.onPointerOutObservable.add((ev) => {
    // Return to default value, you may want to store the value and restore it if you change the value
    camera.inputs.attached.mousewheel.wheelPrecision = 3;
});
1 Like

This is useful. Thanks @PolygonalSun. As I want to stop the camera from moving when the user is interacting with the UI modal, I have instead put this code into the render and dispose functions of the UI modal component. This is instead of listening for the onPointerEnter/Out . It also has the added advantage of working on mobile where there are no onPointerEnter/Out events triggered.

Yes.

So did you actually fix it with this? Else, I would have one more solution (very similar I believe) that has proved to work both on desktop and mobile.

Thanks @mawa actually it’s not fixed as on mobile:

a) the scroll of the scrollViewer does not work so
b) once that’s working then the panning (moving in Y axis?) will need to be avoided (that’s triggered for the camera when you use two fingers to move up/down) and
c) if the pinch zoom was somehow to be used to do something to control the scrollViewer on mobile (though I don’t know what that would be) then these events would also need to be disabled somehow.

Sorry this is a bit messier than I’d like it to be so I’m happy to provide any clarifications and I welcome any suggestions! :slight_smile:

Yes, that’s what I thought. Give a minute to find this recent PG that has proven to work. It has just one little downside to it. You have to first tap a control or the scrollbar to unlock the gesture on the scrollViewer. May be it can be improved. Else, it works both on desktop and mobile and prevents from loosing controls or zooming the scene when interacting with the GUI… Shouldn’t be all too long…

1 Like

Ok so there goes. Sry for the somewhat rushed PG. I quickly extracted the code from another PG you don’t want to see :wink: It’s a huge mess. Anyways, the point you are interested in is not and I implemented this part in your revised PG
Note that you can still combine this with the enter and out observable for desktop, which is more enjoyable on desktop because you don’t have to click. It won’t create any issue to have both (as far as I know). As I said, not 100% perfect but 'Hope this will help,

1 Like

That’s great. Thanks @mawa. I disabled the uicamera as I don’t think it’s needed? https://playground.babylonjs.com/#TF5SQ3#2 This solution definitely gets it a lot closer to an easier user experience so thank you very much for that! :slight_smile:

And for my use case it’s for a slightly transparent modal UI that sits in front of the view so when the modal is first rendered I will call camera.detachControl() and then when it’s disposed of I will call the camera.attachControl()

I have some demo code that I think solves this and solves the other problem: Scrolling scrollViewer seems to not work on Mobile?

I wanted to point out that I did end up using the onPointerEnterObservable / Out as suggested by @PolygonalSun :smiley: So thanks for everyone’s help. Particularly @mawa ! :star2:

1 Like

Thanks a lot for your kind words :blush: and MANY THANKS for taking the time and effort to share the results and complete thread with the community. I already bookmarked it.
I am sure it will be VERY HELPFUL for many users :teacher:
Have an awesome day :parasol_on_ground: :sun_with_face:

1 Like