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