@embedpdf/plugin-annotation 1.0.14 → 1.0.15
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 +23 -6
- 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 +1 -0
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +235 -4
- package/dist/preact/index.js.map +1 -1
- package/dist/react/adapter.d.ts +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +235 -4
- 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/stamp-paint.d.ts +8 -0
- package/dist/shared-preact/components/annotations/stamp.d.ts +12 -0
- package/dist/shared-preact/components/render-annotation.d.ts +1 -1
- package/dist/shared-preact/hooks/use-drag-resize.d.ts +5 -2
- package/dist/shared-react/components/annotation-container.d.ts +2 -1
- 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/render-annotation.d.ts +1 -1
- package/dist/shared-react/hooks/use-drag-resize.d.ts +5 -2
- package/package.json +9 -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";
|
|
@@ -151,6 +151,7 @@ function useDragResize({
|
|
|
151
151
|
isResizable,
|
|
152
152
|
computePatch,
|
|
153
153
|
computeVertices,
|
|
154
|
+
lockAspectRatio = false,
|
|
154
155
|
currentRect,
|
|
155
156
|
setCurrentRect,
|
|
156
157
|
setCurrentVertices,
|
|
@@ -185,6 +186,23 @@ function useDragResize({
|
|
|
185
186
|
oy += dy;
|
|
186
187
|
h -= dy;
|
|
187
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
|
+
}
|
|
188
206
|
}
|
|
189
207
|
if (w < 1 || h < 1) return currentRect;
|
|
190
208
|
w = clamp(w, 1, pageW);
|
|
@@ -221,8 +239,14 @@ function useDragResize({
|
|
|
221
239
|
setCurrentRect(patch.rect ?? nextRect);
|
|
222
240
|
setPreviewObject(patch);
|
|
223
241
|
};
|
|
224
|
-
const onPointerUp = () => {
|
|
242
|
+
const onPointerUp = (e) => {
|
|
225
243
|
if (drag.current === "idle") return;
|
|
244
|
+
if ((e == null ? void 0 : e.currentTarget) && e.pointerId !== void 0) {
|
|
245
|
+
try {
|
|
246
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
}
|
|
226
250
|
const usedDir = dir.current || "bottom-right";
|
|
227
251
|
drag.current = "idle";
|
|
228
252
|
let patch = { rect: currentRect };
|
|
@@ -258,7 +282,9 @@ function useDragResize({
|
|
|
258
282
|
rootHandlers: {
|
|
259
283
|
onPointerDown,
|
|
260
284
|
onPointerMove,
|
|
261
|
-
onPointerUp
|
|
285
|
+
onPointerUp,
|
|
286
|
+
onPointerCancel: () => onPointerUp(),
|
|
287
|
+
onLostPointerCapture: () => onPointerUp()
|
|
262
288
|
},
|
|
263
289
|
startResize
|
|
264
290
|
};
|
|
@@ -336,6 +362,7 @@ function AnnotationContainer({
|
|
|
336
362
|
isSelected = false,
|
|
337
363
|
isDraggable = true,
|
|
338
364
|
isResizable = true,
|
|
365
|
+
lockAspectRatio = false,
|
|
339
366
|
computeVertices,
|
|
340
367
|
computePatch,
|
|
341
368
|
selectionMenu,
|
|
@@ -357,6 +384,7 @@ function AnnotationContainer({
|
|
|
357
384
|
isSelected,
|
|
358
385
|
isDraggable,
|
|
359
386
|
isResizable,
|
|
387
|
+
lockAspectRatio,
|
|
360
388
|
computePatch,
|
|
361
389
|
computeVertices,
|
|
362
390
|
currentRect,
|
|
@@ -1270,6 +1298,86 @@ function FreeText({
|
|
|
1270
1298
|
}
|
|
1271
1299
|
);
|
|
1272
1300
|
}
|
|
1301
|
+
function RenderAnnotation({
|
|
1302
|
+
pageIndex,
|
|
1303
|
+
annotation,
|
|
1304
|
+
scaleFactor = 1,
|
|
1305
|
+
style,
|
|
1306
|
+
...props
|
|
1307
|
+
}) {
|
|
1308
|
+
const { provides: annotationProvides } = useAnnotationCapability();
|
|
1309
|
+
const [imageUrl, setImageUrl] = useState(null);
|
|
1310
|
+
const urlRef = useRef(null);
|
|
1311
|
+
const { width, height } = annotation.rect.size;
|
|
1312
|
+
useEffect(() => {
|
|
1313
|
+
if (annotationProvides) {
|
|
1314
|
+
const task = annotationProvides.renderAnnotation({
|
|
1315
|
+
pageIndex,
|
|
1316
|
+
annotation,
|
|
1317
|
+
scaleFactor,
|
|
1318
|
+
dpr: window.devicePixelRatio
|
|
1319
|
+
});
|
|
1320
|
+
task.wait((blob) => {
|
|
1321
|
+
const url = URL.createObjectURL(blob);
|
|
1322
|
+
setImageUrl(url);
|
|
1323
|
+
urlRef.current = url;
|
|
1324
|
+
}, ignore);
|
|
1325
|
+
return () => {
|
|
1326
|
+
if (urlRef.current) {
|
|
1327
|
+
URL.revokeObjectURL(urlRef.current);
|
|
1328
|
+
urlRef.current = null;
|
|
1329
|
+
} else {
|
|
1330
|
+
task.abort({
|
|
1331
|
+
code: PdfErrorCode.Cancelled,
|
|
1332
|
+
message: "canceled render task"
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
}, [pageIndex, scaleFactor, annotationProvides, annotation.id, width, height]);
|
|
1338
|
+
const handleImageLoad = () => {
|
|
1339
|
+
if (urlRef.current) {
|
|
1340
|
+
URL.revokeObjectURL(urlRef.current);
|
|
1341
|
+
urlRef.current = null;
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
return /* @__PURE__ */ jsx(Fragment, { children: imageUrl && /* @__PURE__ */ jsx(
|
|
1345
|
+
"img",
|
|
1346
|
+
{
|
|
1347
|
+
src: imageUrl,
|
|
1348
|
+
onLoad: handleImageLoad,
|
|
1349
|
+
...props,
|
|
1350
|
+
style: {
|
|
1351
|
+
width: "100%",
|
|
1352
|
+
height: "100%",
|
|
1353
|
+
...style || {}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
) });
|
|
1357
|
+
}
|
|
1358
|
+
function Stamp({ isSelected, annotation, pageIndex, scale, onClick }) {
|
|
1359
|
+
return /* @__PURE__ */ jsx(
|
|
1360
|
+
"div",
|
|
1361
|
+
{
|
|
1362
|
+
style: {
|
|
1363
|
+
position: "absolute",
|
|
1364
|
+
width: "100%",
|
|
1365
|
+
height: "100%",
|
|
1366
|
+
zIndex: 2,
|
|
1367
|
+
pointerEvents: isSelected ? "none" : "auto"
|
|
1368
|
+
},
|
|
1369
|
+
onPointerDown: onClick,
|
|
1370
|
+
children: annotation.pdfId !== void 0 && /* @__PURE__ */ jsx(
|
|
1371
|
+
RenderAnnotation,
|
|
1372
|
+
{
|
|
1373
|
+
pageIndex,
|
|
1374
|
+
annotation: { ...annotation.object, id: annotation.pdfId },
|
|
1375
|
+
scaleFactor: scale
|
|
1376
|
+
}
|
|
1377
|
+
)
|
|
1378
|
+
}
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1273
1381
|
function Annotations(annotationsProps) {
|
|
1274
1382
|
const { pageIndex, scale, selectionMenu } = annotationsProps;
|
|
1275
1383
|
const { provides: annotationProvides } = useAnnotationCapability();
|
|
@@ -1665,6 +1773,34 @@ function Annotations(annotationsProps) {
|
|
|
1665
1773
|
annotation.localId
|
|
1666
1774
|
);
|
|
1667
1775
|
}
|
|
1776
|
+
if (isStamp(annotation)) {
|
|
1777
|
+
return /* @__PURE__ */ jsx(
|
|
1778
|
+
AnnotationContainer,
|
|
1779
|
+
{
|
|
1780
|
+
trackedAnnotation: annotation,
|
|
1781
|
+
isSelected,
|
|
1782
|
+
isDraggable: true,
|
|
1783
|
+
isResizable: true,
|
|
1784
|
+
selectionMenu,
|
|
1785
|
+
lockAspectRatio: true,
|
|
1786
|
+
style: {
|
|
1787
|
+
mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
|
|
1788
|
+
},
|
|
1789
|
+
...annotationsProps,
|
|
1790
|
+
children: (_object) => /* @__PURE__ */ jsx(
|
|
1791
|
+
Stamp,
|
|
1792
|
+
{
|
|
1793
|
+
isSelected,
|
|
1794
|
+
annotation,
|
|
1795
|
+
pageIndex,
|
|
1796
|
+
scale,
|
|
1797
|
+
onClick: (e) => handleClick(e, annotation)
|
|
1798
|
+
}
|
|
1799
|
+
)
|
|
1800
|
+
},
|
|
1801
|
+
annotation.localId
|
|
1802
|
+
);
|
|
1803
|
+
}
|
|
1668
1804
|
return null;
|
|
1669
1805
|
}) });
|
|
1670
1806
|
}
|
|
@@ -2788,6 +2924,92 @@ const FreeTextPaint = ({
|
|
|
2788
2924
|
}
|
|
2789
2925
|
);
|
|
2790
2926
|
};
|
|
2927
|
+
const StampPaint = ({ pageIndex, scale, pageWidth, pageHeight }) => {
|
|
2928
|
+
const { provides: annotationProvides } = useAnnotationCapability();
|
|
2929
|
+
const inputRef = useRef(null);
|
|
2930
|
+
const canvasRef = useRef(null);
|
|
2931
|
+
const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
|
|
2932
|
+
useEffect(() => {
|
|
2933
|
+
if (!annotationProvides) return;
|
|
2934
|
+
return annotationProvides.onActiveToolChange(setActiveTool);
|
|
2935
|
+
}, [annotationProvides]);
|
|
2936
|
+
if (!activeTool.defaults) return null;
|
|
2937
|
+
if (activeTool.defaults.subtype !== PdfAnnotationSubtype.STAMP) return null;
|
|
2938
|
+
const { register } = usePointerHandlers({ modeId: "stamp", pageIndex });
|
|
2939
|
+
const pageWidthPDF = pageWidth / scale;
|
|
2940
|
+
const pageHeightPDF = pageHeight / scale;
|
|
2941
|
+
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
2942
|
+
const [start, setStart] = useState(null);
|
|
2943
|
+
const handlers = useMemo(
|
|
2944
|
+
() => ({
|
|
2945
|
+
onPointerDown: (pos, evt) => {
|
|
2946
|
+
var _a;
|
|
2947
|
+
const x = clamp(pos.x, 0, pageWidthPDF);
|
|
2948
|
+
const y = clamp(pos.y, 0, pageHeightPDF);
|
|
2949
|
+
setStart({ x, y });
|
|
2950
|
+
(_a = inputRef.current) == null ? void 0 : _a.click();
|
|
2951
|
+
}
|
|
2952
|
+
}),
|
|
2953
|
+
[pageWidthPDF, pageHeightPDF]
|
|
2954
|
+
);
|
|
2955
|
+
useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
|
|
2956
|
+
const onChange = async (e) => {
|
|
2957
|
+
var _a;
|
|
2958
|
+
if (!annotationProvides || !start) return;
|
|
2959
|
+
const file = (_a = e.currentTarget.files) == null ? void 0 : _a[0];
|
|
2960
|
+
if (!file) return;
|
|
2961
|
+
const img = await new Promise((res, rej) => {
|
|
2962
|
+
const i = new Image();
|
|
2963
|
+
i.onload = () => res(i);
|
|
2964
|
+
i.onerror = rej;
|
|
2965
|
+
i.src = URL.createObjectURL(file);
|
|
2966
|
+
});
|
|
2967
|
+
const imgW = img.naturalWidth;
|
|
2968
|
+
const imgH = img.naturalHeight;
|
|
2969
|
+
const maxW = pageWidthPDF;
|
|
2970
|
+
const maxH = pageHeightPDF;
|
|
2971
|
+
const scaleFactor = Math.min(1, maxW / imgW, maxH / imgH);
|
|
2972
|
+
const pdfW = imgW * scaleFactor;
|
|
2973
|
+
const pdfH = imgH * scaleFactor;
|
|
2974
|
+
const posX = clamp(start.x, 0, maxW - pdfW);
|
|
2975
|
+
const posY = clamp(start.y, 0, maxH - pdfH);
|
|
2976
|
+
const rect = {
|
|
2977
|
+
origin: { x: posX, y: posY },
|
|
2978
|
+
size: { width: pdfW, height: pdfH }
|
|
2979
|
+
};
|
|
2980
|
+
const canvas = canvasRef.current;
|
|
2981
|
+
if (!canvas) return;
|
|
2982
|
+
canvas.width = pdfW;
|
|
2983
|
+
canvas.height = pdfH;
|
|
2984
|
+
const ctx = canvas.getContext("2d");
|
|
2985
|
+
ctx.drawImage(img, 0, 0, pdfW, pdfH);
|
|
2986
|
+
const imageData = ctx.getImageData(0, 0, pdfW, pdfH);
|
|
2987
|
+
const anno = {
|
|
2988
|
+
type: PdfAnnotationSubtype.STAMP,
|
|
2989
|
+
flags: ["print"],
|
|
2990
|
+
pageIndex,
|
|
2991
|
+
id: Date.now() + Math.random(),
|
|
2992
|
+
rect
|
|
2993
|
+
};
|
|
2994
|
+
annotationProvides.createAnnotation(pageIndex, anno, { imageData });
|
|
2995
|
+
annotationProvides.setActiveVariant(null);
|
|
2996
|
+
annotationProvides.selectAnnotation(pageIndex, anno.id);
|
|
2997
|
+
setStart(null);
|
|
2998
|
+
};
|
|
2999
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3000
|
+
/* @__PURE__ */ jsx("canvas", { style: { display: "none" }, ref: canvasRef }),
|
|
3001
|
+
/* @__PURE__ */ jsx(
|
|
3002
|
+
"input",
|
|
3003
|
+
{
|
|
3004
|
+
ref: inputRef,
|
|
3005
|
+
type: "file",
|
|
3006
|
+
accept: "image/png,image/jpeg",
|
|
3007
|
+
style: { display: "none" },
|
|
3008
|
+
onChange
|
|
3009
|
+
}
|
|
3010
|
+
)
|
|
3011
|
+
] });
|
|
3012
|
+
};
|
|
2791
3013
|
function AnnotationLayer({
|
|
2792
3014
|
pageIndex,
|
|
2793
3015
|
scale,
|
|
@@ -2872,6 +3094,15 @@ function AnnotationLayer({
|
|
|
2872
3094
|
pageWidth,
|
|
2873
3095
|
pageHeight
|
|
2874
3096
|
}
|
|
3097
|
+
),
|
|
3098
|
+
/* @__PURE__ */ jsx(
|
|
3099
|
+
StampPaint,
|
|
3100
|
+
{
|
|
3101
|
+
pageIndex,
|
|
3102
|
+
scale,
|
|
3103
|
+
pageWidth,
|
|
3104
|
+
pageHeight
|
|
3105
|
+
}
|
|
2875
3106
|
)
|
|
2876
3107
|
]
|
|
2877
3108
|
}
|