@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.
@@ -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 = 50,
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([groupRef.current]);
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
- onTransformEnd: computedSignLocation,
255
- children: [signatureImage ? /*#__PURE__*/jsx(Image, {
256
- width: width,
257
- height: height,
258
- image: signatureImage,
259
- cornerRadius: 8,
260
- ref: signRef
261
- }) : /*#__PURE__*/jsx(Rect, {
262
- width: width,
263
- height: height,
264
- fill: "#f0f0f0",
265
- cornerRadius: 8,
266
- ref: signRef
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 _excluded$1 = ["placeholder", "signature", "url", "width", "height", "padding", "filename"];
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 - location.size.height,
2568
+ y: pdfY - signHeight,
2532
2569
  page: currentPage,
2533
- pageWidth: size.originalWidth,
2534
- pageHeight: size.originalHeight,
2535
- width: location.size.width,
2536
- height: location.size.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
- const {
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__*/jsx("div", {
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(SignatureCanvas, {
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
- const file = new window.File([dataURLtoBlob(signatureCanvasRef.current.toDataURL('image/png'))], filename, {
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 = props => {
2745
+ const useSignature = () => {
2701
2746
  const {
2702
- width,
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: () => {