@kne/react-pdf-sign 1.0.0 → 1.0.1
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/README.md +61 -26
- package/dist/index.css +10 -0
- package/dist/index.css.map +1 -1
- package/dist/index.js +142 -87
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +113 -73
- package/dist/index.modern.js.map +1 -1
- package/package.json +2 -1
package/dist/index.modern.js
CHANGED
|
@@ -8,13 +8,14 @@ import { LeftOutlined, RightOutlined } from '@ant-design/icons';
|
|
|
8
8
|
import 'react-pdf/dist/Page/TextLayer.css';
|
|
9
9
|
import 'react-pdf/dist/Page/AnnotationLayer.css';
|
|
10
10
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
11
|
-
import { Stage, Layer, Group, Image, Rect, Text, Transformer } from 'react-konva';
|
|
11
|
+
import { Stage, Layer, Group, Image as Image$1, Rect, Text, Transformer } from 'react-konva';
|
|
12
12
|
import useControlValue from '@kne/use-control-value';
|
|
13
13
|
import useRefCallback from '@kne/use-ref-callback';
|
|
14
14
|
import useImage from 'use-image';
|
|
15
15
|
import { createWithIntlProvider, useIntl } from '@kne/react-intl';
|
|
16
16
|
import { PDFDocument } from 'pdf-lib';
|
|
17
17
|
import SignatureCanvas from 'react-signature-canvas';
|
|
18
|
+
import { snapdom } from '@zumer/snapdom';
|
|
18
19
|
|
|
19
20
|
function _extends() {
|
|
20
21
|
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
@@ -35,7 +36,7 @@ function _objectWithoutPropertiesLoose(r, e) {
|
|
|
35
36
|
return t;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
var style = {"pdf-view-container":"_RgZXN","pdf-view":"_PAju1","pdf-view-children":"_N11Pj","pdf-view-page-control-left":"_IbVpf","pdf-view-page-control-right":"_IIgqj","pdf-view-page-control-current":"_JW3CT","signature-container":"_6TDb-","signature-canvas":"_2CGF4","signature-modal":"_kWe3k"};
|
|
39
|
+
var style = {"pdf-view-container":"_RgZXN","pdf-view":"_PAju1","pdf-view-children":"_N11Pj","pdf-view-page-control-left":"_IbVpf","pdf-view-page-control-right":"_IIgqj","pdf-view-page-control-current":"_JW3CT","signature-container":"_6TDb-","signature-canvas":"_2CGF4","signature-modal":"_kWe3k","signature-mask":"_FSvLv"};
|
|
39
40
|
|
|
40
41
|
const _excluded$3 = ["numPages"];
|
|
41
42
|
const PDFViewer = ({
|
|
@@ -173,7 +174,7 @@ const LocationLayer = withLocale(p => {
|
|
|
173
174
|
} = useIntl();
|
|
174
175
|
const {
|
|
175
176
|
width = 200,
|
|
176
|
-
height =
|
|
177
|
+
height = 80,
|
|
177
178
|
padding = 8,
|
|
178
179
|
stageWidth,
|
|
179
180
|
stageHeight,
|
|
@@ -188,6 +189,7 @@ const LocationLayer = withLocale(p => {
|
|
|
188
189
|
const [signatureImage] = useImage(signature);
|
|
189
190
|
const groupRef = useRef();
|
|
190
191
|
const signRef = useRef();
|
|
192
|
+
const targetRef = useRef();
|
|
191
193
|
const transformerRef = useRef();
|
|
192
194
|
const computedSignLocation = () => {
|
|
193
195
|
const absolutePosition = signRef.current.absolutePosition();
|
|
@@ -235,7 +237,7 @@ const LocationLayer = withLocale(p => {
|
|
|
235
237
|
}, []);
|
|
236
238
|
useEffect(() => {
|
|
237
239
|
if (isInit) {
|
|
238
|
-
transformerRef.current.nodes([
|
|
240
|
+
transformerRef.current.nodes([targetRef.current]);
|
|
239
241
|
}
|
|
240
242
|
}, [isInit]);
|
|
241
243
|
if (!(isInit && value)) {
|
|
@@ -251,19 +253,22 @@ const LocationLayer = withLocale(p => {
|
|
|
251
253
|
draggable: true,
|
|
252
254
|
ref: groupRef,
|
|
253
255
|
onDragEnd: computedSignLocation,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
256
|
+
children: [/*#__PURE__*/jsx(Group, {
|
|
257
|
+
ref: targetRef,
|
|
258
|
+
onTransformEnd: computedSignLocation,
|
|
259
|
+
children: signatureImage ? /*#__PURE__*/jsx(Image$1, {
|
|
260
|
+
width: width,
|
|
261
|
+
height: height,
|
|
262
|
+
image: signatureImage,
|
|
263
|
+
cornerRadius: 8,
|
|
264
|
+
ref: signRef
|
|
265
|
+
}) : /*#__PURE__*/jsx(Rect, {
|
|
266
|
+
width: width,
|
|
267
|
+
height: height,
|
|
268
|
+
fill: "#f0f0f0",
|
|
269
|
+
cornerRadius: 8,
|
|
270
|
+
ref: signRef
|
|
271
|
+
})
|
|
267
272
|
}), /*#__PURE__*/jsx(Text, {
|
|
268
273
|
text: signatureImage ? '' : placeholder,
|
|
269
274
|
fontSize: 16,
|
|
@@ -285,8 +290,7 @@ const LocationLayer = withLocale(p => {
|
|
|
285
290
|
borderStroke: themeColor,
|
|
286
291
|
rotateAnchorStroke: themeColor,
|
|
287
292
|
anchorStroke: themeColor,
|
|
288
|
-
padding: padding
|
|
289
|
-
enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
|
|
293
|
+
padding: padding
|
|
290
294
|
})]
|
|
291
295
|
})
|
|
292
296
|
});
|
|
@@ -2497,7 +2501,36 @@ function isEqual(value, other) {
|
|
|
2497
2501
|
|
|
2498
2502
|
var isEqual_1 = isEqual;
|
|
2499
2503
|
|
|
2500
|
-
const
|
|
2504
|
+
const signPdfFile = async pdfSignature => {
|
|
2505
|
+
const {
|
|
2506
|
+
x,
|
|
2507
|
+
y,
|
|
2508
|
+
page,
|
|
2509
|
+
width,
|
|
2510
|
+
height,
|
|
2511
|
+
signature,
|
|
2512
|
+
url,
|
|
2513
|
+
filename
|
|
2514
|
+
} = pdfSignature;
|
|
2515
|
+
const response = await window.fetch(url);
|
|
2516
|
+
const pdfBytes = await response.arrayBuffer();
|
|
2517
|
+
const pdfDoc = await PDFDocument.load(pdfBytes);
|
|
2518
|
+
const pdfPage = pdfDoc.getPage(page - 1);
|
|
2519
|
+
const signatureBytes = await window.fetch(signature).then(res => res.arrayBuffer());
|
|
2520
|
+
const signatureImageEmbed = await pdfDoc.embedPng(signatureBytes);
|
|
2521
|
+
pdfPage.drawImage(signatureImageEmbed, {
|
|
2522
|
+
x,
|
|
2523
|
+
y,
|
|
2524
|
+
width,
|
|
2525
|
+
height
|
|
2526
|
+
});
|
|
2527
|
+
const modifiedPdfBytes = await pdfDoc.save();
|
|
2528
|
+
return new window.File([modifiedPdfBytes], filename, {
|
|
2529
|
+
type: 'application/pdf'
|
|
2530
|
+
});
|
|
2531
|
+
};
|
|
2532
|
+
|
|
2533
|
+
const _excluded$1 = ["placeholder", "signature", "url", "width", "height", "padding", "filename", "defaultLocation", "onChange"];
|
|
2501
2534
|
const PDFSign = withLocale(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
2502
2535
|
let {
|
|
2503
2536
|
placeholder,
|
|
@@ -2506,10 +2539,12 @@ const PDFSign = withLocale(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
2506
2539
|
width,
|
|
2507
2540
|
height,
|
|
2508
2541
|
padding,
|
|
2509
|
-
filename = 'signed-document.pdf'
|
|
2542
|
+
filename = 'signed-document.pdf',
|
|
2543
|
+
defaultLocation,
|
|
2544
|
+
onChange
|
|
2510
2545
|
} = _ref,
|
|
2511
2546
|
props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
|
|
2512
|
-
const [location, setLocation] = useState({});
|
|
2547
|
+
const [location, setLocation] = useState(Object.assign({}, defaultLocation));
|
|
2513
2548
|
const [pdfProps, setPdfProps] = useState(null);
|
|
2514
2549
|
const {
|
|
2515
2550
|
formatMessage
|
|
@@ -2526,49 +2561,28 @@ const PDFSign = withLocale(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
2526
2561
|
const scaleY = size.height / size.originalHeight;
|
|
2527
2562
|
const pdfX = Math.round(location.size.x / scaleX);
|
|
2528
2563
|
const pdfY = Math.round(size.originalHeight - location.size.y / scaleY);
|
|
2564
|
+
const signWidth = Math.round(location.size.width / scaleX);
|
|
2565
|
+
const signHeight = Math.round(location.size.height / scaleY);
|
|
2529
2566
|
return {
|
|
2530
2567
|
x: pdfX,
|
|
2531
|
-
y: pdfY -
|
|
2568
|
+
y: pdfY - signHeight,
|
|
2532
2569
|
page: currentPage,
|
|
2533
|
-
pageWidth: size.originalWidth,
|
|
2534
|
-
pageHeight: size.originalHeight,
|
|
2535
|
-
width:
|
|
2536
|
-
height:
|
|
2570
|
+
pageWidth: Math.round(size.originalWidth),
|
|
2571
|
+
pageHeight: Math.round(size.originalHeight),
|
|
2572
|
+
width: signWidth,
|
|
2573
|
+
height: signHeight,
|
|
2537
2574
|
signature,
|
|
2538
|
-
url
|
|
2575
|
+
url,
|
|
2576
|
+
filename
|
|
2539
2577
|
};
|
|
2540
|
-
}, [pdfProps, location, signature, url]);
|
|
2578
|
+
}, [pdfProps, location, signature, url, filename]);
|
|
2541
2579
|
const signPdf = useCallback(async () => {
|
|
2542
2580
|
if (!pdfProps) {
|
|
2543
2581
|
throw new Error(formatMessage({
|
|
2544
2582
|
id: 'loadingError'
|
|
2545
2583
|
}));
|
|
2546
2584
|
}
|
|
2547
|
-
|
|
2548
|
-
x,
|
|
2549
|
-
y,
|
|
2550
|
-
page,
|
|
2551
|
-
width,
|
|
2552
|
-
height,
|
|
2553
|
-
signature,
|
|
2554
|
-
url
|
|
2555
|
-
} = pdfSignature;
|
|
2556
|
-
const response = await window.fetch(url);
|
|
2557
|
-
const pdfBytes = await response.arrayBuffer();
|
|
2558
|
-
const pdfDoc = await PDFDocument.load(pdfBytes);
|
|
2559
|
-
const pdfPage = pdfDoc.getPage(page - 1);
|
|
2560
|
-
const signatureBytes = await window.fetch(signature).then(res => res.arrayBuffer());
|
|
2561
|
-
const signatureImageEmbed = await pdfDoc.embedPng(signatureBytes);
|
|
2562
|
-
pdfPage.drawImage(signatureImageEmbed, {
|
|
2563
|
-
x,
|
|
2564
|
-
y,
|
|
2565
|
-
width,
|
|
2566
|
-
height
|
|
2567
|
-
});
|
|
2568
|
-
const modifiedPdfBytes = await pdfDoc.save();
|
|
2569
|
-
return new window.File([modifiedPdfBytes], filename, {
|
|
2570
|
-
type: 'application/pdf'
|
|
2571
|
-
});
|
|
2585
|
+
return await signPdfFile(pdfSignature);
|
|
2572
2586
|
}, [pdfSignature]);
|
|
2573
2587
|
useImperativeHandle(ref, () => ({
|
|
2574
2588
|
getLocation: () => location,
|
|
@@ -2576,6 +2590,13 @@ const PDFSign = withLocale(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
2576
2590
|
getPdfSignature: () => pdfSignature,
|
|
2577
2591
|
sign: () => signPdf()
|
|
2578
2592
|
}));
|
|
2593
|
+
const handlerChange = useRefCallback(onChange);
|
|
2594
|
+
useEffect(() => {
|
|
2595
|
+
handlerChange == null || handlerChange({
|
|
2596
|
+
pdfSignature,
|
|
2597
|
+
location
|
|
2598
|
+
});
|
|
2599
|
+
}, [pdfSignature, location, handlerChange]);
|
|
2579
2600
|
return /*#__PURE__*/jsx(PDFViewer, _extends({}, props, {
|
|
2580
2601
|
url: url,
|
|
2581
2602
|
children: ({
|
|
@@ -2608,7 +2629,7 @@ const PDFSign = withLocale(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
2608
2629
|
}));
|
|
2609
2630
|
}));
|
|
2610
2631
|
|
|
2611
|
-
const _excluded = ["filename", "onSuccess"];
|
|
2632
|
+
const _excluded = ["filename", "onSuccess", "width", "height", "mask"];
|
|
2612
2633
|
const dataURLtoBlob = dataURL => {
|
|
2613
2634
|
let arr = dataURL.split(',');
|
|
2614
2635
|
// 注意base64的最后面中括号和引号是不转译的
|
|
@@ -2629,7 +2650,8 @@ const Signature = withLocale(({
|
|
|
2629
2650
|
onSuccess,
|
|
2630
2651
|
filename,
|
|
2631
2652
|
width,
|
|
2632
|
-
height
|
|
2653
|
+
height,
|
|
2654
|
+
mask: _mask = null
|
|
2633
2655
|
}) => {
|
|
2634
2656
|
const {
|
|
2635
2657
|
formatMessage
|
|
@@ -2638,22 +2660,27 @@ const Signature = withLocale(({
|
|
|
2638
2660
|
message
|
|
2639
2661
|
} = App.useApp();
|
|
2640
2662
|
const signatureCanvasRef = useRef(null);
|
|
2663
|
+
const maskRef = useRef(null);
|
|
2641
2664
|
return /*#__PURE__*/jsxs(Flex, {
|
|
2642
2665
|
vertical: true,
|
|
2643
2666
|
gap: 12,
|
|
2644
2667
|
className: classnames(style['signature-modal-content'], 'signature-modal-content'),
|
|
2645
|
-
children: [/*#__PURE__*/
|
|
2668
|
+
children: [/*#__PURE__*/jsxs("div", {
|
|
2646
2669
|
className: classnames(style['signature-container'], 'signature-container'),
|
|
2647
2670
|
style: {
|
|
2648
2671
|
width: '368px',
|
|
2649
2672
|
height: `${Math.round(height * 368 / width)}px`
|
|
2650
2673
|
},
|
|
2651
|
-
children: /*#__PURE__*/jsx(
|
|
2674
|
+
children: [/*#__PURE__*/jsx("div", {
|
|
2675
|
+
className: classnames(style['signature-mask'], 'signature-mask'),
|
|
2676
|
+
ref: maskRef,
|
|
2677
|
+
children: _mask
|
|
2678
|
+
}), /*#__PURE__*/jsx(SignatureCanvas, {
|
|
2652
2679
|
ref: signatureCanvasRef,
|
|
2653
2680
|
canvasProps: {
|
|
2654
2681
|
className: classnames(style['signature-canvas'], 'signature-canvas')
|
|
2655
2682
|
}
|
|
2656
|
-
})
|
|
2683
|
+
})]
|
|
2657
2684
|
}), /*#__PURE__*/jsxs(Flex, {
|
|
2658
2685
|
justify: "flex-end",
|
|
2659
2686
|
align: "center",
|
|
@@ -2667,14 +2694,32 @@ const Signature = withLocale(({
|
|
|
2667
2694
|
})
|
|
2668
2695
|
}), /*#__PURE__*/jsx(Button, {
|
|
2669
2696
|
type: "primary",
|
|
2670
|
-
onClick: () => {
|
|
2697
|
+
onClick: async () => {
|
|
2671
2698
|
if (signatureCanvasRef.current.isEmpty()) {
|
|
2672
2699
|
message.error(formatMessage({
|
|
2673
2700
|
id: 'signatureEmptyError'
|
|
2674
2701
|
}));
|
|
2675
2702
|
return;
|
|
2676
2703
|
}
|
|
2677
|
-
|
|
2704
|
+
let result = signatureCanvasRef.current.toDataURL('image/png');
|
|
2705
|
+
if (_mask) {
|
|
2706
|
+
const maskPng = await snapdom.toPng(maskRef.current, {
|
|
2707
|
+
scale: 2
|
|
2708
|
+
});
|
|
2709
|
+
const canvas = document.createElement('canvas');
|
|
2710
|
+
canvas.width = width * 2;
|
|
2711
|
+
canvas.height = height * 2;
|
|
2712
|
+
const ctx = canvas.getContext('2d');
|
|
2713
|
+
ctx.drawImage(maskPng, 0, 0, canvas.width, canvas.height);
|
|
2714
|
+
const resultImage = new Image();
|
|
2715
|
+
resultImage.src = result;
|
|
2716
|
+
await new Promise(resolve => {
|
|
2717
|
+
resultImage.onload = resolve;
|
|
2718
|
+
});
|
|
2719
|
+
ctx.drawImage(resultImage, 0, 0, canvas.width, canvas.height);
|
|
2720
|
+
result = canvas.toDataURL('image/png');
|
|
2721
|
+
}
|
|
2722
|
+
const file = new window.File([dataURLtoBlob(result)], filename, {
|
|
2678
2723
|
type: 'image/png'
|
|
2679
2724
|
});
|
|
2680
2725
|
onClose();
|
|
@@ -2697,24 +2742,18 @@ const Title = withLocale(() => {
|
|
|
2697
2742
|
})
|
|
2698
2743
|
});
|
|
2699
2744
|
});
|
|
2700
|
-
const useSignature =
|
|
2745
|
+
const useSignature = () => {
|
|
2701
2746
|
const {
|
|
2702
|
-
|
|
2703
|
-
height
|
|
2704
|
-
} = Object.assign({}, {
|
|
2705
|
-
width: 200,
|
|
2706
|
-
height: 50
|
|
2707
|
-
}, props);
|
|
2708
|
-
const {
|
|
2709
|
-
modal,
|
|
2710
|
-
message
|
|
2747
|
+
modal
|
|
2711
2748
|
} = App.useApp();
|
|
2712
|
-
useRef(null);
|
|
2713
2749
|
return props => {
|
|
2714
2750
|
const _Object$assign = Object.assign({}, props),
|
|
2715
2751
|
{
|
|
2716
2752
|
filename = 'signature.png',
|
|
2717
|
-
onSuccess
|
|
2753
|
+
onSuccess,
|
|
2754
|
+
width = 200,
|
|
2755
|
+
height = 80,
|
|
2756
|
+
mask
|
|
2718
2757
|
} = _Object$assign,
|
|
2719
2758
|
modalProps = _objectWithoutPropertiesLoose(_Object$assign, _excluded);
|
|
2720
2759
|
const modalApi = modal.info(Object.assign({}, {
|
|
@@ -2729,6 +2768,7 @@ const useSignature = props => {
|
|
|
2729
2768
|
content: /*#__PURE__*/jsx(Signature, {
|
|
2730
2769
|
width: width,
|
|
2731
2770
|
height: height,
|
|
2771
|
+
mask: mask,
|
|
2732
2772
|
filename: filename,
|
|
2733
2773
|
onSuccess: onSuccess,
|
|
2734
2774
|
onClose: () => {
|