您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

useZoomEvents.ts 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { useRef } from 'react'
  2. import state from 'state'
  3. import inputs from 'state/inputs'
  4. import vec from 'utils/vec'
  5. import { useGesture } from 'react-use-gesture'
  6. import { fastPinchCamera, fastZoomUpdate } from 'state/hacks'
  7. /**
  8. * Capture zoom gestures (pinches, wheels and pans) and send to the state.
  9. * @param ref
  10. * @returns
  11. */
  12. export default function useZoomEvents() {
  13. const rPinchDa = useRef<number[] | undefined>(undefined)
  14. const rPinchPoint = useRef<number[] | undefined>(undefined)
  15. useGesture(
  16. {
  17. onWheel: ({ event, delta }) => {
  18. if (event.ctrlKey) {
  19. const { point } = inputs.wheel(event as WheelEvent)
  20. fastZoomUpdate(point, delta[1])
  21. return
  22. }
  23. state.send('PANNED_CAMERA', {
  24. delta,
  25. ...inputs.wheel(event as WheelEvent),
  26. })
  27. },
  28. onPinch: ({ pinching, da, origin }) => {
  29. if (!pinching) {
  30. state.send('STOPPED_PINCHING')
  31. rPinchDa.current = undefined
  32. rPinchPoint.current = undefined
  33. return
  34. }
  35. if (rPinchPoint.current === undefined) {
  36. state.send('STARTED_PINCHING')
  37. rPinchDa.current = da
  38. rPinchPoint.current = origin
  39. }
  40. const [distanceDelta] = vec.sub(rPinchDa.current, da)
  41. fastPinchCamera(
  42. origin,
  43. vec.sub(rPinchPoint.current, origin),
  44. distanceDelta
  45. )
  46. rPinchDa.current = da
  47. rPinchPoint.current = origin
  48. },
  49. },
  50. {
  51. domTarget: document.body,
  52. eventOptions: { passive: false },
  53. }
  54. )
  55. }