| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import Vec from '@tldraw/vec'
- import type { Handler, WebKitGestureEvent } from '@use-gesture/core/types'
- import { useGesture } from '@use-gesture/react'
- import * as React from 'react'
- import { useRendererContext } from '~hooks'
- import { TLTargetType, TLViewport } from '@tldraw/core'
- type PinchHandler = Handler<
- 'pinch',
- WheelEvent | PointerEvent | TouchEvent | WebKitGestureEvent | KeyboardEvent
- >
- export function useGestureEvents(ref: React.RefObject<HTMLDivElement>) {
- const { viewport, inputs, callbacks } = useRendererContext()
- const events = React.useMemo(() => {
- const onWheel: Handler<'wheel', WheelEvent> = gesture => {
- const { event, delta } = gesture
- event.preventDefault()
- if (inputs.state === 'pinching') return
- if (Vec.isEqual(delta, [0, 0])) return
- callbacks.onWheel?.(
- {
- type: TLTargetType.Canvas,
- order: 0,
- delta: gesture.delta,
- point: inputs.currentPoint,
- },
- event
- )
- }
- const onPinchStart: PinchHandler = gesture => {
- const elm = ref.current
- const { event } = gesture
- if (!(event.target === elm || elm?.contains(event.target as Node))) return
- if (!['idle', 'panning'].includes(inputs.state)) return
- callbacks.onPinchStart?.(
- {
- type: TLTargetType.Canvas,
- order: 0,
- delta: gesture.delta,
- offset: gesture.offset,
- point: Vec.sub(gesture.origin, inputs.containerOffset),
- },
- event
- )
- }
- const onPinch: PinchHandler = gesture => {
- const elm = ref.current
- const { event } = gesture
- if (!(event.target === elm || elm?.contains(event.target as Node))) return
- if (inputs.state !== 'pinching') return
- callbacks.onPinch?.(
- {
- type: TLTargetType.Canvas,
- order: 0,
- delta: gesture.delta,
- offset: gesture.offset,
- point: Vec.sub(gesture.origin, inputs.containerOffset),
- },
- event
- )
- }
- const onPinchEnd: PinchHandler = gesture => {
- const elm = ref.current
- const { event } = gesture
- if (!(event.target === elm || elm?.contains(event.target as Node))) return
- if (inputs.state !== 'pinching') return
- callbacks.onPinchEnd?.(
- {
- type: TLTargetType.Canvas,
- order: 0,
- delta: gesture.delta,
- offset: gesture.offset,
- point: Vec.sub(gesture.origin, inputs.containerOffset),
- },
- event
- )
- }
- return {
- onWheel,
- onPinchStart,
- onPinchEnd,
- onPinch,
- }
- }, [callbacks])
- useGesture(events, {
- target: ref,
- eventOptions: { passive: false },
- pinch: {
- from: [viewport.camera.zoom, viewport.camera.zoom],
- scaleBounds: () => ({
- from: viewport.camera.zoom,
- max: TLViewport.maxZoom,
- min: TLViewport.minZoom,
- }),
- },
- })
- }
|