Skip to content

Commit

Permalink
Fix zoom callback on camera controls (#3924)
Browse files Browse the repository at this point in the history
  • Loading branch information
jtran authored Sep 19, 2024
1 parent dabf256 commit d8236dd
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 15 deletions.
42 changes: 33 additions & 9 deletions src/clientSideScene/CameraControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,19 @@ export class CameraControls {
}

onMouseWheel = (event: WheelEvent) => {
const interaction = this.getInteractionType(event)
if (interaction === 'none') return
event.preventDefault()

if (this.syncDirection === 'engineToClient') {
this.zoomDataFromLastFrame = event.deltaY
if (interaction === 'zoom') {
this.zoomDataFromLastFrame = event.deltaY
} else {
// This case will get handled when we add pan and rotate using Apple trackpad.
console.error(
`Unexpected interaction type for engineToClient wheel event: ${interaction}`
)
}
return
}

Expand All @@ -455,8 +466,16 @@ export class CameraControls {
// zoom commands to engine. This means dropping some zoom
// commands too.
// From onMouseMove zoom handling which seems to be really smooth

this.handleStart()
this.pendingZoom = 1 + (event.deltaY / window.devicePixelRatio) * 0.001
if (interaction === 'zoom') {
this.pendingZoom = 1 + (event.deltaY / window.devicePixelRatio) * 0.001
} else {
// This case will get handled when we add pan and rotate using Apple trackpad.
console.error(
`Unexpected interaction type for wheel event: ${interaction}`
)
}
this.handleEnd()
}

Expand Down Expand Up @@ -1123,7 +1142,7 @@ export class CameraControls {
this.deferReactUpdate(this.reactCameraProperties)
Object.values(this._camChangeCallbacks).forEach((cb) => cb())
}
getInteractionType = (event: any) =>
getInteractionType = (event: MouseEvent) =>
_getInteractionType(
this.interactionGuards,
event,
Expand Down Expand Up @@ -1231,16 +1250,21 @@ function _lookAt(position: Vector3, target: Vector3, up: Vector3): Quaternion {

function _getInteractionType(
interactionGuards: MouseGuard,
event: any,
event: MouseEvent | WheelEvent,
enablePan: boolean,
enableRotate: boolean,
enableZoom: boolean
): interactionType | 'none' {
let state: interactionType | 'none' = 'none'
if (enablePan && interactionGuards.pan.callback(event)) return 'pan'
if (enableRotate && interactionGuards.rotate.callback(event)) return 'rotate'
if (enableZoom && interactionGuards.zoom.dragCallback(event)) return 'zoom'
return state
if (event instanceof WheelEvent) {
if (enableZoom && interactionGuards.zoom.scrollCallback(event))
return 'zoom'
} else {
if (enablePan && interactionGuards.pan.callback(event)) return 'pan'
if (enableRotate && interactionGuards.rotate.callback(event))
return 'rotate'
if (enableZoom && interactionGuards.zoom.dragCallback(event)) return 'zoom'
}
return 'none'
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/components/Stream.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export const Stream = () => {
if (state.matches('Sketch')) return
if (state.matches({ idle: 'showPlanes' })) return

if (btnName(e).left) {
if (btnName(e.nativeEvent).left) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
sendSelectEventToEngine(e, videoRef.current)
}
Expand Down
10 changes: 5 additions & 5 deletions src/lib/cameraControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const META =
PLATFORM === 'macos' ? 'Cmd' : PLATFORM === 'windows' ? 'Win' : 'Super'
const ALT = PLATFORM === 'macos' ? 'Option' : 'Alt'

const noModifiersPressed = (e: React.MouseEvent) =>
const noModifiersPressed = (e: MouseEvent) =>
!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey

export type CameraSystem =
Expand Down Expand Up @@ -53,14 +53,14 @@ export function mouseControlsToCameraSystem(

interface MouseGuardHandler {
description: string
callback: (e: React.MouseEvent) => boolean
callback: (e: MouseEvent) => boolean
lenientDragStartButton?: number
}

interface MouseGuardZoomHandler {
description: string
dragCallback: (e: React.MouseEvent) => boolean
scrollCallback: (e: React.MouseEvent) => boolean
dragCallback: (e: MouseEvent) => boolean
scrollCallback: (e: WheelEvent) => boolean
lenientDragStartButton?: number
}

Expand All @@ -70,7 +70,7 @@ export interface MouseGuard {
rotate: MouseGuardHandler
}

export const btnName = (e: React.MouseEvent) => ({
export const btnName = (e: MouseEvent) => ({
middle: !!(e.buttons & 4) || e.button === 1,
right: !!(e.buttons & 2) || e.button === 2,
left: !!(e.buttons & 1) || e.button === 0,
Expand Down

0 comments on commit d8236dd

Please sign in to comment.