react-pdf-highlighter-plus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +411 -0
- package/dist/esm/components/AreaHighlight.d.ts +82 -0
- package/dist/esm/components/AreaHighlight.js +109 -0
- package/dist/esm/components/AreaHighlight.js.map +1 -0
- package/dist/esm/components/DrawingCanvas.d.ts +48 -0
- package/dist/esm/components/DrawingCanvas.js +277 -0
- package/dist/esm/components/DrawingCanvas.js.map +1 -0
- package/dist/esm/components/DrawingHighlight.d.ts +70 -0
- package/dist/esm/components/DrawingHighlight.js +164 -0
- package/dist/esm/components/DrawingHighlight.js.map +1 -0
- package/dist/esm/components/FreetextHighlight.d.ts +112 -0
- package/dist/esm/components/FreetextHighlight.js +193 -0
- package/dist/esm/components/FreetextHighlight.js.map +1 -0
- package/dist/esm/components/HighlightLayer.d.ts +49 -0
- package/dist/esm/components/HighlightLayer.js +37 -0
- package/dist/esm/components/HighlightLayer.js.map +1 -0
- package/dist/esm/components/ImageHighlight.d.ts +63 -0
- package/dist/esm/components/ImageHighlight.js +65 -0
- package/dist/esm/components/ImageHighlight.js.map +1 -0
- package/dist/esm/components/MonitoredHighlightContainer.d.ts +37 -0
- package/dist/esm/components/MonitoredHighlightContainer.js +42 -0
- package/dist/esm/components/MonitoredHighlightContainer.js.map +1 -0
- package/dist/esm/components/MouseMonitor.d.ts +34 -0
- package/dist/esm/components/MouseMonitor.js +30 -0
- package/dist/esm/components/MouseMonitor.js.map +1 -0
- package/dist/esm/components/MouseSelection.d.ts +66 -0
- package/dist/esm/components/MouseSelection.js +122 -0
- package/dist/esm/components/MouseSelection.js.map +1 -0
- package/dist/esm/components/PdfHighlighter.d.ts +184 -0
- package/dist/esm/components/PdfHighlighter.js +410 -0
- package/dist/esm/components/PdfHighlighter.js.map +1 -0
- package/dist/esm/components/PdfLoader.d.ts +55 -0
- package/dist/esm/components/PdfLoader.js +57 -0
- package/dist/esm/components/PdfLoader.js.map +1 -0
- package/dist/esm/components/ShapeCanvas.d.ts +51 -0
- package/dist/esm/components/ShapeCanvas.js +205 -0
- package/dist/esm/components/ShapeCanvas.js.map +1 -0
- package/dist/esm/components/ShapeHighlight.d.ts +107 -0
- package/dist/esm/components/ShapeHighlight.js +140 -0
- package/dist/esm/components/ShapeHighlight.js.map +1 -0
- package/dist/esm/components/SignaturePad.d.ts +40 -0
- package/dist/esm/components/SignaturePad.js +138 -0
- package/dist/esm/components/SignaturePad.js.map +1 -0
- package/dist/esm/components/TextHighlight.d.ts +93 -0
- package/dist/esm/components/TextHighlight.js +115 -0
- package/dist/esm/components/TextHighlight.js.map +1 -0
- package/dist/esm/components/TipContainer.d.ts +27 -0
- package/dist/esm/components/TipContainer.js +58 -0
- package/dist/esm/components/TipContainer.js.map +1 -0
- package/dist/esm/contexts/HighlightContext.d.ts +44 -0
- package/dist/esm/contexts/HighlightContext.js +16 -0
- package/dist/esm/contexts/HighlightContext.js.map +1 -0
- package/dist/esm/contexts/PdfHighlighterContext.d.ts +89 -0
- package/dist/esm/contexts/PdfHighlighterContext.js +16 -0
- package/dist/esm/contexts/PdfHighlighterContext.js.map +1 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.js +19 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/coordinates.d.ts +16 -0
- package/dist/esm/lib/coordinates.js +69 -0
- package/dist/esm/lib/coordinates.js.map +1 -0
- package/dist/esm/lib/export-pdf.d.ts +81 -0
- package/dist/esm/lib/export-pdf.js +511 -0
- package/dist/esm/lib/export-pdf.js.map +1 -0
- package/dist/esm/lib/get-bounding-rect.d.ts +3 -0
- package/dist/esm/lib/get-bounding-rect.js +35 -0
- package/dist/esm/lib/get-bounding-rect.js.map +1 -0
- package/dist/esm/lib/get-client-rects.d.ts +3 -0
- package/dist/esm/lib/get-client-rects.js +43 -0
- package/dist/esm/lib/get-client-rects.js.map +1 -0
- package/dist/esm/lib/group-highlights-by-page.d.ts +6 -0
- package/dist/esm/lib/group-highlights-by-page.js +23 -0
- package/dist/esm/lib/group-highlights-by-page.js.map +1 -0
- package/dist/esm/lib/optimize-client-rects.d.ts +3 -0
- package/dist/esm/lib/optimize-client-rects.js +65 -0
- package/dist/esm/lib/optimize-client-rects.js.map +1 -0
- package/dist/esm/lib/pdfjs-dom.d.ts +9 -0
- package/dist/esm/lib/pdfjs-dom.js +55 -0
- package/dist/esm/lib/pdfjs-dom.js.map +1 -0
- package/dist/esm/lib/screenshot.d.ts +4 -0
- package/dist/esm/lib/screenshot.js +24 -0
- package/dist/esm/lib/screenshot.js.map +1 -0
- package/dist/esm/style/AreaHighlight.css +134 -0
- package/dist/esm/style/DrawingCanvas.css +62 -0
- package/dist/esm/style/DrawingHighlight.css +184 -0
- package/dist/esm/style/FreetextHighlight.css +249 -0
- package/dist/esm/style/ImageHighlight.css +97 -0
- package/dist/esm/style/MouseSelection.css +15 -0
- package/dist/esm/style/PdfHighlighter.css +77 -0
- package/dist/esm/style/ShapeCanvas.css +47 -0
- package/dist/esm/style/ShapeHighlight.css +182 -0
- package/dist/esm/style/SignaturePad.css +83 -0
- package/dist/esm/style/TextHighlight.css +199 -0
- package/dist/esm/style/pdf_viewer.css +41 -0
- package/dist/esm/types.d.ts +213 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import React, { useRef, useEffect, useCallback, useState, } from "react";
|
|
2
|
+
import { viewportPositionToScaled } from "../lib/coordinates";
|
|
3
|
+
import "../style/DrawingCanvas.css";
|
|
4
|
+
/**
|
|
5
|
+
* A transparent overlay canvas for freehand drawing on PDF pages.
|
|
6
|
+
* Supports mouse and touch input.
|
|
7
|
+
*
|
|
8
|
+
* @category Component
|
|
9
|
+
*/
|
|
10
|
+
export const DrawingCanvas = ({ isActive, strokeColor = "#000000", strokeWidth = 3, viewer, onComplete, onCancel, }) => {
|
|
11
|
+
const canvasRef = useRef(null);
|
|
12
|
+
const [strokes, setStrokes] = useState([]);
|
|
13
|
+
const [currentStroke, setCurrentStroke] = useState(null);
|
|
14
|
+
const isDrawingRef = useRef(false);
|
|
15
|
+
const [pageNumber, setPageNumber] = useState(null);
|
|
16
|
+
const [pageElement, setPageElement] = useState(null);
|
|
17
|
+
// Find which page the user is drawing on
|
|
18
|
+
const findPageFromPoint = useCallback((clientX, clientY) => {
|
|
19
|
+
if (!viewer)
|
|
20
|
+
return null;
|
|
21
|
+
for (let i = 0; i < viewer.pagesCount; i++) {
|
|
22
|
+
const pageView = viewer.getPageView(i);
|
|
23
|
+
if (!pageView?.div)
|
|
24
|
+
continue;
|
|
25
|
+
const rect = pageView.div.getBoundingClientRect();
|
|
26
|
+
if (clientX >= rect.left &&
|
|
27
|
+
clientX <= rect.right &&
|
|
28
|
+
clientY >= rect.top &&
|
|
29
|
+
clientY <= rect.bottom) {
|
|
30
|
+
return {
|
|
31
|
+
pageNumber: i + 1,
|
|
32
|
+
element: pageView.div,
|
|
33
|
+
rect,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}, [viewer]);
|
|
39
|
+
// Redraw all strokes
|
|
40
|
+
const redrawCanvas = useCallback(() => {
|
|
41
|
+
const canvas = canvasRef.current;
|
|
42
|
+
const ctx = canvas?.getContext("2d");
|
|
43
|
+
if (!ctx || !canvas)
|
|
44
|
+
return;
|
|
45
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
46
|
+
// Draw all completed strokes with their own color/width
|
|
47
|
+
strokes.forEach((stroke) => {
|
|
48
|
+
if (stroke.points.length < 2)
|
|
49
|
+
return;
|
|
50
|
+
ctx.strokeStyle = stroke.color;
|
|
51
|
+
ctx.lineWidth = stroke.width;
|
|
52
|
+
ctx.lineCap = "round";
|
|
53
|
+
ctx.lineJoin = "round";
|
|
54
|
+
ctx.beginPath();
|
|
55
|
+
ctx.moveTo(stroke.points[0].x, stroke.points[0].y);
|
|
56
|
+
stroke.points.slice(1).forEach((point) => {
|
|
57
|
+
ctx.lineTo(point.x, point.y);
|
|
58
|
+
});
|
|
59
|
+
ctx.stroke();
|
|
60
|
+
});
|
|
61
|
+
// Draw current stroke with current color/width
|
|
62
|
+
if (currentStroke && currentStroke.points.length >= 2) {
|
|
63
|
+
ctx.strokeStyle = currentStroke.color;
|
|
64
|
+
ctx.lineWidth = currentStroke.width;
|
|
65
|
+
ctx.lineCap = "round";
|
|
66
|
+
ctx.lineJoin = "round";
|
|
67
|
+
ctx.beginPath();
|
|
68
|
+
ctx.moveTo(currentStroke.points[0].x, currentStroke.points[0].y);
|
|
69
|
+
currentStroke.points.slice(1).forEach((point) => {
|
|
70
|
+
ctx.lineTo(point.x, point.y);
|
|
71
|
+
});
|
|
72
|
+
ctx.stroke();
|
|
73
|
+
}
|
|
74
|
+
}, [strokes, currentStroke]);
|
|
75
|
+
// Redraw when strokes change
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
redrawCanvas();
|
|
78
|
+
}, [redrawCanvas]);
|
|
79
|
+
// Handle mouse/touch down
|
|
80
|
+
const handleStart = useCallback((clientX, clientY) => {
|
|
81
|
+
const pageInfo = findPageFromPoint(clientX, clientY);
|
|
82
|
+
if (!pageInfo)
|
|
83
|
+
return;
|
|
84
|
+
console.log("DrawingCanvas: Started drawing on page", pageInfo.pageNumber);
|
|
85
|
+
// Set page context if not already set
|
|
86
|
+
if (pageNumber === null) {
|
|
87
|
+
setPageNumber(pageInfo.pageNumber);
|
|
88
|
+
setPageElement(pageInfo.element);
|
|
89
|
+
// Resize canvas to match page
|
|
90
|
+
const canvas = canvasRef.current;
|
|
91
|
+
if (canvas) {
|
|
92
|
+
canvas.width = pageInfo.rect.width;
|
|
93
|
+
canvas.height = pageInfo.rect.height;
|
|
94
|
+
canvas.style.left = `${pageInfo.rect.left}px`;
|
|
95
|
+
canvas.style.top = `${pageInfo.rect.top}px`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (pageInfo.pageNumber !== pageNumber) {
|
|
99
|
+
// User trying to draw on different page - ignore
|
|
100
|
+
console.log("DrawingCanvas: Ignoring - different page");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
isDrawingRef.current = true;
|
|
104
|
+
const pos = {
|
|
105
|
+
x: clientX - pageInfo.rect.left,
|
|
106
|
+
y: clientY - pageInfo.rect.top,
|
|
107
|
+
};
|
|
108
|
+
setCurrentStroke({ points: [pos], color: strokeColor, width: strokeWidth });
|
|
109
|
+
}, [pageNumber, findPageFromPoint, strokeColor, strokeWidth]);
|
|
110
|
+
// Handle mouse/touch move
|
|
111
|
+
const handleMove = useCallback((clientX, clientY) => {
|
|
112
|
+
if (!isDrawingRef.current || !pageElement)
|
|
113
|
+
return;
|
|
114
|
+
const rect = pageElement.getBoundingClientRect();
|
|
115
|
+
const pos = {
|
|
116
|
+
x: clientX - rect.left,
|
|
117
|
+
y: clientY - rect.top,
|
|
118
|
+
};
|
|
119
|
+
setCurrentStroke((prev) => {
|
|
120
|
+
if (!prev)
|
|
121
|
+
return null;
|
|
122
|
+
return { ...prev, points: [...prev.points, pos] };
|
|
123
|
+
});
|
|
124
|
+
}, [pageElement]);
|
|
125
|
+
// Handle mouse/touch end
|
|
126
|
+
const handleEnd = useCallback(() => {
|
|
127
|
+
if (!isDrawingRef.current)
|
|
128
|
+
return;
|
|
129
|
+
isDrawingRef.current = false;
|
|
130
|
+
if (currentStroke && currentStroke.points.length >= 2) {
|
|
131
|
+
setStrokes((prev) => [...prev, currentStroke]);
|
|
132
|
+
}
|
|
133
|
+
setCurrentStroke(null);
|
|
134
|
+
}, [currentStroke]);
|
|
135
|
+
// Mouse event handlers
|
|
136
|
+
const handleMouseDown = useCallback((e) => {
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
handleStart(e.clientX, e.clientY);
|
|
139
|
+
}, [handleStart]);
|
|
140
|
+
const handleMouseMove = useCallback((e) => {
|
|
141
|
+
handleMove(e.clientX, e.clientY);
|
|
142
|
+
}, [handleMove]);
|
|
143
|
+
const handleMouseUp = useCallback(() => {
|
|
144
|
+
handleEnd();
|
|
145
|
+
}, [handleEnd]);
|
|
146
|
+
// Touch event handlers
|
|
147
|
+
const handleTouchStart = useCallback((e) => {
|
|
148
|
+
e.preventDefault();
|
|
149
|
+
if (e.touches.length > 0) {
|
|
150
|
+
handleStart(e.touches[0].clientX, e.touches[0].clientY);
|
|
151
|
+
}
|
|
152
|
+
}, [handleStart]);
|
|
153
|
+
const handleTouchMove = useCallback((e) => {
|
|
154
|
+
e.preventDefault();
|
|
155
|
+
if (e.touches.length > 0) {
|
|
156
|
+
handleMove(e.touches[0].clientX, e.touches[0].clientY);
|
|
157
|
+
}
|
|
158
|
+
}, [handleMove]);
|
|
159
|
+
const handleTouchEnd = useCallback(() => {
|
|
160
|
+
handleEnd();
|
|
161
|
+
}, [handleEnd]);
|
|
162
|
+
// Handle keyboard events
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
if (!isActive)
|
|
165
|
+
return;
|
|
166
|
+
const handleKeyDown = (e) => {
|
|
167
|
+
if (e.code === "Escape") {
|
|
168
|
+
console.log("DrawingCanvas: Cancelled via Escape");
|
|
169
|
+
onCancel();
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
173
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
174
|
+
}, [isActive, onCancel]);
|
|
175
|
+
// Clear drawing
|
|
176
|
+
const handleClear = () => {
|
|
177
|
+
console.log("DrawingCanvas: Cleared strokes");
|
|
178
|
+
setStrokes([]);
|
|
179
|
+
setCurrentStroke(null);
|
|
180
|
+
setPageNumber(null);
|
|
181
|
+
setPageElement(null);
|
|
182
|
+
};
|
|
183
|
+
// Complete drawing
|
|
184
|
+
const handleDone = () => {
|
|
185
|
+
if (strokes.length === 0 || pageNumber === null || !pageElement || !viewer) {
|
|
186
|
+
console.log("DrawingCanvas: No strokes to save");
|
|
187
|
+
onCancel();
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
console.log("DrawingCanvas: Completing drawing with", strokes.length, "strokes");
|
|
191
|
+
// Calculate bounding box of all strokes
|
|
192
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
193
|
+
strokes.forEach((stroke) => {
|
|
194
|
+
stroke.points.forEach((point) => {
|
|
195
|
+
minX = Math.min(minX, point.x);
|
|
196
|
+
minY = Math.min(minY, point.y);
|
|
197
|
+
maxX = Math.max(maxX, point.x);
|
|
198
|
+
maxY = Math.max(maxY, point.y);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
// Find max stroke width for padding
|
|
202
|
+
const maxStrokeWidth = Math.max(...strokes.map(s => s.width));
|
|
203
|
+
const padding = maxStrokeWidth * 2;
|
|
204
|
+
minX = Math.max(0, minX - padding);
|
|
205
|
+
minY = Math.max(0, minY - padding);
|
|
206
|
+
maxX = maxX + padding;
|
|
207
|
+
maxY = maxY + padding;
|
|
208
|
+
const width = maxX - minX;
|
|
209
|
+
const height = maxY - minY;
|
|
210
|
+
// Create a new canvas with just the drawing (cropped to bounding box)
|
|
211
|
+
const outputCanvas = document.createElement("canvas");
|
|
212
|
+
outputCanvas.width = width;
|
|
213
|
+
outputCanvas.height = height;
|
|
214
|
+
const outputCtx = outputCanvas.getContext("2d");
|
|
215
|
+
if (!outputCtx) {
|
|
216
|
+
console.error("DrawingCanvas: Could not get output canvas context");
|
|
217
|
+
onCancel();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// Draw all strokes offset by bounding box origin, using per-stroke color/width
|
|
221
|
+
strokes.forEach((stroke) => {
|
|
222
|
+
if (stroke.points.length < 2)
|
|
223
|
+
return;
|
|
224
|
+
outputCtx.strokeStyle = stroke.color;
|
|
225
|
+
outputCtx.lineWidth = stroke.width;
|
|
226
|
+
outputCtx.lineCap = "round";
|
|
227
|
+
outputCtx.lineJoin = "round";
|
|
228
|
+
outputCtx.beginPath();
|
|
229
|
+
outputCtx.moveTo(stroke.points[0].x - minX, stroke.points[0].y - minY);
|
|
230
|
+
stroke.points.slice(1).forEach((point) => {
|
|
231
|
+
outputCtx.lineTo(point.x - minX, point.y - minY);
|
|
232
|
+
});
|
|
233
|
+
outputCtx.stroke();
|
|
234
|
+
});
|
|
235
|
+
const dataUrl = outputCanvas.toDataURL("image/png");
|
|
236
|
+
// Create viewport position
|
|
237
|
+
const viewportPosition = {
|
|
238
|
+
boundingRect: {
|
|
239
|
+
left: minX,
|
|
240
|
+
top: minY,
|
|
241
|
+
width: width,
|
|
242
|
+
height: height,
|
|
243
|
+
pageNumber: pageNumber,
|
|
244
|
+
},
|
|
245
|
+
rects: [],
|
|
246
|
+
};
|
|
247
|
+
const scaledPosition = viewportPositionToScaled(viewportPosition, viewer);
|
|
248
|
+
// Normalize strokes relative to bounding box for storage
|
|
249
|
+
const normalizedStrokes = strokes.map((stroke) => ({
|
|
250
|
+
...stroke,
|
|
251
|
+
points: stroke.points.map((point) => ({
|
|
252
|
+
x: point.x - minX,
|
|
253
|
+
y: point.y - minY,
|
|
254
|
+
})),
|
|
255
|
+
}));
|
|
256
|
+
console.log("DrawingCanvas: Created drawing at position", scaledPosition);
|
|
257
|
+
onComplete(dataUrl, scaledPosition, normalizedStrokes);
|
|
258
|
+
// Reset state
|
|
259
|
+
setStrokes([]);
|
|
260
|
+
setCurrentStroke(null);
|
|
261
|
+
setPageNumber(null);
|
|
262
|
+
setPageElement(null);
|
|
263
|
+
};
|
|
264
|
+
if (!isActive)
|
|
265
|
+
return null;
|
|
266
|
+
return (React.createElement(React.Fragment, null,
|
|
267
|
+
React.createElement("canvas", { ref: canvasRef, className: "DrawingCanvas", style: {
|
|
268
|
+
width: pageElement ? pageElement.getBoundingClientRect().width : "100%",
|
|
269
|
+
height: pageElement ? pageElement.getBoundingClientRect().height : "100%",
|
|
270
|
+
position: "fixed",
|
|
271
|
+
}, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd }),
|
|
272
|
+
React.createElement("div", { className: "DrawingCanvas__controls" },
|
|
273
|
+
React.createElement("button", { type: "button", className: "DrawingCanvas__clearButton", onClick: handleClear }, "Clear"),
|
|
274
|
+
React.createElement("button", { type: "button", className: "DrawingCanvas__cancelButton", onClick: onCancel }, "Cancel"),
|
|
275
|
+
React.createElement("button", { type: "button", className: "DrawingCanvas__doneButton", onClick: handleDone }, "Done"))));
|
|
276
|
+
};
|
|
277
|
+
//# sourceMappingURL=DrawingCanvas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DrawingCanvas.js","sourceRoot":"","sources":["../../../src/components/DrawingCanvas.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React, { CSSProperties, MouseEvent, ReactNode } from "react";
|
|
2
|
+
import "../style/DrawingHighlight.css";
|
|
3
|
+
import type { DrawingStroke, LTWHP, ViewportHighlight } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* The props type for {@link DrawingHighlight}.
|
|
6
|
+
*
|
|
7
|
+
* @category Component Properties
|
|
8
|
+
*/
|
|
9
|
+
export interface DrawingHighlightProps {
|
|
10
|
+
/**
|
|
11
|
+
* The highlight to be rendered as a {@link DrawingHighlight}.
|
|
12
|
+
* The highlight.content.image should contain the drawing as a PNG data URL.
|
|
13
|
+
*/
|
|
14
|
+
highlight: ViewportHighlight;
|
|
15
|
+
/**
|
|
16
|
+
* A callback triggered whenever the highlight position or size changes.
|
|
17
|
+
*
|
|
18
|
+
* @param rect - The updated highlight area.
|
|
19
|
+
*/
|
|
20
|
+
onChange?(rect: LTWHP): void;
|
|
21
|
+
/**
|
|
22
|
+
* Has the highlight been auto-scrolled into view?
|
|
23
|
+
*/
|
|
24
|
+
isScrolledTo?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* react-rnd bounds on the highlight area.
|
|
27
|
+
*/
|
|
28
|
+
bounds?: string | Element;
|
|
29
|
+
/**
|
|
30
|
+
* A callback triggered on context menu.
|
|
31
|
+
*/
|
|
32
|
+
onContextMenu?(event: MouseEvent<HTMLDivElement>): void;
|
|
33
|
+
/**
|
|
34
|
+
* Event called when editing begins (drag or resize).
|
|
35
|
+
*/
|
|
36
|
+
onEditStart?(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Event called when editing ends.
|
|
39
|
+
*/
|
|
40
|
+
onEditEnd?(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Custom styling for the container.
|
|
43
|
+
*/
|
|
44
|
+
style?: CSSProperties;
|
|
45
|
+
/**
|
|
46
|
+
* Custom drag icon. Replaces the default 6-dot grid icon.
|
|
47
|
+
*/
|
|
48
|
+
dragIcon?: ReactNode;
|
|
49
|
+
/**
|
|
50
|
+
* Callback when drawing style changes (color or stroke width).
|
|
51
|
+
* The newImage is the re-rendered PNG data URL with updated styles.
|
|
52
|
+
* The newStrokes contain the updated stroke data.
|
|
53
|
+
*/
|
|
54
|
+
onStyleChange?(newImage: string, newStrokes: DrawingStroke[]): void;
|
|
55
|
+
/**
|
|
56
|
+
* Callback triggered when the delete button is clicked.
|
|
57
|
+
*/
|
|
58
|
+
onDelete?(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Custom delete icon. Replaces the default trash icon.
|
|
61
|
+
*/
|
|
62
|
+
deleteIcon?: ReactNode;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Renders a draggable, resizable freehand drawing annotation.
|
|
66
|
+
* Drawings are stored as PNG images with transparent backgrounds.
|
|
67
|
+
*
|
|
68
|
+
* @category Component
|
|
69
|
+
*/
|
|
70
|
+
export declare const DrawingHighlight: ({ highlight, onChange, isScrolledTo, bounds, onContextMenu, onEditStart, onEditEnd, style, dragIcon, onStyleChange, onDelete, deleteIcon, }: DrawingHighlightProps) => React.JSX.Element;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React, { useState, useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import { Rnd } from "react-rnd";
|
|
3
|
+
import { getPageFromElement } from "../lib/pdfjs-dom";
|
|
4
|
+
import "../style/DrawingHighlight.css";
|
|
5
|
+
// Drawing style presets (same as toolbar)
|
|
6
|
+
const DRAWING_COLORS = ["#000000", "#FF0000", "#0000FF", "#00FF00", "#FFFF00"];
|
|
7
|
+
const STROKE_WIDTHS = [
|
|
8
|
+
{ label: "Thin", value: 1 },
|
|
9
|
+
{ label: "Medium", value: 3 },
|
|
10
|
+
{ label: "Thick", value: 5 },
|
|
11
|
+
];
|
|
12
|
+
/**
|
|
13
|
+
* Default drag icon - 6 dot grid pattern.
|
|
14
|
+
*/
|
|
15
|
+
const DefaultDragIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
16
|
+
React.createElement("circle", { cx: "8", cy: "6", r: "2" }),
|
|
17
|
+
React.createElement("circle", { cx: "16", cy: "6", r: "2" }),
|
|
18
|
+
React.createElement("circle", { cx: "8", cy: "12", r: "2" }),
|
|
19
|
+
React.createElement("circle", { cx: "16", cy: "12", r: "2" }),
|
|
20
|
+
React.createElement("circle", { cx: "8", cy: "18", r: "2" }),
|
|
21
|
+
React.createElement("circle", { cx: "16", cy: "18", r: "2" })));
|
|
22
|
+
const DefaultDeleteIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
23
|
+
React.createElement("path", { d: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" })));
|
|
24
|
+
/**
|
|
25
|
+
* Re-render strokes to a canvas and return as PNG data URL.
|
|
26
|
+
*/
|
|
27
|
+
const renderStrokesToImage = (strokes, width, height) => {
|
|
28
|
+
const canvas = document.createElement("canvas");
|
|
29
|
+
canvas.width = width;
|
|
30
|
+
canvas.height = height;
|
|
31
|
+
const ctx = canvas.getContext("2d");
|
|
32
|
+
if (!ctx)
|
|
33
|
+
return "";
|
|
34
|
+
strokes.forEach((stroke) => {
|
|
35
|
+
if (stroke.points.length < 2)
|
|
36
|
+
return;
|
|
37
|
+
ctx.strokeStyle = stroke.color;
|
|
38
|
+
ctx.lineWidth = stroke.width;
|
|
39
|
+
ctx.lineCap = "round";
|
|
40
|
+
ctx.lineJoin = "round";
|
|
41
|
+
ctx.beginPath();
|
|
42
|
+
ctx.moveTo(stroke.points[0].x, stroke.points[0].y);
|
|
43
|
+
stroke.points.slice(1).forEach((point) => {
|
|
44
|
+
ctx.lineTo(point.x, point.y);
|
|
45
|
+
});
|
|
46
|
+
ctx.stroke();
|
|
47
|
+
});
|
|
48
|
+
return canvas.toDataURL("image/png");
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Renders a draggable, resizable freehand drawing annotation.
|
|
52
|
+
* Drawings are stored as PNG images with transparent backgrounds.
|
|
53
|
+
*
|
|
54
|
+
* @category Component
|
|
55
|
+
*/
|
|
56
|
+
export const DrawingHighlight = ({ highlight, onChange, isScrolledTo, bounds, onContextMenu, onEditStart, onEditEnd, style, dragIcon, onStyleChange, onDelete, deleteIcon, }) => {
|
|
57
|
+
const highlightClass = isScrolledTo ? "DrawingHighlight--scrolledTo" : "";
|
|
58
|
+
const [showStyleControls, setShowStyleControls] = useState(false);
|
|
59
|
+
const styleControlsRef = useRef(null);
|
|
60
|
+
// Close style controls when clicking outside
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!showStyleControls)
|
|
63
|
+
return;
|
|
64
|
+
const handleClickOutside = (e) => {
|
|
65
|
+
if (styleControlsRef.current && !styleControlsRef.current.contains(e.target)) {
|
|
66
|
+
setShowStyleControls(false);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
// Delay adding listener to avoid immediate close
|
|
70
|
+
const timeoutId = setTimeout(() => {
|
|
71
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
72
|
+
}, 0);
|
|
73
|
+
return () => {
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
76
|
+
};
|
|
77
|
+
}, [showStyleControls]);
|
|
78
|
+
// Generate key based on position for Rnd remount on position changes
|
|
79
|
+
const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;
|
|
80
|
+
const imageUrl = highlight.content?.image;
|
|
81
|
+
const strokes = highlight.content?.strokes;
|
|
82
|
+
// Apply new color to all strokes
|
|
83
|
+
const handleColorChange = useCallback((newColor) => {
|
|
84
|
+
if (!strokes || !onStyleChange)
|
|
85
|
+
return;
|
|
86
|
+
console.log("DrawingHighlight: Changing color to", newColor);
|
|
87
|
+
const newStrokes = strokes.map((stroke) => ({
|
|
88
|
+
...stroke,
|
|
89
|
+
color: newColor,
|
|
90
|
+
}));
|
|
91
|
+
const newImage = renderStrokesToImage(newStrokes, highlight.position.boundingRect.width, highlight.position.boundingRect.height);
|
|
92
|
+
onStyleChange(newImage, newStrokes);
|
|
93
|
+
}, [strokes, onStyleChange, highlight.position.boundingRect.width, highlight.position.boundingRect.height]);
|
|
94
|
+
// Apply new width to all strokes
|
|
95
|
+
const handleWidthChange = useCallback((newWidth) => {
|
|
96
|
+
if (!strokes || !onStyleChange)
|
|
97
|
+
return;
|
|
98
|
+
console.log("DrawingHighlight: Changing width to", newWidth);
|
|
99
|
+
const newStrokes = strokes.map((stroke) => ({
|
|
100
|
+
...stroke,
|
|
101
|
+
width: newWidth,
|
|
102
|
+
}));
|
|
103
|
+
const newImage = renderStrokesToImage(newStrokes, highlight.position.boundingRect.width, highlight.position.boundingRect.height);
|
|
104
|
+
onStyleChange(newImage, newStrokes);
|
|
105
|
+
}, [strokes, onStyleChange, highlight.position.boundingRect.width, highlight.position.boundingRect.height]);
|
|
106
|
+
// Get current color from first stroke (for showing active state)
|
|
107
|
+
const currentColor = strokes?.[0]?.color || "#000000";
|
|
108
|
+
const currentWidth = strokes?.[0]?.width || 3;
|
|
109
|
+
return (React.createElement("div", { className: `DrawingHighlight ${highlightClass}`, onContextMenu: onContextMenu },
|
|
110
|
+
React.createElement(Rnd, { className: "DrawingHighlight__rnd", onDragStop: (_, data) => {
|
|
111
|
+
const boundingRect = {
|
|
112
|
+
...highlight.position.boundingRect,
|
|
113
|
+
top: data.y,
|
|
114
|
+
left: data.x,
|
|
115
|
+
};
|
|
116
|
+
onChange?.(boundingRect);
|
|
117
|
+
onEditEnd?.();
|
|
118
|
+
}, onDragStart: onEditStart, onResizeStop: (_e, _direction, ref, _delta, position) => {
|
|
119
|
+
const boundingRect = {
|
|
120
|
+
top: position.y,
|
|
121
|
+
left: position.x,
|
|
122
|
+
width: ref.offsetWidth,
|
|
123
|
+
height: ref.offsetHeight,
|
|
124
|
+
pageNumber: getPageFromElement(ref)?.number ||
|
|
125
|
+
highlight.position.boundingRect.pageNumber,
|
|
126
|
+
};
|
|
127
|
+
onChange?.(boundingRect);
|
|
128
|
+
onEditEnd?.();
|
|
129
|
+
}, onResizeStart: onEditStart, default: {
|
|
130
|
+
x: highlight.position.boundingRect.left,
|
|
131
|
+
y: highlight.position.boundingRect.top,
|
|
132
|
+
width: highlight.position.boundingRect.width || 150,
|
|
133
|
+
height: highlight.position.boundingRect.height || 100,
|
|
134
|
+
}, minWidth: 30, minHeight: 30, key: key, bounds: bounds,
|
|
135
|
+
// No aspect ratio lock for drawings - allow free resizing
|
|
136
|
+
lockAspectRatio: false, dragHandleClassName: "DrawingHighlight__drag-handle", onClick: (event) => {
|
|
137
|
+
event.stopPropagation();
|
|
138
|
+
event.preventDefault();
|
|
139
|
+
}, style: style },
|
|
140
|
+
React.createElement("div", { className: "DrawingHighlight__container" },
|
|
141
|
+
React.createElement("div", { className: "DrawingHighlight__toolbar" },
|
|
142
|
+
React.createElement("div", { className: "DrawingHighlight__drag-handle", title: "Drag to move" }, dragIcon || React.createElement(DefaultDragIcon, null)),
|
|
143
|
+
strokes && strokes.length > 0 && onStyleChange && (React.createElement("button", { type: "button", className: "DrawingHighlight__style-button", title: "Edit style", onClick: (e) => {
|
|
144
|
+
e.stopPropagation();
|
|
145
|
+
setShowStyleControls(!showStyleControls);
|
|
146
|
+
} },
|
|
147
|
+
React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
148
|
+
React.createElement("path", { d: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" })))),
|
|
149
|
+
onDelete && (React.createElement("button", { className: "DrawingHighlight__delete-button", onClick: (e) => {
|
|
150
|
+
e.stopPropagation();
|
|
151
|
+
onDelete();
|
|
152
|
+
}, title: "Delete", type: "button" }, deleteIcon || React.createElement(DefaultDeleteIcon, null)))),
|
|
153
|
+
showStyleControls && strokes && strokes.length > 0 && onStyleChange && (React.createElement("div", { className: "DrawingHighlight__style-controls", ref: styleControlsRef },
|
|
154
|
+
React.createElement("div", { className: "DrawingHighlight__color-picker" }, DRAWING_COLORS.map((color) => (React.createElement("button", { key: color, type: "button", className: `DrawingHighlight__color-button ${currentColor === color ? 'active' : ''}`, style: { backgroundColor: color }, onClick: (e) => {
|
|
155
|
+
e.stopPropagation();
|
|
156
|
+
handleColorChange(color);
|
|
157
|
+
}, title: `Color: ${color}` })))),
|
|
158
|
+
React.createElement("div", { className: "DrawingHighlight__width-picker" }, STROKE_WIDTHS.map((w) => (React.createElement("button", { key: w.value, type: "button", className: `DrawingHighlight__width-button ${currentWidth === w.value ? 'active' : ''}`, onClick: (e) => {
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
handleWidthChange(w.value);
|
|
161
|
+
}, title: w.label }, w.label)))))),
|
|
162
|
+
React.createElement("div", { className: "DrawingHighlight__content" }, imageUrl ? (React.createElement("img", { src: imageUrl, alt: "Drawing", className: "DrawingHighlight__image", draggable: false })) : (React.createElement("div", { className: "DrawingHighlight__placeholder" }, "No drawing")))))));
|
|
163
|
+
};
|
|
164
|
+
//# sourceMappingURL=DrawingHighlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DrawingHighlight.js","sourceRoot":"","sources":["../../../src/components/DrawingHighlight.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import React, { CSSProperties, MouseEvent, ReactNode } from "react";
|
|
2
|
+
import "../style/FreetextHighlight.css";
|
|
3
|
+
import type { LTWHP, ViewportHighlight } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* Style options for freetext highlight appearance.
|
|
6
|
+
*/
|
|
7
|
+
export interface FreetextStyle {
|
|
8
|
+
color?: string;
|
|
9
|
+
backgroundColor?: string;
|
|
10
|
+
fontFamily?: string;
|
|
11
|
+
fontSize?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The props type for {@link FreetextHighlight}.
|
|
15
|
+
*
|
|
16
|
+
* @category Component Properties
|
|
17
|
+
*/
|
|
18
|
+
export interface FreetextHighlightProps {
|
|
19
|
+
/**
|
|
20
|
+
* The highlight to be rendered as a {@link FreetextHighlight}.
|
|
21
|
+
*/
|
|
22
|
+
highlight: ViewportHighlight;
|
|
23
|
+
/**
|
|
24
|
+
* A callback triggered whenever the highlight position changes (drag).
|
|
25
|
+
*
|
|
26
|
+
* @param rect - The updated highlight area.
|
|
27
|
+
*/
|
|
28
|
+
onChange?(rect: LTWHP): void;
|
|
29
|
+
/**
|
|
30
|
+
* A callback triggered whenever the text content changes.
|
|
31
|
+
*
|
|
32
|
+
* @param text - The new text content.
|
|
33
|
+
*/
|
|
34
|
+
onTextChange?(text: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* A callback triggered whenever the style changes.
|
|
37
|
+
*
|
|
38
|
+
* @param style - The new style options.
|
|
39
|
+
*/
|
|
40
|
+
onStyleChange?(style: FreetextStyle): void;
|
|
41
|
+
/**
|
|
42
|
+
* Has the highlight been auto-scrolled into view?
|
|
43
|
+
*/
|
|
44
|
+
isScrolledTo?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* react-rnd bounds on the highlight area.
|
|
47
|
+
*/
|
|
48
|
+
bounds?: string | Element;
|
|
49
|
+
/**
|
|
50
|
+
* A callback triggered on context menu.
|
|
51
|
+
*/
|
|
52
|
+
onContextMenu?(event: MouseEvent<HTMLDivElement>): void;
|
|
53
|
+
/**
|
|
54
|
+
* Event called when editing begins (drag or text edit).
|
|
55
|
+
*/
|
|
56
|
+
onEditStart?(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Event called when editing ends.
|
|
59
|
+
*/
|
|
60
|
+
onEditEnd?(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Custom styling for the container.
|
|
63
|
+
*/
|
|
64
|
+
style?: CSSProperties;
|
|
65
|
+
/**
|
|
66
|
+
* Text color.
|
|
67
|
+
*/
|
|
68
|
+
color?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Background color.
|
|
71
|
+
*/
|
|
72
|
+
backgroundColor?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Font family.
|
|
75
|
+
*/
|
|
76
|
+
fontFamily?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Font size (e.g., "14px").
|
|
79
|
+
*/
|
|
80
|
+
fontSize?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Custom drag icon. Receives default icon as child if not provided.
|
|
83
|
+
*/
|
|
84
|
+
dragIcon?: ReactNode;
|
|
85
|
+
/**
|
|
86
|
+
* Custom edit icon. Receives default icon as child if not provided.
|
|
87
|
+
*/
|
|
88
|
+
editIcon?: ReactNode;
|
|
89
|
+
/**
|
|
90
|
+
* Custom style/settings icon. Receives default icon as child if not provided.
|
|
91
|
+
*/
|
|
92
|
+
styleIcon?: ReactNode;
|
|
93
|
+
/**
|
|
94
|
+
* Custom background color presets for the style panel.
|
|
95
|
+
* Default: ["#ffffc8", "#ffcdd2", "#c8e6c9", "#bbdefb", "#e1bee7"]
|
|
96
|
+
*/
|
|
97
|
+
backgroundColorPresets?: string[];
|
|
98
|
+
/**
|
|
99
|
+
* Custom text color presets for the style panel.
|
|
100
|
+
* Default: ["#333333", "#d32f2f", "#1976d2", "#388e3c", "#7b1fa2"]
|
|
101
|
+
*/
|
|
102
|
+
textColorPresets?: string[];
|
|
103
|
+
/**
|
|
104
|
+
* Callback triggered when the delete button is clicked.
|
|
105
|
+
*/
|
|
106
|
+
onDelete?(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Custom delete icon. Replaces the default trash icon.
|
|
109
|
+
*/
|
|
110
|
+
deleteIcon?: ReactNode;
|
|
111
|
+
}
|
|
112
|
+
export declare const FreetextHighlight: ({ highlight, onChange, onTextChange, onStyleChange, isScrolledTo, bounds, onContextMenu, onEditStart, onEditEnd, style, color, backgroundColor, fontFamily, fontSize, dragIcon, editIcon, styleIcon, backgroundColorPresets, textColorPresets, onDelete, deleteIcon, }: FreetextHighlightProps) => React.JSX.Element;
|