/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-devtools-timeline/src/view-base/useCanvasInteraction.js
254 строки
6 KB
Andrew Clark
[Codemod] Update copyright header to Meta (#25315)
18 окт 2022, 18:19
Не верифицирован
18 окт 2022, 18:19
9cdf8a9
Код
Авторство
О чём код?
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import type {NormalizedWheelDelta} from './utils/normalizeWheel'; import type {Point} from './geometry'; import {useEffect, useRef} from 'react'; import {normalizeWheel} from './utils/normalizeWheel'; export type ClickInteraction = { type: 'click', payload: { event: MouseEvent, location: Point, }, }; export type DoubleClickInteraction = { type: 'double-click', payload: { event: MouseEvent, location: Point, }, }; export type MouseDownInteraction = { type: 'mousedown', payload: { event: MouseEvent, location: Point, }, }; export type MouseMoveInteraction = { type: 'mousemove', payload: { event: MouseEvent, location: Point, }, }; export type MouseUpInteraction = { type: 'mouseup', payload: { event: MouseEvent, location: Point, }, }; export type WheelPlainInteraction = { type: 'wheel-plain', payload: { event: WheelEvent, location: Point, delta: NormalizedWheelDelta, }, }; export type WheelWithShiftInteraction = { type: 'wheel-shift', payload: { event: WheelEvent, location: Point, delta: NormalizedWheelDelta, }, }; export type WheelWithControlInteraction = { type: 'wheel-control', payload: { event: WheelEvent, location: Point, delta: NormalizedWheelDelta, }, }; export type WheelWithMetaInteraction = { type: 'wheel-meta', payload: { event: WheelEvent, location: Point, delta: NormalizedWheelDelta, }, }; export type Interaction = | ClickInteraction | DoubleClickInteraction | MouseDownInteraction | MouseMoveInteraction | MouseUpInteraction | WheelPlainInteraction | WheelWithShiftInteraction | WheelWithControlInteraction | WheelWithMetaInteraction; let canvasBoundingRectCache = null; function cacheFirstGetCanvasBoundingRect( canvas: HTMLCanvasElement, ): ClientRect { if ( canvasBoundingRectCache && canvas.width === canvasBoundingRectCache.width && canvas.height === canvasBoundingRectCache.height ) { return canvasBoundingRectCache.rect; } canvasBoundingRectCache = { width: canvas.width, height: canvas.height, rect: canvas.getBoundingClientRect(), }; return canvasBoundingRectCache.rect; } export function useCanvasInteraction( canvasRef: {current: HTMLCanvasElement | null}, interactor: (interaction: Interaction) => void, ) { const isMouseDownRef = useRef<boolean>(false); const didMouseMoveWhileDownRef = useRef<boolean>(false); useEffect(() => { const canvas = canvasRef.current; if (!canvas) { return; } function localToCanvasCoordinates(localCoordinates: Point): Point { // $FlowFixMe[incompatible-call] found when upgrading Flow const canvasRect = cacheFirstGetCanvasBoundingRect(canvas); return { x: localCoordinates.x - canvasRect.left, y: localCoordinates.y - canvasRect.top, }; } const onCanvasClick: MouseEventHandler = event => { if (didMouseMoveWhileDownRef.current) { return; } interactor({ type: 'click', payload: { event, location: localToCanvasCoordinates({x: event.x, y: event.y}), }, }); }; const onCanvasDoubleClick: MouseEventHandler = event => { if (didMouseMoveWhileDownRef.current) { return; } interactor({ type: 'double-click', payload: { event, location: localToCanvasCoordinates({x: event.x, y: event.y}), }, }); }; const onCanvasMouseDown: MouseEventHandler = event => { didMouseMoveWhileDownRef.current = false; isMouseDownRef.current = true; interactor({ type: 'mousedown', payload: { event, location: localToCanvasCoordinates({x: event.x, y: event.y}), }, }); }; const onDocumentMouseMove: MouseEventHandler = event => { if (isMouseDownRef.current) { didMouseMoveWhileDownRef.current = true; } interactor({ type: 'mousemove', payload: { event, location: localToCanvasCoordinates({x: event.x, y: event.y}), }, }); }; const onDocumentMouseUp: MouseEventHandler = event => { isMouseDownRef.current = false; interactor({ type: 'mouseup', payload: { event, location: localToCanvasCoordinates({x: event.x, y: event.y}), }, }); }; const onCanvasWheel: WheelEventHandler = event => { event.preventDefault(); event.stopPropagation(); const location = localToCanvasCoordinates({x: event.x, y: event.y}); const delta = normalizeWheel(event); if (event.shiftKey) { interactor({ type: 'wheel-shift', payload: {event, location, delta}, }); } else if (event.ctrlKey) { interactor({ type: 'wheel-control', payload: {event, location, delta}, }); } else if (event.metaKey) { interactor({ type: 'wheel-meta', payload: {event, location, delta}, }); } else { interactor({ type: 'wheel-plain', payload: {event, location, delta}, }); } return false; }; const ownerDocument = canvas.ownerDocument; ownerDocument.addEventListener('mousemove', onDocumentMouseMove); ownerDocument.addEventListener('mouseup', onDocumentMouseUp); canvas.addEventListener('click', onCanvasClick); canvas.addEventListener('dblclick', onCanvasDoubleClick); canvas.addEventListener('mousedown', onCanvasMouseDown); canvas.addEventListener('wheel', onCanvasWheel); return () => { ownerDocument.removeEventListener('mousemove', onDocumentMouseMove); ownerDocument.removeEventListener('mouseup', onDocumentMouseUp); canvas.removeEventListener('click', onCanvasClick); canvas.removeEventListener('dblclick', onCanvasDoubleClick); canvas.removeEventListener('mousedown', onCanvasMouseDown); canvas.removeEventListener('wheel', onCanvasWheel); }; }, [canvasRef, interactor]); }