You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

useZoomEvents.ts 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
  2. import { useRef } from 'react'
  3. import state from 'state'
  4. import inputs from 'state/inputs'
  5. import vec from 'utils/vec'
  6. import { useGesture } from 'react-use-gesture'
  7. import {
  8. fastBrushSelect,
  9. fastDrawUpdate,
  10. fastPanUpdate,
  11. fastPinchCamera,
  12. fastTransform,
  13. fastTranslate,
  14. fastZoomUpdate,
  15. } from 'state/hacks'
  16. /**
  17. * Capture zoom gestures (pinches, wheels and pans) and send to the state.
  18. * @param ref
  19. * @returns
  20. */
  21. export default function useZoomEvents() {
  22. const rPinchDa = useRef<number[] | undefined>(undefined)
  23. const rPinchPoint = useRef<number[] | undefined>(undefined)
  24. useGesture(
  25. {
  26. onWheel: ({ event, delta }) => {
  27. if (event.ctrlKey) {
  28. const { point } = inputs.wheel(event as WheelEvent)
  29. fastZoomUpdate(point, delta[1])
  30. return
  31. }
  32. fastPanUpdate(delta)
  33. const info = inputs.pointer
  34. if (state.isIn('draw.editing')) {
  35. fastDrawUpdate(info)
  36. } else if (state.isIn('brushSelecting')) {
  37. fastBrushSelect(info.point)
  38. } else if (state.isIn('translatingSelection')) {
  39. fastTranslate(info)
  40. } else if (state.isIn('transformingSelection')) {
  41. fastTransform(info)
  42. }
  43. state.send('PANNED_CAMERA', {
  44. delta,
  45. ...inputs.wheel(event as WheelEvent),
  46. })
  47. },
  48. onPinch: ({ pinching, da, origin }) => {
  49. if (!pinching) {
  50. state.send('STOPPED_PINCHING')
  51. rPinchDa.current = undefined
  52. rPinchPoint.current = undefined
  53. return
  54. }
  55. if (rPinchPoint.current === undefined) {
  56. state.send('STARTED_PINCHING')
  57. rPinchDa.current = da
  58. rPinchPoint.current = origin
  59. }
  60. const [distanceDelta] = vec.sub(rPinchDa.current, da)
  61. fastPinchCamera(
  62. origin,
  63. vec.sub(rPinchPoint.current, origin),
  64. distanceDelta
  65. )
  66. rPinchDa.current = da
  67. rPinchPoint.current = origin
  68. },
  69. },
  70. {
  71. domTarget: document.body,
  72. eventOptions: { passive: false },
  73. }
  74. )
  75. }