diff --git a/src/App.scss b/src/App.scss index 1b8ae10..b24e16a 100644 --- a/src/App.scss +++ b/src/App.scss @@ -100,12 +100,10 @@ input { -webkit-user-select: none; user-select: none; - overflow: hidden; /* Ensure no overflow */ - > img { display: block; - max-width: 100%; - max-height: 100%; + width: 100%; + height: auto; object-fit: contain; /* Ensure the image fits within the container */ } } diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index e5e33ca..35de444 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -17,6 +17,7 @@ import { settleAllFullfilfedPromises, hexToNpub } from '../../utils' import { getSigitFile, SigitFile } from '../../utils/file' import { FileDivider } from '../FileDivider' import { ExtensionFileBox } from '../ExtensionFileBox' +import { inPx } from '../../utils/pdf' PDFJS.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.min.mjs', @@ -105,8 +106,8 @@ export const DrawPDFFields = (props: Props) => { const { mouseX, mouseY } = getMouseCoordinates(event) const newField: DrawnField = { - left: mouseX, - top: mouseY, + left: mouseX / page.scale, + top: mouseY / page.scale, width: 0, height: 0, counterpart: '', @@ -160,8 +161,8 @@ export const DrawPDFFields = (props: Props) => { const { mouseX, mouseY } = getMouseCoordinates(event) - const width = mouseX - lastDrawnField.left - const height = mouseY - lastDrawnField.top + const width = mouseX / page.scale - lastDrawnField.left + const height = mouseY / page.scale - lastDrawnField.top lastDrawnField.width = width lastDrawnField.height = height @@ -209,7 +210,8 @@ export const DrawPDFFields = (props: Props) => { */ const onDrawnFieldMouseMove = ( event: React.MouseEvent, - drawnField: DrawnField + drawnField: DrawnField, + scale: number ) => { if (mouseState.dragging) { const { mouseX, mouseY, rect } = getMouseCoordinates( @@ -219,11 +221,11 @@ export const DrawPDFFields = (props: Props) => { const coordsOffset = mouseState.coordsInWrapper if (coordsOffset) { - let left = mouseX - coordsOffset.mouseX - let top = mouseY - coordsOffset.mouseY + let left = (mouseX - coordsOffset.mouseX) / scale + let top = (mouseY - coordsOffset.mouseY) / scale - const rightLimit = rect.width - drawnField.width - 3 - const bottomLimit = rect.height - drawnField.height - 3 + const rightLimit = rect.width / scale - drawnField.width - 3 + const bottomLimit = rect.height / scale - drawnField.height - 3 if (left < 0) left = 0 if (top < 0) top = 0 @@ -263,7 +265,8 @@ export const DrawPDFFields = (props: Props) => { */ const onResizeHandleMouseMove = ( event: React.MouseEvent, - drawnField: DrawnField + drawnField: DrawnField, + scale: number ) => { if (mouseState.resizing) { const { mouseX, mouseY } = getMouseCoordinates( @@ -274,8 +277,8 @@ export const DrawPDFFields = (props: Props) => { event.currentTarget.parentElement?.parentElement ) - const width = mouseX - drawnField.left - const height = mouseY - drawnField.top + const width = mouseX / scale - drawnField.left + const height = mouseY / scale - drawnField.top drawnField.width = width drawnField.height = height @@ -372,21 +375,21 @@ export const DrawPDFFields = (props: Props) => { key={drawnFieldIndex} onMouseDown={onDrawnFieldMouseDown} onMouseMove={(event) => { - onDrawnFieldMouseMove(event, drawnField) + onDrawnFieldMouseMove(event, drawnField, page.scale) }} className={styles.drawingRectangle} style={{ - left: `${drawnField.left}px`, - top: `${drawnField.top}px`, - width: `${drawnField.width}px`, - height: `${drawnField.height}px`, + left: inPx(drawnField.left * page.scale), + top: inPx(drawnField.top * page.scale), + width: inPx(drawnField.width * page.scale), + height: inPx(drawnField.height * page.scale), pointerEvents: mouseState.clicked ? 'none' : 'all' }} > { - onResizeHandleMouseMove(event, drawnField) + onResizeHandleMouseMove(event, drawnField, page.scale) }} className={styles.resizeHandle} > diff --git a/src/components/PDFView/PdfMarkItem.tsx b/src/components/PDFView/PdfMarkItem.tsx index 9642499..cc9c9b2 100644 --- a/src/components/PDFView/PdfMarkItem.tsx +++ b/src/components/PDFView/PdfMarkItem.tsx @@ -7,6 +7,7 @@ interface PdfMarkItemProps { handleMarkClick: (id: number) => void selectedMarkValue: string selectedMark: CurrentUserMark | null + scale: number } /** @@ -16,7 +17,8 @@ const PdfMarkItem = ({ selectedMark, handleMarkClick, selectedMarkValue, - userMark + userMark, + scale }: PdfMarkItemProps) => { const { location } = userMark.mark const handleClick = () => handleMarkClick(userMark.mark.id) @@ -28,12 +30,12 @@ const PdfMarkItem = ({ onClick={handleClick} className={`file-mark ${styles.drawingRectangle} ${isEdited() && styles.edited}`} style={{ - left: inPx(location.left), - top: inPx(location.top), - width: inPx(location.width), - height: inPx(location.height), + left: inPx(location.left * scale), + top: inPx(location.top * scale), + width: inPx(location.width * scale), + height: inPx(location.height * scale), fontFamily: FONT_TYPE, - fontSize: inPx(FONT_SIZE) + fontSize: inPx(FONT_SIZE * scale) }} > {getMarkValue()} diff --git a/src/components/PDFView/PdfPageItem.tsx b/src/components/PDFView/PdfPageItem.tsx index 65ea322..f5f310d 100644 --- a/src/components/PDFView/PdfPageItem.tsx +++ b/src/components/PDFView/PdfPageItem.tsx @@ -4,7 +4,7 @@ import { CurrentUserMark, Mark } from '../../types/mark.ts' import PdfMarkItem from './PdfMarkItem.tsx' import { useEffect, useRef } from 'react' import pdfViewStyles from './style.module.scss' -import { inPx } from '../../utils/pdf.ts' +import { FONT_SIZE, FONT_TYPE, inPx } from '../../utils/pdf.ts' interface PdfPageProps { currentUserMarks: CurrentUserMark[] handleMarkClick: (id: number) => void @@ -44,23 +44,28 @@ const PdfPageItem = ({ selectedMarkValue={selectedMarkValue} userMark={m} selectedMark={selectedMark} + scale={page.scale} /> ))} - {otherUserMarks.map((m, i) => ( -
- {m.value} -
- ))} + {otherUserMarks.map((m, i) => { + return ( +
+ {m.value} +
+ ) + })} ) } diff --git a/src/layouts/StickySideColumns.module.scss b/src/layouts/StickySideColumns.module.scss index 7495cad..77daa03 100644 --- a/src/layouts/StickySideColumns.module.scss +++ b/src/layouts/StickySideColumns.module.scss @@ -29,8 +29,4 @@ padding: 10px; border: 10px solid $overlay-background-color; border-radius: 4px; - - max-width: 590px; - width: 590px; - margin: 0 auto; } diff --git a/src/layouts/StickySideColumns.tsx b/src/layouts/StickySideColumns.tsx index 1ada87f..43dc430 100644 --- a/src/layouts/StickySideColumns.tsx +++ b/src/layouts/StickySideColumns.tsx @@ -17,7 +17,9 @@ export const StickySideColumns = ({
{left}
-
{children}
+
+ {children} +
{right}
diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index f442cd7..6ff679a 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -110,12 +110,12 @@ const SlimPdfView = ({ className={`file-mark ${styles.mark}`} key={m.id} style={{ - left: inPx(m.location.left), - top: inPx(m.location.top), - width: inPx(m.location.width), - height: inPx(m.location.height), + left: inPx(m.location.left * page.scale), + top: inPx(m.location.top * page.scale), + width: inPx(m.location.width * page.scale), + height: inPx(m.location.height * page.scale), fontFamily: FONT_TYPE, - fontSize: inPx(FONT_SIZE) + fontSize: inPx(FONT_SIZE * page.scale) }} > {m.value} @@ -431,7 +431,7 @@ export const VerifyPage = () => { for (const [fileName, file] of Object.entries(files)) { if (file.isPdf) { // Draw marks into PDF file and generate a brand new blob - const pages = await addMarks(file, file.pages!, marksByPage[fileName]) + const pages = await addMarks(file, marksByPage[fileName]) const blob = await convertToPdfBlob(pages) zip.file(`files/${fileName}`, blob) } else { diff --git a/src/types/drawing.ts b/src/types/drawing.ts index bb7c970..d8c5cc3 100644 --- a/src/types/drawing.ts +++ b/src/types/drawing.ts @@ -1,3 +1,5 @@ +import { MarkRect } from './mark' + export interface MouseState { clicked?: boolean dragging?: boolean @@ -14,11 +16,7 @@ export interface PdfPage { drawnFields: DrawnField[] } -export interface DrawnField { - left: number - top: number - width: number - height: number +export interface DrawnField extends MarkRect { type: MarkType /** * npub of a counter part diff --git a/src/types/mark.ts b/src/types/mark.ts index efc1899..df733d6 100644 --- a/src/types/mark.ts +++ b/src/types/mark.ts @@ -18,10 +18,13 @@ export interface Mark { value?: string } -export interface MarkLocation { - top: number - left: number - height: number - width: number +export interface MarkLocation extends MarkRect { page: number } + +export interface MarkRect { + left: number + top: number + width: number + height: number +} diff --git a/src/utils/file.ts b/src/utils/file.ts index 26f03ef..63d40e5 100644 --- a/src/utils/file.ts +++ b/src/utils/file.ts @@ -22,11 +22,7 @@ export const getZipWithFiles = async ( for (const [fileName, file] of Object.entries(files)) { if (file.isPdf) { // Handle PDF Files - const pages = await addMarks( - file, - file.pages!, - marksByFileNamePage[fileName] - ) + const pages = await addMarks(file, marksByFileNamePage[fileName]) const blob = await convertToPdfBlob(pages) zip.file(`files/${fileName}`, blob) } else { @@ -78,6 +74,7 @@ export const getSigitFile = async (file: File) => { const sigitFile = new SigitFile(file) // Process sigit file // - generate pages for PDF files + // - generate ObjectRL for image files await sigitFile.process() return sigitFile } diff --git a/src/utils/pdf.ts b/src/utils/pdf.ts index c7eca36..15bcba7 100644 --- a/src/utils/pdf.ts +++ b/src/utils/pdf.ts @@ -8,11 +8,6 @@ PDFJS.GlobalWorkerOptions.workerSrc = new URL( import.meta.url ).toString() -/** - * Default width of the rendered element on the website - * @constant {number} - */ -export const DEFAULT_VIEWPORT_WIDTH = 550 /** * Scale between the PDF page's natural size and rendered size * @constant {number} @@ -32,11 +27,17 @@ export const FONT_SIZE: number = 16 export const FONT_TYPE: string = 'Arial' /** - * A utility that transforms a drawing coordinate number into a CSS-compatible string + * A utility that transforms a drawing coordinate number into a CSS-compatible pixel string * @param coordinate */ export const inPx = (coordinate: number): string => `${coordinate}px` +/** + * A utility that transforms a drawing coordinate number into a CSS-compatible percentage string + * @param coordinate + */ +export const inPerc = (coordinate: number): string => `${coordinate}%` + /** * A utility that checks if a given file is of the pdf type * @param file @@ -80,14 +81,14 @@ export const pdfToImages = async ( const pages: PdfPage[] = [] const pdf = await PDFJS.getDocument(data).promise const canvas = document.createElement('canvas') + const width = document.querySelector('#content-preview > *')?.clientWidth || 1 for (let i = 0; i < pdf.numPages; i++) { const page = await pdf.getPage(i + 1) const originalViewport = page.getViewport({ scale: 1 }) - const scale = originalViewport.width / DEFAULT_VIEWPORT_WIDTH - - const viewport = page.getViewport({ scale }) + const scale = width / originalViewport.width + const viewport = page.getViewport({ scale: scale }) const context = canvas.getContext('2d') canvas.height = viewport.height canvas.width = viewport.width @@ -110,7 +111,6 @@ export const pdfToImages = async ( */ export const addMarks = async ( file: File, - pages: PdfPage[], marksPerPage: { [key: string]: Mark[] } ) => { const p = await readPdf(file) @@ -129,7 +129,7 @@ export const addMarks = async ( await page.render({ canvasContext: context, viewport: viewport }).promise if (marksPerPage && Object.hasOwn(marksPerPage, i)) { - marksPerPage[i]?.forEach((mark) => draw(mark, context, pages[i].scale)) + marksPerPage[i]?.forEach((mark) => draw(mark, context)) } images.push(canvas.toDataURL()) @@ -169,14 +169,9 @@ export const hasValue = (mark: Mark): boolean => !!mark.value * @param mark to be drawn * @param ctx a Canvas representation of a specific PDF Page */ -export const draw = ( - mark: Mark, - ctx: CanvasRenderingContext2D, - scale: number -) => { - const { location } = scaleMark(mark, scale) - - ctx.font = scale * FONT_SIZE + 'px ' + FONT_TYPE +export const draw = (mark: Mark, ctx: CanvasRenderingContext2D) => { + const { location } = mark + ctx.font = FONT_SIZE + 'px ' + FONT_TYPE ctx.fillStyle = 'black' const textMetrics = ctx.measureText(mark.value!) const textHeight =