diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 13a50c0..563bb94 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -9,7 +9,6 @@ import { } from '@mui/material' import styles from './style.module.scss' import React, { useEffect, useState } from 'react' -import * as PDFJS from 'pdfjs-dist' import { ProfileMetadata, User, UserRole } from '../../types' import { MouseState, PdfPage, DrawnField, DrawTool } from '../../types/drawing' import { truncate } from 'lodash' @@ -22,10 +21,10 @@ import { useScale } from '../../hooks/useScale' import { AvatarIconButton } from '../UserAvatarIconButton' import { LoadingSpinner } from '../LoadingSpinner' -PDFJS.GlobalWorkerOptions.workerSrc = new URL( - 'pdfjs-dist/build/pdf.worker.min.mjs', - import.meta.url -).toString() +const DEFAULT_START_SIZE = { + width: 140, + height: 40 +} as const interface Props { selectedFiles: File[] @@ -46,6 +45,8 @@ export const DrawPDFFields = (props: Props) => { clicked: false }) + const [activeDrawField, setActiveDrawField] = useState() + useEffect(() => { if (selectedFiles) { /** @@ -77,10 +78,12 @@ export const DrawPDFFields = (props: Props) => { * Drawing events */ useEffect(() => { - window.addEventListener('mouseup', onMouseUp) + window.addEventListener('pointerup', handlePointerUp) + window.addEventListener('pointercancel', handlePointerUp) return () => { - window.removeEventListener('mouseup', onMouseUp) + window.removeEventListener('pointerup', handlePointerUp) + window.removeEventListener('pointercancel', handlePointerUp) } }, []) @@ -96,10 +99,7 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param page PdfPage where press happened */ - const onMouseDown = ( - event: React.MouseEvent, - page: PdfPage - ) => { + const handlePointerDown = (event: React.PointerEvent, page: PdfPage) => { // Proceed only if left click if (event.button !== 0) return @@ -112,8 +112,8 @@ export const DrawPDFFields = (props: Props) => { const newField: DrawnField = { left: to(page.width, mouseX), top: to(page.width, mouseY), - width: 0, - height: 0, + width: event.pointerType === 'mouse' ? 0 : DEFAULT_START_SIZE.width, + height: event.pointerType === 'mouse' ? 0 : DEFAULT_START_SIZE.height, counterpart: '', type: selectedTool.identifier } @@ -132,7 +132,7 @@ export const DrawPDFFields = (props: Props) => { * Drawing is finished, resets all the variables used to draw * @param event Mouse event */ - const onMouseUp = () => { + const handlePointerUp = () => { setMouseState((prev) => { return { ...prev, @@ -144,16 +144,13 @@ export const DrawPDFFields = (props: Props) => { } /** - * After {@link onMouseDown} create an drawing element, this function gets called on every pixel moved + * After {@link handlePointerDown} create an drawing element, this function gets called on every pixel moved * which alters the newly created drawing element, resizing it while mouse move * @param event Mouse event * @param page PdfPage where moving is happening */ - const onMouseMove = ( - event: React.MouseEvent, - page: PdfPage - ) => { - if (mouseState.clicked && selectedTool) { + const handlePointerMove = (event: React.PointerEvent, page: PdfPage) => { + if (mouseState.clicked && selectedTool && event.pointerType === 'mouse') { const lastElementIndex = page.drawnFields.length - 1 const lastDrawnField = page.drawnFields[lastElementIndex] @@ -187,9 +184,12 @@ export const DrawPDFFields = (props: Props) => { * mouseY - offsetY * * @param event Mouse event - * @param drawnField Which we are moving + * @param drawnFieldIndex Which we are moving */ - const onDrawnFieldMouseDown = (event: React.MouseEvent) => { + const handleDrawnFieldPointerDown = ( + event: React.PointerEvent, + drawnFieldIndex: number + ) => { event.stopPropagation() // Proceed only if left click @@ -197,6 +197,7 @@ export const DrawPDFFields = (props: Props) => { const drawingRectangleCoords = getMouseCoordinates(event) + setActiveDrawField(drawnFieldIndex) setMouseState({ dragging: true, clicked: false, @@ -212,8 +213,8 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param drawnField which we are moving */ - const onDrawnFieldMouseMove = ( - event: React.MouseEvent, + const handleDrawnFieldPointerMove = ( + event: React.PointerEvent, drawnField: DrawnField, pageWidth: number ) => { @@ -228,8 +229,8 @@ export const DrawPDFFields = (props: Props) => { let left = to(pageWidth, mouseX - coordsOffset.mouseX) let top = to(pageWidth, mouseY - coordsOffset.mouseY) - const rightLimit = to(pageWidth, rect.width) - drawnField.width - 3 - const bottomLimit = to(pageWidth, rect.height) - drawnField.height - 3 + const rightLimit = to(pageWidth, rect.width) - drawnField.width + const bottomLimit = to(pageWidth, rect.height) - drawnField.height if (left < 0) left = 0 if (top < 0) top = 0 @@ -247,16 +248,17 @@ export const DrawPDFFields = (props: Props) => { /** * Fired when clicked on the resize handle, sets the state for a resize action * @param event Mouse event - * @param drawnField which we are resizing + * @param drawnFieldIndex which we are resizing */ - const onResizeHandleMouseDown = ( - event: React.MouseEvent + const handleResizePointerDown = ( + event: React.PointerEvent, + drawnFieldIndex: number ) => { // Proceed only if left click if (event.button !== 0) return - event.stopPropagation() + setActiveDrawField(drawnFieldIndex) setMouseState({ resizing: true }) @@ -267,8 +269,8 @@ export const DrawPDFFields = (props: Props) => { * @param event Mouse event * @param drawnField which we are resizing */ - const onResizeHandleMouseMove = ( - event: React.MouseEvent, + const handleResizePointerMove = ( + event: React.PointerEvent, drawnField: DrawnField, pageWidth: number ) => { @@ -298,8 +300,8 @@ export const DrawPDFFields = (props: Props) => { * @param pdfPageIndex pdf page index * @param drawnFileIndex drawn file index */ - const onRemoveHandleMouseDown = ( - event: React.MouseEvent, + const handleRemovePointerDown = ( + event: React.PointerEvent, pdfFileIndex: number, pdfPageIndex: number, drawnFileIndex: number @@ -317,20 +319,18 @@ export const DrawPDFFields = (props: Props) => { * so select can work properly * @param event Mouse event */ - const onUserSelectHandleMouseDown = ( - event: React.MouseEvent - ) => { + const handleUserSelectPointerDown = (event: React.PointerEvent) => { event.stopPropagation() } /** * Gets the mouse coordinates relative to a element in the `event` param - * @param event MouseEvent + * @param event PointerEvent * @param customTarget mouse coordinates relative to this element, if not provided * event.target will be used */ const getMouseCoordinates = ( - event: React.MouseEvent, + event: React.PointerEvent, customTarget?: HTMLElement | null ) => { const target = customTarget ? customTarget : event.currentTarget @@ -346,7 +346,6 @@ export const DrawPDFFields = (props: Props) => { rect } } - /** * Renders the pdf pages and drawing elements */ @@ -363,11 +362,11 @@ export const DrawPDFFields = (props: Props) => { className={`image-wrapper ${styles.pdfImageWrapper} ${selectedTool ? styles.drawing : ''}`} > { - onMouseMove(event, page) + onPointerMove={(event) => { + handlePointerMove(event, page) }} - onMouseDown={(event) => { - onMouseDown(event, page) + onPointerDown={(event) => { + handlePointerDown(event, page) }} draggable="false" src={page.image} @@ -378,29 +377,52 @@ export const DrawPDFFields = (props: Props) => { return (
{ - onDrawnFieldMouseMove(event, drawnField, page.width) + onPointerDown={(event) => + handleDrawnFieldPointerDown(event, drawnFieldIndex) + } + onPointerMove={(event) => { + handleDrawnFieldPointerMove(event, drawnField, page.width) }} className={styles.drawingRectangle} style={{ + backgroundColor: drawnField.counterpart + ? `#${npubToHex(drawnField.counterpart)?.substring(0, 6)}4b` + : undefined, + borderColor: drawnField.counterpart + ? `#${npubToHex(drawnField.counterpart)?.substring(0, 6)}` + : undefined, left: inPx(from(page.width, drawnField.left)), top: inPx(from(page.width, drawnField.top)), width: inPx(from(page.width, drawnField.width)), height: inPx(from(page.width, drawnField.height)), - pointerEvents: mouseState.clicked ? 'none' : 'all' + pointerEvents: mouseState.clicked ? 'none' : 'all', + touchAction: 'none', + opacity: + mouseState.dragging && + activeDrawField === drawnFieldIndex + ? 0.8 + : undefined }} > { - onResizeHandleMouseMove(event, drawnField, page.width) + onPointerDown={(event) => + handleResizePointerDown(event, drawnFieldIndex) + } + onPointerMove={(event) => { + handleResizePointerMove(event, drawnField, page.width) }} className={styles.resizeHandle} + style={{ + background: + mouseState.resizing && + activeDrawField === drawnFieldIndex + ? 'var(--primary-main)' + : undefined + }} > { - onRemoveHandleMouseDown( + onPointerDown={(event) => { + handleRemovePointerDown( event, fileIndex, pageIndex, @@ -412,7 +434,7 @@ export const DrawPDFFields = (props: Props) => {