UNPKG

react-plot

Version:

Library of React components to render SVG 2D plots.

72 lines (63 loc) 2.2 kB
import { useEffect, useRef, useState } from 'react'; import type { TrackingResult } from '../components/Tracking.js'; import { usePlotEvents } from '../contexts/plotController/plotControllerContext.js'; import type { ControllerHookOptions } from './types.js'; export type UseStartMoveEndCallback = ( data: TrackingResult<PointerEvent>, start: UseStartMoveEndPosition, end: UseStartMoveEndPosition, ) => void; export interface UseStartMoveEndOptions extends ControllerHookOptions { onStart?: UseStartMoveEndCallback; onMove?: UseStartMoveEndCallback; onEnd?: UseStartMoveEndCallback; } export interface UseStartMoveEndPosition { coordinates: Record<string, number>; clampedCoordinates: Record<string, number>; } export interface UseStartMoveEndState { start: UseStartMoveEndPosition; end?: UseStartMoveEndPosition; } export function useStartMoveEnd(options: UseStartMoveEndOptions) { const ref = useRef(options); useEffect(() => { ref.current = options; }, [options]); const [data, setData] = useState<UseStartMoveEndState | null>(null); usePlotEvents( { onPointerDown(result) { if (result.event.button !== 0 || result.event.altKey) return; const { coordinates, clampedCoordinates } = result; const position = { coordinates, clampedCoordinates }; setData({ start: position }); ref.current?.onStart?.(result, position, position); }, onPointerMove(result) { // TODO: boolean that says if pointer is currently down? if (!data || result.event.altKey) return; const { coordinates, clampedCoordinates } = result; const position = { coordinates, clampedCoordinates }; setData((data) => { if (!data) return null; return { ...data, end: position, }; }); ref.current?.onMove?.(result, data.start, position); }, onPointerUp(result) { if (result.event.button !== 0 || !data || result.event.altKey) return; setData(null); if (data.end) { ref.current?.onEnd?.(result, data.start, data.end); } }, }, options, ); return data; }