Add middle-click + drag listener for ZOOM on EnvironmentControls
Is your feature request related to a problem? Please describe.
The EnvironmentControls parses left and right clicks + mouse-wheel events, (Quick note, the SHIFT + LEFT_CLICK did not trigger rotate during my tests). It could be nice if these controls could also parse Middle click for zoom - the awy it is done in googleMapsAerial within OrbitControls
Describe the solution you'd like
Web/API/Pointer_events suggest adding to PointerTracker.js
isMiddleClicked() {
return Boolean( this.buttons & 4 );
}
And then this could probably resort to something like the following addition to EnvironmentControls.js - pointerdownCallback
else if ( pointerTracker.isMiddleClicked() ) {
// if the clicked point is coming from below the plane then don't perform the drag
this.setState( ZOOM );
this.zoomDirectionSet = false;
this._updateZoomDirection();
// The below could be shared on top if the `if (hit)` block
this.pivotPoint.copy( hit.point );
this.pivotMesh.position.copy( hit.point );
this.pivotMesh.updateMatrixWorld();
this.scene.add( this.pivotMesh );
}
Finally,
- or replicate somehow the wheelCallback and replace how it handles event cursor
e.deltaYmotion withmovementY, and apply tozoomDelta, but build this into pointermoveCallback:
const pointermoveCallback = e => {
// ...
// Add mouse click handle in pointerMove
if ( this.state === ZOOM ) {
console.log( 'MOUSE MIDDLE CLICKED: ', e, e.deltaMode, e.deltaY );
const delta = e.movementY;
// use LOG to scale the scroll delta and hopefully normalize them across platforms
const deltaSign = Math.sign( delta );
const normalizedDelta = Math.log( Math.abs( delta ) + 1 );
this.zoomDelta -= 3 * deltaSign * normalizedDelta * 1;
// this.needsUpdate = true;
}
Describe alternatives you've considered
Use another controls, like Pivot controls instead of EnvironmentControls to handle middle-mouse click
I'm open to adding the feature if you like to make a PR!
Just did a try, seems like this is working! https://github.com/NASA-AMMOS/3DTilesRendererJS/pull/789
Edit: seems that terrain avoidance makes it not exactly work like mouse-wheel - where the cursor stays at the same spot on the mesh during zooming-in/out, while it slides with the middle-click zoom. Maybe an update that should be disabled or enabled that I am missing - something like zoomDirection or pivot?
seems that terrain avoidance makes it not exactly work like mouse-wheel - where the cursor stays at the same spot on the mesh during zooming-in/out, while it slides with the middle-click zoom. Maybe an update that should be disabled or enabled that I am missing - something like zoomDirection or pivot?
I'll have to try it when I'm on a computer with a mouse but I wouldn't expect this to keep the terrain in the same spot under the mouse since the cursor is being dragged. It should zoom into the point that was originally clicked.
Yes I agree it should zoom on the spot originally clicked, but this spot seem to slide a little because of the terrain constraint. It's not very noticeable, but still a bit weird.
It might be trying to zoom always to where the cursor is, which when middleclicking + sliding vertically, moves towards the top or bottom of the screen.
Conditioning _updatePosition and _updateRotation on controls update only to when state is ROTATE or DRAG also seem to be reducing the issue:
if ( state === ZOOM && zoomDelta !== 0 ) {
this._updateZoom();
this.rotationInertia.set( 0, 0 );
this.dragInertia.set( 0, 0, 0 );
}
else if ( state === ROTATE || state === DRAG ) {
this._updatePosition( deltaTime );
this._updateRotation( deltaTime );
}