How to do Orthographic ArcRotateCamera Zooming and Panning on Desktop and Mobile?

Hi Guys,

I have the following playground where I have panning and zooming working as I would like it to on desktop:

However this doesn’t seem to work on mobile, the scene disappears…

Am I going about this the wrong way? Im sure this must have been done by others before as its got to be a pretty common thing.

I read: https://doc.babylonjs.com/features/featuresDeepDive/cameras/customizingCameraInputs and saw that I could use “HammerJS” but before I dive into all of that I was wondering anyone had any better ideas?

Cheers

cc @PolygonalSun

I tested your PG on my phone (Galaxy S21) and panning worked well (had to use two fingers to pan), however, zooming didn’t happen on pinch gestures. But the scene never disappeared.

By any chance, are you testing on an iOS device? If so, pointer events don’t provide values for the movementX/Y values so when you pan, you’re basically adding a non-number and the camera’s target becomes NaN, NaN, NaN and that’s why things would disappear. You could try calculating this manually by just storing the clientX and clientY values on a POINTERDOWN and grabbing the diff (and updating after) on a POINTERMOVE.

    var oldX: number = 0;
    var oldY: number = 0;
...
            if (e.type === BABYLON.PointerEventTypes.POINTERDOWN) {
                oldX = e.event.clientX;
                oldY = e.event.clientY;
                const pickResult = scene.pick(e.event.clientX, e.event.clientY);
                if (!pickResult.hit) dragStart = { x: e.event.offsetX, y: e.event.offsetY };
            }

            if (e.type === BABYLON.PointerEventTypes.POINTERUP) dragStart = null;

            if (e.type === BABYLON.PointerEventTypes.POINTERMOVE) {
                if (!dragStart) return;       
                // Store the diffs and update the old values
                const movementX = e.event.clientX - oldX;
                const movementY = e.event.clientY - oldY;
                oldX = e.event.clientX;
                oldY = e.event.clientY;
                camera.inertialPanningX -= movementX / 1000;
                camera.inertialPanningY += movementY / 1000;
            }

For zoom, I don’t think that a wheel event will fire for all mobile devices so you may have to create some kind of gesture recognizer to handle that. You could also just extend the BaseCameraPointersInput class and create an input using it’s point tracking.

2 Likes

Ah… yes indeed, I was testing on ios.

Okay thanks for that info, ill have another stab at it