@embedpdf/plugin-annotation 1.0.14 → 1.0.16
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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +24 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/annotation-plugin.d.ts +1 -0
- package/dist/lib/helpers.d.ts +1 -0
- package/dist/lib/types.d.ts +6 -3
- package/dist/preact/adapter.d.ts +2 -0
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +321 -48
- package/dist/preact/index.js.map +1 -1
- package/dist/react/adapter.d.ts +2 -2
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +321 -48
- package/dist/react/index.js.map +1 -1
- package/dist/shared-preact/components/annotation-container.d.ts +2 -1
- package/dist/shared-preact/components/annotations/circle.d.ts +5 -5
- package/dist/shared-preact/components/annotations/free-text.d.ts +2 -2
- package/dist/shared-preact/components/annotations/ink.d.ts +5 -5
- package/dist/shared-preact/components/annotations/line.d.ts +2 -2
- package/dist/shared-preact/components/annotations/polygon.d.ts +2 -2
- package/dist/shared-preact/components/annotations/polyline.d.ts +2 -2
- package/dist/shared-preact/components/annotations/square.d.ts +5 -5
- package/dist/shared-preact/components/annotations/stamp-paint.d.ts +8 -0
- package/dist/shared-preact/components/annotations/stamp.d.ts +12 -0
- package/dist/shared-preact/components/counter-rotate-container.d.ts +2 -1
- package/dist/shared-preact/components/render-annotation.d.ts +1 -1
- package/dist/shared-preact/components/text-markup/highlight.d.ts +2 -2
- package/dist/shared-preact/components/text-markup/squiggly.d.ts +2 -2
- package/dist/shared-preact/components/text-markup/strikeout.d.ts +2 -2
- package/dist/shared-preact/components/text-markup/underline.d.ts +2 -2
- package/dist/shared-preact/hooks/use-drag-resize.d.ts +10 -3
- package/dist/shared-react/components/annotation-container.d.ts +2 -1
- package/dist/shared-react/components/annotations/circle.d.ts +5 -5
- package/dist/shared-react/components/annotations/free-text.d.ts +2 -2
- package/dist/shared-react/components/annotations/ink.d.ts +5 -5
- package/dist/shared-react/components/annotations/line.d.ts +2 -2
- package/dist/shared-react/components/annotations/polygon.d.ts +2 -2
- package/dist/shared-react/components/annotations/polyline.d.ts +2 -2
- package/dist/shared-react/components/annotations/square.d.ts +5 -5
- package/dist/shared-react/components/annotations/stamp-paint.d.ts +8 -0
- package/dist/shared-react/components/annotations/stamp.d.ts +12 -0
- package/dist/shared-react/components/counter-rotate-container.d.ts +2 -1
- package/dist/shared-react/components/render-annotation.d.ts +1 -1
- package/dist/shared-react/components/text-markup/highlight.d.ts +2 -2
- package/dist/shared-react/components/text-markup/squiggly.d.ts +2 -2
- package/dist/shared-react/components/text-markup/strikeout.d.ts +2 -2
- package/dist/shared-react/components/text-markup/underline.d.ts +2 -2
- package/dist/shared-react/hooks/use-drag-resize.d.ts +10 -3
- package/package.json +14 -9
package/dist/react/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { usePlugin, useCapability } from "@embedpdf/core/react";
|
|
2
|
-
import { AnnotationPlugin, patching, getAnnotationsByPageIndex, getSelectedAnnotationByPageIndex, isInk, isSquare, isCircle, isUnderline, isStrikeout, isSquiggly, isHighlight, isLine, isPolyline, isPolygon, isFreeText } from "@embedpdf/plugin-annotation";
|
|
2
|
+
import { AnnotationPlugin, patching, getAnnotationsByPageIndex, getSelectedAnnotationByPageIndex, isInk, isSquare, isCircle, isUnderline, isStrikeout, isSquiggly, isHighlight, isLine, isPolyline, isPolygon, isFreeText, isStamp } from "@embedpdf/plugin-annotation";
|
|
3
3
|
import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
|
|
4
|
-
import { restoreOffset, rectEquals, PdfAnnotationBorderStyle, PdfAnnotationSubtype, expandRect, rectFromPoints, textAlignmentToCss, standardFontCss, PdfVerticalAlignment, blendModeToCss, PdfBlendMode } from "@embedpdf/models";
|
|
4
|
+
import { restoreOffset, rectEquals, PdfAnnotationBorderStyle, PdfAnnotationSubtype, expandRect, rectFromPoints, textAlignmentToCss, standardFontCss, PdfVerticalAlignment, ignore, PdfErrorCode, blendModeToCss, PdfBlendMode } from "@embedpdf/models";
|
|
5
5
|
import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/react";
|
|
6
6
|
import { useSelectionCapability } from "@embedpdf/plugin-selection/react";
|
|
7
7
|
import { Fragment, useState, useRef, useEffect, useLayoutEffect, useMemo, useCallback } from "react";
|
|
@@ -53,7 +53,8 @@ function CounterRotate({ children, ...props }) {
|
|
|
53
53
|
};
|
|
54
54
|
const menuWrapperProps = {
|
|
55
55
|
style: menuWrapperStyle,
|
|
56
|
-
onPointerDown: (e) => e.stopPropagation()
|
|
56
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
57
|
+
onTouchStart: (e) => e.stopPropagation()
|
|
57
58
|
};
|
|
58
59
|
return /* @__PURE__ */ jsx(Fragment, { children: children({
|
|
59
60
|
menuWrapperProps,
|
|
@@ -150,6 +151,7 @@ function useDragResize({
|
|
|
150
151
|
isResizable,
|
|
151
152
|
computePatch,
|
|
152
153
|
computeVertices,
|
|
154
|
+
lockAspectRatio = false,
|
|
153
155
|
currentRect,
|
|
154
156
|
setCurrentRect,
|
|
155
157
|
setCurrentVertices,
|
|
@@ -184,6 +186,23 @@ function useDragResize({
|
|
|
184
186
|
oy += dy;
|
|
185
187
|
h -= dy;
|
|
186
188
|
}
|
|
189
|
+
if (lockAspectRatio && startRect.current) {
|
|
190
|
+
const ratio = startRect.current.size.width / startRect.current.size.height;
|
|
191
|
+
const anchorRight = ox + w;
|
|
192
|
+
const anchorBottom = oy + h;
|
|
193
|
+
const horizontalPrimary = dir.current.includes("left") || dir.current.includes("right");
|
|
194
|
+
if (horizontalPrimary) {
|
|
195
|
+
h = w / ratio;
|
|
196
|
+
} else {
|
|
197
|
+
w = h * ratio;
|
|
198
|
+
}
|
|
199
|
+
if (dir.current.includes("left")) {
|
|
200
|
+
ox = anchorRight - w;
|
|
201
|
+
}
|
|
202
|
+
if (dir.current.includes("top")) {
|
|
203
|
+
oy = anchorBottom - h;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
187
206
|
}
|
|
188
207
|
if (w < 1 || h < 1) return currentRect;
|
|
189
208
|
w = clamp(w, 1, pageW);
|
|
@@ -192,20 +211,16 @@ function useDragResize({
|
|
|
192
211
|
oy = clamp(oy, 0, pageH - h);
|
|
193
212
|
return { origin: { x: ox, y: oy }, size: { width: w, height: h } };
|
|
194
213
|
};
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
e.preventDefault();
|
|
199
|
-
drag.current = "dragging";
|
|
200
|
-
startPos.current = { x: e.clientX, y: e.clientY };
|
|
214
|
+
const beginDrag = (kind, clientX, clientY) => {
|
|
215
|
+
drag.current = kind;
|
|
216
|
+
startPos.current = { x: clientX, y: clientY };
|
|
201
217
|
startRect.current = currentRect;
|
|
202
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
203
218
|
};
|
|
204
|
-
const
|
|
219
|
+
const handleMove = (clientX, clientY) => {
|
|
205
220
|
if (drag.current === "idle" || !startPos.current) return;
|
|
206
221
|
const disp = {
|
|
207
|
-
x:
|
|
208
|
-
y:
|
|
222
|
+
x: clientX - startPos.current.x,
|
|
223
|
+
y: clientY - startPos.current.y
|
|
209
224
|
};
|
|
210
225
|
const { x, y } = restoreOffset(disp, rotation, scale);
|
|
211
226
|
const nextRect = applyDelta(x, y);
|
|
@@ -220,7 +235,7 @@ function useDragResize({
|
|
|
220
235
|
setCurrentRect(patch.rect ?? nextRect);
|
|
221
236
|
setPreviewObject(patch);
|
|
222
237
|
};
|
|
223
|
-
const
|
|
238
|
+
const finishDragInternal = () => {
|
|
224
239
|
if (drag.current === "idle") return;
|
|
225
240
|
const usedDir = dir.current || "bottom-right";
|
|
226
241
|
drag.current = "idle";
|
|
@@ -237,16 +252,45 @@ function useDragResize({
|
|
|
237
252
|
dir.current = "none";
|
|
238
253
|
setPreviewObject(null);
|
|
239
254
|
};
|
|
255
|
+
const onPointerDown = (e) => {
|
|
256
|
+
if (!isSelected || !isDraggable) return;
|
|
257
|
+
e.stopPropagation();
|
|
258
|
+
e.preventDefault();
|
|
259
|
+
beginDrag("dragging", e.clientX, e.clientY);
|
|
260
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
261
|
+
};
|
|
262
|
+
const onPointerMove = (e) => handleMove(e.clientX, e.clientY);
|
|
263
|
+
const onPointerUp = (e) => {
|
|
264
|
+
finishDragInternal();
|
|
265
|
+
if ((e == null ? void 0 : e.currentTarget) && e.pointerId !== void 0) {
|
|
266
|
+
try {
|
|
267
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
268
|
+
} catch {
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
};
|
|
240
272
|
const startResize = (direction) => (e) => {
|
|
241
273
|
if (!isSelected || !isResizable) return;
|
|
242
274
|
e.stopPropagation();
|
|
243
275
|
e.preventDefault();
|
|
244
|
-
drag.current = "resizing";
|
|
245
276
|
dir.current = direction;
|
|
246
|
-
|
|
247
|
-
startRect.current = currentRect;
|
|
277
|
+
beginDrag("resizing", e.clientX, e.clientY);
|
|
248
278
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
249
279
|
};
|
|
280
|
+
const onTouchStart = (e) => {
|
|
281
|
+
if (!isSelected || !isDraggable) return;
|
|
282
|
+
e.stopPropagation();
|
|
283
|
+
e.preventDefault();
|
|
284
|
+
const t = e.touches[0];
|
|
285
|
+
if (!t) return;
|
|
286
|
+
beginDrag("dragging", t.clientX, t.clientY);
|
|
287
|
+
};
|
|
288
|
+
const onTouchMove = (e) => {
|
|
289
|
+
const t = e.touches[0];
|
|
290
|
+
if (!t) return;
|
|
291
|
+
handleMove(t.clientX, t.clientY);
|
|
292
|
+
};
|
|
293
|
+
const onTouchEnd = () => finishDragInternal();
|
|
250
294
|
useEffect(() => {
|
|
251
295
|
drag.current = "idle";
|
|
252
296
|
dir.current = "none";
|
|
@@ -257,7 +301,14 @@ function useDragResize({
|
|
|
257
301
|
rootHandlers: {
|
|
258
302
|
onPointerDown,
|
|
259
303
|
onPointerMove,
|
|
260
|
-
onPointerUp
|
|
304
|
+
onPointerUp,
|
|
305
|
+
onPointerCancel: () => onPointerUp(),
|
|
306
|
+
onLostPointerCapture: () => onPointerUp(),
|
|
307
|
+
/* mobile touch fallback */
|
|
308
|
+
onTouchStart,
|
|
309
|
+
onTouchMove,
|
|
310
|
+
onTouchEnd,
|
|
311
|
+
onTouchCancel: onTouchEnd
|
|
261
312
|
},
|
|
262
313
|
startResize
|
|
263
314
|
};
|
|
@@ -335,6 +386,7 @@ function AnnotationContainer({
|
|
|
335
386
|
isSelected = false,
|
|
336
387
|
isDraggable = true,
|
|
337
388
|
isResizable = true,
|
|
389
|
+
lockAspectRatio = false,
|
|
338
390
|
computeVertices,
|
|
339
391
|
computePatch,
|
|
340
392
|
selectionMenu,
|
|
@@ -356,6 +408,7 @@ function AnnotationContainer({
|
|
|
356
408
|
isSelected,
|
|
357
409
|
isDraggable,
|
|
358
410
|
isResizable,
|
|
411
|
+
lockAspectRatio,
|
|
359
412
|
computePatch,
|
|
360
413
|
computeVertices,
|
|
361
414
|
currentRect,
|
|
@@ -387,6 +440,7 @@ function AnnotationContainer({
|
|
|
387
440
|
width: `${currentRect.size.width * scale}px`,
|
|
388
441
|
height: `${currentRect.size.height * scale}px`,
|
|
389
442
|
pointerEvents: isSelected ? "auto" : "none",
|
|
443
|
+
touchAction: isSelected ? "auto" : "none",
|
|
390
444
|
cursor: isSelected && isDraggable ? "move" : "default",
|
|
391
445
|
...isSelected && {
|
|
392
446
|
zIndex: 3
|
|
@@ -467,7 +521,8 @@ function Highlight({
|
|
|
467
521
|
return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((b, i) => /* @__PURE__ */ jsx(
|
|
468
522
|
"div",
|
|
469
523
|
{
|
|
470
|
-
|
|
524
|
+
onPointerDown: onClick,
|
|
525
|
+
onTouchStart: onClick,
|
|
471
526
|
style: {
|
|
472
527
|
position: "absolute",
|
|
473
528
|
left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,
|
|
@@ -500,7 +555,8 @@ function Underline({
|
|
|
500
555
|
return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
|
|
501
556
|
"div",
|
|
502
557
|
{
|
|
503
|
-
|
|
558
|
+
onPointerDown: onClick,
|
|
559
|
+
onTouchStart: onClick,
|
|
504
560
|
style: {
|
|
505
561
|
position: "absolute",
|
|
506
562
|
left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
|
|
@@ -547,7 +603,8 @@ function Strikeout({
|
|
|
547
603
|
return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
|
|
548
604
|
"div",
|
|
549
605
|
{
|
|
550
|
-
|
|
606
|
+
onPointerDown: onClick,
|
|
607
|
+
onTouchStart: onClick,
|
|
551
608
|
style: {
|
|
552
609
|
position: "absolute",
|
|
553
610
|
left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
|
|
@@ -601,7 +658,8 @@ function Squiggly({
|
|
|
601
658
|
return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
|
|
602
659
|
"div",
|
|
603
660
|
{
|
|
604
|
-
|
|
661
|
+
onPointerDown: onClick,
|
|
662
|
+
onTouchStart: onClick,
|
|
605
663
|
style: {
|
|
606
664
|
position: "absolute",
|
|
607
665
|
left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
|
|
@@ -637,14 +695,14 @@ function Squiggly({
|
|
|
637
695
|
)) });
|
|
638
696
|
}
|
|
639
697
|
function Ink({
|
|
698
|
+
isSelected,
|
|
640
699
|
color = "#000000",
|
|
641
700
|
opacity = 1,
|
|
642
701
|
strokeWidth,
|
|
643
702
|
inkList,
|
|
644
703
|
rect,
|
|
645
704
|
scale,
|
|
646
|
-
onClick
|
|
647
|
-
cursor
|
|
705
|
+
onClick
|
|
648
706
|
}) {
|
|
649
707
|
const paths = useMemo(() => {
|
|
650
708
|
return inkList.map(({ points }) => {
|
|
@@ -679,10 +737,11 @@ function Ink({
|
|
|
679
737
|
d,
|
|
680
738
|
fill: "none",
|
|
681
739
|
opacity,
|
|
682
|
-
|
|
740
|
+
onPointerDown: onClick,
|
|
741
|
+
onTouchStart: onClick,
|
|
683
742
|
style: {
|
|
684
|
-
cursor,
|
|
685
|
-
pointerEvents: "visibleStroke",
|
|
743
|
+
cursor: isSelected ? "move" : "pointer",
|
|
744
|
+
pointerEvents: isSelected ? "none" : "visibleStroke",
|
|
686
745
|
stroke: color,
|
|
687
746
|
strokeWidth,
|
|
688
747
|
strokeLinecap: "round",
|
|
@@ -695,6 +754,7 @@ function Ink({
|
|
|
695
754
|
);
|
|
696
755
|
}
|
|
697
756
|
function Square({
|
|
757
|
+
isSelected,
|
|
698
758
|
color = "#000000",
|
|
699
759
|
strokeColor,
|
|
700
760
|
opacity = 1,
|
|
@@ -703,8 +763,7 @@ function Square({
|
|
|
703
763
|
strokeDashArray,
|
|
704
764
|
rect,
|
|
705
765
|
scale,
|
|
706
|
-
onClick
|
|
707
|
-
cursor
|
|
766
|
+
onClick
|
|
708
767
|
}) {
|
|
709
768
|
const { width, height, x, y } = useMemo(() => {
|
|
710
769
|
const outerW = rect.size.width;
|
|
@@ -742,10 +801,11 @@ function Square({
|
|
|
742
801
|
height,
|
|
743
802
|
fill: color,
|
|
744
803
|
opacity,
|
|
745
|
-
|
|
804
|
+
onPointerDown: onClick,
|
|
805
|
+
onTouchStart: onClick,
|
|
746
806
|
style: {
|
|
747
|
-
cursor,
|
|
748
|
-
pointerEvents: color === "transparent" ? "visibleStroke" : "visible",
|
|
807
|
+
cursor: isSelected ? "move" : "pointer",
|
|
808
|
+
pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
|
|
749
809
|
stroke: strokeColor ?? color,
|
|
750
810
|
strokeWidth,
|
|
751
811
|
...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
|
|
@@ -767,7 +827,7 @@ function Circle({
|
|
|
767
827
|
rect,
|
|
768
828
|
scale,
|
|
769
829
|
onClick,
|
|
770
|
-
|
|
830
|
+
isSelected
|
|
771
831
|
}) {
|
|
772
832
|
const { width, height, cx, cy, rx, ry } = useMemo(() => {
|
|
773
833
|
const outerW = rect.size.width;
|
|
@@ -808,10 +868,11 @@ function Circle({
|
|
|
808
868
|
ry,
|
|
809
869
|
fill: color,
|
|
810
870
|
opacity,
|
|
811
|
-
|
|
871
|
+
onPointerDown: onClick,
|
|
872
|
+
onTouchStart: onClick,
|
|
812
873
|
style: {
|
|
813
|
-
cursor,
|
|
814
|
-
pointerEvents: color === "transparent" ? "visibleStroke" : "visible",
|
|
874
|
+
cursor: isSelected ? "move" : "pointer",
|
|
875
|
+
pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
|
|
815
876
|
stroke: strokeColor ?? color,
|
|
816
877
|
strokeWidth,
|
|
817
878
|
...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
|
|
@@ -919,7 +980,8 @@ function Line({
|
|
|
919
980
|
x2,
|
|
920
981
|
y2,
|
|
921
982
|
opacity,
|
|
922
|
-
|
|
983
|
+
onPointerDown: onClick,
|
|
984
|
+
onTouchStart: onClick,
|
|
923
985
|
style: {
|
|
924
986
|
cursor: isSelected ? "move" : "pointer",
|
|
925
987
|
pointerEvents: "visibleStroke",
|
|
@@ -937,7 +999,8 @@ function Line({
|
|
|
937
999
|
{
|
|
938
1000
|
d: endings.start.d,
|
|
939
1001
|
transform: endings.start.transform,
|
|
940
|
-
|
|
1002
|
+
onPointerDown: onClick,
|
|
1003
|
+
onTouchStart: onClick,
|
|
941
1004
|
stroke: strokeColor,
|
|
942
1005
|
style: {
|
|
943
1006
|
cursor: isSelected ? "move" : "pointer",
|
|
@@ -957,7 +1020,8 @@ function Line({
|
|
|
957
1020
|
d: endings.end.d,
|
|
958
1021
|
transform: endings.end.transform,
|
|
959
1022
|
stroke: strokeColor,
|
|
960
|
-
|
|
1023
|
+
onPointerDown: onClick,
|
|
1024
|
+
onTouchStart: onClick,
|
|
961
1025
|
style: {
|
|
962
1026
|
cursor: isSelected ? "move" : "pointer",
|
|
963
1027
|
strokeWidth,
|
|
@@ -1038,7 +1102,8 @@ function Polyline({
|
|
|
1038
1102
|
"path",
|
|
1039
1103
|
{
|
|
1040
1104
|
d: pathData,
|
|
1041
|
-
|
|
1105
|
+
onPointerDown: onClick,
|
|
1106
|
+
onTouchStart: onClick,
|
|
1042
1107
|
opacity,
|
|
1043
1108
|
style: {
|
|
1044
1109
|
fill: "none",
|
|
@@ -1058,7 +1123,8 @@ function Polyline({
|
|
|
1058
1123
|
transform: endings.start.transform,
|
|
1059
1124
|
stroke: strokeColor,
|
|
1060
1125
|
fill: endings.start.filled ? color : "none",
|
|
1061
|
-
|
|
1126
|
+
onPointerDown: onClick,
|
|
1127
|
+
onTouchStart: onClick,
|
|
1062
1128
|
style: {
|
|
1063
1129
|
cursor: isSelected ? "move" : "pointer",
|
|
1064
1130
|
strokeWidth,
|
|
@@ -1074,11 +1140,12 @@ function Polyline({
|
|
|
1074
1140
|
transform: endings.end.transform,
|
|
1075
1141
|
stroke: strokeColor,
|
|
1076
1142
|
fill: endings.end.filled ? color : "none",
|
|
1077
|
-
|
|
1143
|
+
onPointerDown: onClick,
|
|
1144
|
+
onTouchStart: onClick,
|
|
1078
1145
|
style: {
|
|
1079
1146
|
cursor: isSelected ? "move" : "pointer",
|
|
1080
1147
|
strokeWidth,
|
|
1081
|
-
pointerEvents: endings.end.filled ? "visible" : "visibleStroke",
|
|
1148
|
+
pointerEvents: isSelected ? "none" : endings.end.filled ? "visible" : "visibleStroke",
|
|
1082
1149
|
strokeLinecap: "butt"
|
|
1083
1150
|
}
|
|
1084
1151
|
}
|
|
@@ -1129,14 +1196,15 @@ function Polygon({
|
|
|
1129
1196
|
"path",
|
|
1130
1197
|
{
|
|
1131
1198
|
d: pathData,
|
|
1132
|
-
|
|
1199
|
+
onPointerDown: onClick,
|
|
1200
|
+
onTouchStart: onClick,
|
|
1133
1201
|
opacity,
|
|
1134
1202
|
style: {
|
|
1135
1203
|
fill: color,
|
|
1136
1204
|
stroke: strokeColor ?? color,
|
|
1137
1205
|
strokeWidth,
|
|
1138
1206
|
cursor: isSelected ? "move" : "pointer",
|
|
1139
|
-
pointerEvents: color === "transparent" ? "visibleStroke" : "visible",
|
|
1207
|
+
pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
|
|
1140
1208
|
strokeLinecap: "butt",
|
|
1141
1209
|
strokeLinejoin: "miter",
|
|
1142
1210
|
...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
|
|
@@ -1240,6 +1308,7 @@ function FreeText({
|
|
|
1240
1308
|
zIndex: 2
|
|
1241
1309
|
},
|
|
1242
1310
|
onPointerDown: onClick,
|
|
1311
|
+
onTouchStart: onClick,
|
|
1243
1312
|
children: /* @__PURE__ */ jsx(
|
|
1244
1313
|
"span",
|
|
1245
1314
|
{
|
|
@@ -1269,6 +1338,87 @@ function FreeText({
|
|
|
1269
1338
|
}
|
|
1270
1339
|
);
|
|
1271
1340
|
}
|
|
1341
|
+
function RenderAnnotation({
|
|
1342
|
+
pageIndex,
|
|
1343
|
+
annotation,
|
|
1344
|
+
scaleFactor = 1,
|
|
1345
|
+
style,
|
|
1346
|
+
...props
|
|
1347
|
+
}) {
|
|
1348
|
+
const { provides: annotationProvides } = useAnnotationCapability();
|
|
1349
|
+
const [imageUrl, setImageUrl] = useState(null);
|
|
1350
|
+
const urlRef = useRef(null);
|
|
1351
|
+
const { width, height } = annotation.rect.size;
|
|
1352
|
+
useEffect(() => {
|
|
1353
|
+
if (annotationProvides) {
|
|
1354
|
+
const task = annotationProvides.renderAnnotation({
|
|
1355
|
+
pageIndex,
|
|
1356
|
+
annotation,
|
|
1357
|
+
scaleFactor,
|
|
1358
|
+
dpr: window.devicePixelRatio
|
|
1359
|
+
});
|
|
1360
|
+
task.wait((blob) => {
|
|
1361
|
+
const url = URL.createObjectURL(blob);
|
|
1362
|
+
setImageUrl(url);
|
|
1363
|
+
urlRef.current = url;
|
|
1364
|
+
}, ignore);
|
|
1365
|
+
return () => {
|
|
1366
|
+
if (urlRef.current) {
|
|
1367
|
+
URL.revokeObjectURL(urlRef.current);
|
|
1368
|
+
urlRef.current = null;
|
|
1369
|
+
} else {
|
|
1370
|
+
task.abort({
|
|
1371
|
+
code: PdfErrorCode.Cancelled,
|
|
1372
|
+
message: "canceled render task"
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
}, [pageIndex, scaleFactor, annotationProvides, annotation.id, width, height]);
|
|
1378
|
+
const handleImageLoad = () => {
|
|
1379
|
+
if (urlRef.current) {
|
|
1380
|
+
URL.revokeObjectURL(urlRef.current);
|
|
1381
|
+
urlRef.current = null;
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
return /* @__PURE__ */ jsx(Fragment, { children: imageUrl && /* @__PURE__ */ jsx(
|
|
1385
|
+
"img",
|
|
1386
|
+
{
|
|
1387
|
+
src: imageUrl,
|
|
1388
|
+
onLoad: handleImageLoad,
|
|
1389
|
+
...props,
|
|
1390
|
+
style: {
|
|
1391
|
+
width: "100%",
|
|
1392
|
+
height: "100%",
|
|
1393
|
+
...style || {}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
) });
|
|
1397
|
+
}
|
|
1398
|
+
function Stamp({ isSelected, annotation, pageIndex, scale, onClick }) {
|
|
1399
|
+
return /* @__PURE__ */ jsx(
|
|
1400
|
+
"div",
|
|
1401
|
+
{
|
|
1402
|
+
style: {
|
|
1403
|
+
position: "absolute",
|
|
1404
|
+
width: "100%",
|
|
1405
|
+
height: "100%",
|
|
1406
|
+
zIndex: 2,
|
|
1407
|
+
pointerEvents: isSelected ? "none" : "auto"
|
|
1408
|
+
},
|
|
1409
|
+
onPointerDown: onClick,
|
|
1410
|
+
onTouchStart: onClick,
|
|
1411
|
+
children: annotation.pdfId !== void 0 && /* @__PURE__ */ jsx(
|
|
1412
|
+
RenderAnnotation,
|
|
1413
|
+
{
|
|
1414
|
+
pageIndex,
|
|
1415
|
+
annotation: { ...annotation.object, id: annotation.pdfId },
|
|
1416
|
+
scaleFactor: scale
|
|
1417
|
+
}
|
|
1418
|
+
)
|
|
1419
|
+
}
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1272
1422
|
function Annotations(annotationsProps) {
|
|
1273
1423
|
const { pageIndex, scale, selectionMenu } = annotationsProps;
|
|
1274
1424
|
const { provides: annotationProvides } = useAnnotationCapability();
|
|
@@ -1330,7 +1480,7 @@ function Annotations(annotationsProps) {
|
|
|
1330
1480
|
children: (obj) => /* @__PURE__ */ jsx(
|
|
1331
1481
|
Ink,
|
|
1332
1482
|
{
|
|
1333
|
-
|
|
1483
|
+
isSelected,
|
|
1334
1484
|
color: obj.color,
|
|
1335
1485
|
opacity: obj.opacity,
|
|
1336
1486
|
strokeWidth: obj.strokeWidth,
|
|
@@ -1360,7 +1510,7 @@ function Annotations(annotationsProps) {
|
|
|
1360
1510
|
children: (obj) => /* @__PURE__ */ jsx(
|
|
1361
1511
|
Square,
|
|
1362
1512
|
{
|
|
1363
|
-
|
|
1513
|
+
isSelected,
|
|
1364
1514
|
rect: obj.rect,
|
|
1365
1515
|
color: obj.color,
|
|
1366
1516
|
opacity: obj.opacity,
|
|
@@ -1392,7 +1542,7 @@ function Annotations(annotationsProps) {
|
|
|
1392
1542
|
children: (obj) => /* @__PURE__ */ jsx(
|
|
1393
1543
|
Circle,
|
|
1394
1544
|
{
|
|
1395
|
-
|
|
1545
|
+
isSelected,
|
|
1396
1546
|
rect: obj.rect,
|
|
1397
1547
|
color: obj.color,
|
|
1398
1548
|
opacity: obj.opacity,
|
|
@@ -1664,6 +1814,34 @@ function Annotations(annotationsProps) {
|
|
|
1664
1814
|
annotation.localId
|
|
1665
1815
|
);
|
|
1666
1816
|
}
|
|
1817
|
+
if (isStamp(annotation)) {
|
|
1818
|
+
return /* @__PURE__ */ jsx(
|
|
1819
|
+
AnnotationContainer,
|
|
1820
|
+
{
|
|
1821
|
+
trackedAnnotation: annotation,
|
|
1822
|
+
isSelected,
|
|
1823
|
+
isDraggable: true,
|
|
1824
|
+
isResizable: true,
|
|
1825
|
+
selectionMenu,
|
|
1826
|
+
lockAspectRatio: true,
|
|
1827
|
+
style: {
|
|
1828
|
+
mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
|
|
1829
|
+
},
|
|
1830
|
+
...annotationsProps,
|
|
1831
|
+
children: (_object) => /* @__PURE__ */ jsx(
|
|
1832
|
+
Stamp,
|
|
1833
|
+
{
|
|
1834
|
+
isSelected,
|
|
1835
|
+
annotation,
|
|
1836
|
+
pageIndex,
|
|
1837
|
+
scale,
|
|
1838
|
+
onClick: (e) => handleClick(e, annotation)
|
|
1839
|
+
}
|
|
1840
|
+
)
|
|
1841
|
+
},
|
|
1842
|
+
annotation.localId
|
|
1843
|
+
);
|
|
1844
|
+
}
|
|
1667
1845
|
return null;
|
|
1668
1846
|
}) });
|
|
1669
1847
|
}
|
|
@@ -2787,6 +2965,92 @@ const FreeTextPaint = ({
|
|
|
2787
2965
|
}
|
|
2788
2966
|
);
|
|
2789
2967
|
};
|
|
2968
|
+
const StampPaint = ({ pageIndex, scale, pageWidth, pageHeight }) => {
|
|
2969
|
+
const { provides: annotationProvides } = useAnnotationCapability();
|
|
2970
|
+
const inputRef = useRef(null);
|
|
2971
|
+
const canvasRef = useRef(null);
|
|
2972
|
+
const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
|
|
2973
|
+
useEffect(() => {
|
|
2974
|
+
if (!annotationProvides) return;
|
|
2975
|
+
return annotationProvides.onActiveToolChange(setActiveTool);
|
|
2976
|
+
}, [annotationProvides]);
|
|
2977
|
+
if (!activeTool.defaults) return null;
|
|
2978
|
+
if (activeTool.defaults.subtype !== PdfAnnotationSubtype.STAMP) return null;
|
|
2979
|
+
const { register } = usePointerHandlers({ modeId: "stamp", pageIndex });
|
|
2980
|
+
const pageWidthPDF = pageWidth / scale;
|
|
2981
|
+
const pageHeightPDF = pageHeight / scale;
|
|
2982
|
+
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
2983
|
+
const [start, setStart] = useState(null);
|
|
2984
|
+
const handlers = useMemo(
|
|
2985
|
+
() => ({
|
|
2986
|
+
onPointerDown: (pos, evt) => {
|
|
2987
|
+
var _a;
|
|
2988
|
+
const x = clamp(pos.x, 0, pageWidthPDF);
|
|
2989
|
+
const y = clamp(pos.y, 0, pageHeightPDF);
|
|
2990
|
+
setStart({ x, y });
|
|
2991
|
+
(_a = inputRef.current) == null ? void 0 : _a.click();
|
|
2992
|
+
}
|
|
2993
|
+
}),
|
|
2994
|
+
[pageWidthPDF, pageHeightPDF]
|
|
2995
|
+
);
|
|
2996
|
+
useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
|
|
2997
|
+
const onChange = async (e) => {
|
|
2998
|
+
var _a;
|
|
2999
|
+
if (!annotationProvides || !start) return;
|
|
3000
|
+
const file = (_a = e.currentTarget.files) == null ? void 0 : _a[0];
|
|
3001
|
+
if (!file) return;
|
|
3002
|
+
const img = await new Promise((res, rej) => {
|
|
3003
|
+
const i = new Image();
|
|
3004
|
+
i.onload = () => res(i);
|
|
3005
|
+
i.onerror = rej;
|
|
3006
|
+
i.src = URL.createObjectURL(file);
|
|
3007
|
+
});
|
|
3008
|
+
const imgW = img.naturalWidth;
|
|
3009
|
+
const imgH = img.naturalHeight;
|
|
3010
|
+
const maxW = pageWidthPDF;
|
|
3011
|
+
const maxH = pageHeightPDF;
|
|
3012
|
+
const scaleFactor = Math.min(1, maxW / imgW, maxH / imgH);
|
|
3013
|
+
const pdfW = imgW * scaleFactor;
|
|
3014
|
+
const pdfH = imgH * scaleFactor;
|
|
3015
|
+
const posX = clamp(start.x, 0, maxW - pdfW);
|
|
3016
|
+
const posY = clamp(start.y, 0, maxH - pdfH);
|
|
3017
|
+
const rect = {
|
|
3018
|
+
origin: { x: posX, y: posY },
|
|
3019
|
+
size: { width: pdfW, height: pdfH }
|
|
3020
|
+
};
|
|
3021
|
+
const canvas = canvasRef.current;
|
|
3022
|
+
if (!canvas) return;
|
|
3023
|
+
canvas.width = pdfW;
|
|
3024
|
+
canvas.height = pdfH;
|
|
3025
|
+
const ctx = canvas.getContext("2d");
|
|
3026
|
+
ctx.drawImage(img, 0, 0, pdfW, pdfH);
|
|
3027
|
+
const imageData = ctx.getImageData(0, 0, pdfW, pdfH);
|
|
3028
|
+
const anno = {
|
|
3029
|
+
type: PdfAnnotationSubtype.STAMP,
|
|
3030
|
+
flags: ["print"],
|
|
3031
|
+
pageIndex,
|
|
3032
|
+
id: Date.now() + Math.random(),
|
|
3033
|
+
rect
|
|
3034
|
+
};
|
|
3035
|
+
annotationProvides.createAnnotation(pageIndex, anno, { imageData });
|
|
3036
|
+
annotationProvides.setActiveVariant(null);
|
|
3037
|
+
annotationProvides.selectAnnotation(pageIndex, anno.id);
|
|
3038
|
+
setStart(null);
|
|
3039
|
+
};
|
|
3040
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3041
|
+
/* @__PURE__ */ jsx("canvas", { style: { display: "none" }, ref: canvasRef }),
|
|
3042
|
+
/* @__PURE__ */ jsx(
|
|
3043
|
+
"input",
|
|
3044
|
+
{
|
|
3045
|
+
ref: inputRef,
|
|
3046
|
+
type: "file",
|
|
3047
|
+
accept: "image/png,image/jpeg",
|
|
3048
|
+
style: { display: "none" },
|
|
3049
|
+
onChange
|
|
3050
|
+
}
|
|
3051
|
+
)
|
|
3052
|
+
] });
|
|
3053
|
+
};
|
|
2790
3054
|
function AnnotationLayer({
|
|
2791
3055
|
pageIndex,
|
|
2792
3056
|
scale,
|
|
@@ -2871,6 +3135,15 @@ function AnnotationLayer({
|
|
|
2871
3135
|
pageWidth,
|
|
2872
3136
|
pageHeight
|
|
2873
3137
|
}
|
|
3138
|
+
),
|
|
3139
|
+
/* @__PURE__ */ jsx(
|
|
3140
|
+
StampPaint,
|
|
3141
|
+
{
|
|
3142
|
+
pageIndex,
|
|
3143
|
+
scale,
|
|
3144
|
+
pageWidth,
|
|
3145
|
+
pageHeight
|
|
3146
|
+
}
|
|
2874
3147
|
)
|
|
2875
3148
|
]
|
|
2876
3149
|
}
|