Skip to content

Commit 2633605

Browse files
sciecodemrdoob
authored andcommitted
OrbitControls: fix pinch zoom behaviour (#27446)
Signed-off-by: Guilherme Avila <[email protected]>
1 parent d04539a commit 2633605

File tree

1 file changed

+66
-4
lines changed

1 file changed

+66
-4
lines changed

examples/jsm/controls/OrbitControls.js

+66-4
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ class OrbitControls extends EventDispatcher {
478478
const pointers = [];
479479
const pointerPositions = {};
480480

481+
let controlActive = false;
482+
481483
function getAutoRotationAngle( deltaTime ) {
482484

483485
if ( deltaTime !== null ) {
@@ -494,8 +496,8 @@ class OrbitControls extends EventDispatcher {
494496

495497
function getZoomScale( delta ) {
496498

497-
const normalized_delta = Math.abs( delta ) / ( 100 * ( window.devicePixelRatio | 0 ) );
498-
return Math.pow( 0.95, scope.zoomSpeed * normalized_delta );
499+
const normalizedDelta = Math.abs( delta * 0.01 );
500+
return Math.pow( 0.95, scope.zoomSpeed * normalizedDelta );
499501

500502
}
501503

@@ -1192,12 +1194,70 @@ class OrbitControls extends EventDispatcher {
11921194

11931195
scope.dispatchEvent( _startEvent );
11941196

1195-
handleMouseWheel( event );
1197+
handleMouseWheel( customWheelEvent( event ) );
11961198

11971199
scope.dispatchEvent( _endEvent );
11981200

11991201
}
12001202

1203+
function customWheelEvent( event ) {
1204+
1205+
const mode = event.deltaMode;
1206+
1207+
// minimal wheel event altered to meet delta-zoom demand
1208+
const newEvent = {
1209+
clientX: event.clientX,
1210+
clientY: event.clientY,
1211+
deltaY: event.deltaY,
1212+
}
1213+
1214+
switch ( mode ) {
1215+
1216+
case 1: // LINE_MODE
1217+
newEvent.deltaY *= 16;
1218+
break;
1219+
1220+
case 2: // PAGE_MODE
1221+
newEvent.deltaY *= 100;
1222+
break;
1223+
1224+
}
1225+
1226+
// detect if event was triggered by pinching
1227+
if ( event.ctrlKey && !controlActive ) {
1228+
1229+
newEvent.deltaY *= 10;
1230+
1231+
}
1232+
1233+
return newEvent;
1234+
1235+
}
1236+
1237+
function interceptControlDown( event ) {
1238+
1239+
if ( event.key === "Control" ) {
1240+
1241+
controlActive = true;
1242+
1243+
document.addEventListener('keyup', interceptControlUp, { passive: true, capture: true });
1244+
1245+
}
1246+
1247+
}
1248+
1249+
function interceptControlUp( event ) {
1250+
1251+
if ( event.key === "Control" ) {
1252+
1253+
controlActive = false;
1254+
1255+
document.removeEventListener('keyup', interceptControlUp, { passive: true, capture: true });
1256+
1257+
}
1258+
1259+
}
1260+
12011261
function onKeyDown( event ) {
12021262

12031263
if ( scope.enabled === false || scope.enablePan === false ) return;
@@ -1406,6 +1466,8 @@ class OrbitControls extends EventDispatcher {
14061466
scope.domElement.addEventListener( 'pointercancel', onPointerUp );
14071467
scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
14081468

1469+
document.addEventListener( 'keydown', interceptControlDown, { passive: true, capture: true } );
1470+
14091471
// force an update at start
14101472

14111473
this.update();
@@ -1414,4 +1476,4 @@ class OrbitControls extends EventDispatcher {
14141476

14151477
}
14161478

1417-
export { OrbitControls };
1479+
export { OrbitControls };

0 commit comments

Comments
 (0)