@@ -40,8 +40,11 @@ export default function (
4040 onMouseDownTheta ,
4141 phi ,
4242 onMouseDownPhi ,
43+ onTouchStartFingersDistance ,
4344 canvasSize = Math . min ( maxSize , window . innerWidth * innerWidthMultiplier ) ,
4445 autoRescale = true ;
46+
47+ const onMouseDownPosition = new Int16Array ( 2 ) ;
4548
4649 container . style . width = canvasSize + 'px' ;
4750 // to avoid overflow when a tick numbers is out of the parent element
@@ -315,7 +318,7 @@ export default function (
315318
316319 positionTickNumbers ( hasAxes , tickNumbers , ticks , camera , canvasSize , maxSize ) ;
317320
318- if ( event . shiftKey ) { // pan
321+ if ( event . shiftKey ) { // pan with mouse
319322 if ( ! isShiftDown ) {
320323 isShiftDown = true ;
321324 onMouseDownPosition [ 0 ] = clientX ;
@@ -340,23 +343,36 @@ export default function (
340343 focus . z = onMouseDownFocus . z + ( radius / canvasSize ) * ( cameraY . z * ( onMouseDownPosition [ 1 ] - clientY ) ) ;
341344
342345 updateCameraPosition ( ) ;
343- } else if ( event . ctrlKey ) { // zoom
346+ } else if ( event . ctrlKey || ( touch && event . touches . length === 2 ) ) { // zoom
344347 if ( ! isCtrlDown ) {
345348 isCtrlDown = true ;
346349 onCtrlDownFov = camera . fov ;
347350 onMouseDownPosition [ 0 ] = clientX ;
348351 onMouseDownPosition [ 1 ] = clientY ;
349352 autoRescale = false ;
350353 container . style . cursor = 'crosshair' ;
354+
355+ if ( touch ) {
356+ onTouchStartFingersDistance = Math . hypot (
357+ clientX - event . touches [ 1 ] . clientX ,
358+ clientY - event . touches [ 1 ] . clientY
359+ ) ;
360+ }
351361 }
352362
353- camera . fov = Math . max (
354- 1 ,
355- Math . min (
356- onCtrlDownFov + 20 * Math . atan ( ( event . clientY - onMouseDownPosition [ 1 ] ) / 50 ) ,
357- 150
358- )
359- ) ;
363+ let fov = onCtrlDownFov ;
364+
365+ if ( touch ) {
366+ fov -= ( Math . hypot (
367+ clientX - event . touches [ 1 ] . clientX ,
368+ clientY - event . touches [ 1 ] . clientY
369+ ) - onTouchStartFingersDistance ) / 25 ;
370+ } else {
371+ fov += 20 * Math . atan ( ( clientY - onMouseDownPosition [ 1 ] ) / 50 ) ;
372+ }
373+
374+ // Keeps the FOV between 1 and 150.
375+ camera . fov = Math . max ( 1 , Math . min ( 150 , fov ) ) ;
360376
361377 camera . updateProjectionMatrix ( ) ;
362378 } else { // spin
@@ -420,8 +436,6 @@ export default function (
420436 positionTickNumbers ( hasAxes , tickNumbers , ticks , camera , canvasSize , maxSize ) ;
421437 } ) ;
422438
423- const onMouseDownPosition = new Int16Array ( 2 ) ;
424-
425439 updateCameraPosition ( ) ;
426440 scaleInView ( ) ;
427441 render ( ) ;
0 commit comments