Hi, Thanks for your answer.
I’m following your sign app example
But, i don’t want to make the same thing… I want to put annotation styled (With Great Vibes font). So, My code base is similar to that example (I copied and pasted), This my first time using your solution.
By the way, I’m using NextJS (I don’t know if it’s useful to know it)
This is my code. I modified some handler as uploadForSigning, applyFields and i’m harcording my name on annotation content.
imports...
interface IContentModalLocaleSignatureProps {
onCloseModal: () => void;
}
interface ICoodirnates {
x: number;
y: number;
}
const ContentModalLocaleSignature: FunctionComponent<IContentModalLocaleSignatureProps> =
({ onCloseModal }) => {
const viewerRef = useRef<HTMLDivElement>(null);
const [webViewerInstance, setWebViewerInstance] =
useState<WebViewerInstance | null>(null);
const [dropPoint, setDropPoint] = useState<ICoodirnates | null>(null);
useEffect(() => {
let instance: WebViewerInstance;
if (!webViewerInstance) {
const runWebViewer = async () => {
instance = await WebViewer(
{
path: '/lib/webviewer',
initialDoc:
'https://pdftron.s3.amazonaws.com/downloads/pl/PDFTRON_about.pdf',
disabledElements: [
'leftPanelButton',
'printButton',
'ribbons',
'toggleNotesButton',
'downloadButton',
'searchButton',
'annotationCommentButton',
'linkButton',
'menuButton',
'highlightToolButton',
'freeHandToolButton',
'freeHandHighlightToolButton',
'freeTextToolButton',
'annotationStylePopup',
'annotationGroupButton',
'rotateHeader',
'rotateClockwiseButton',
'rotateCounterClockwiseButton',
'viewControlsDivider2',
],
css: '/assets/css/webViewerStyles.css',
},
viewerRef.current as HTMLDivElement,
);
const { documentViewer, Annotations, annotationManager } =
instance.Core;
const { setZoomLevel, iframeWindow } = instance.UI;
documentViewer.addEventListener('documentLoaded', async () => {
if (!isProduction) {
console.log(`WebViewer is running and showing`);
}
setZoomLevel('100%');
});
setWebViewerInstance(instance);
const iframeDoc = iframeWindow.document.body;
iframeDoc.addEventListener('dragover', (e) => {
e.preventDefault();
return false;
});
iframeDoc.addEventListener('drop', (e) => {
const eventInherited = e as unknown;
drop(eventInherited as DragEvent<HTMLDivElement>, instance);
});
};
runWebViewer();
}
return () => {
if (webViewerInstance && instance) {
webViewerInstance.Core.dispose();
}
};
}, []);
const uploadForSigning = async () => {
if (webViewerInstance) {
const { documentViewer, AnnotationManager } = webViewerInstance.Core;
const annotManager = documentViewer.getAnnotationManager();
const xfdfString = await annotManager.exportAnnotations({
widgets: true,
fields: true,
});
console.log('XFDF Result', xfdfString);
}
};
const applyFields = async () => {
if (webViewerInstance) {
const { documentViewer } = webViewerInstance.Core;
const annotManager = documentViewer.getAnnotationManager();
const xfdfString = await annotManager.exportAnnotations({
fields: true,
links: false,
});
console.log('XFDF Result', xfdfString);
webViewerInstance.UI.downloadPdf({
flatten: false,
});
}
};
const addField = (
type: string,
point: ICoodirnates,
name = '',
value = '',
flag = {},
) => {
if (webViewerInstance) {
const { documentViewer, Annotations, Math } = webViewerInstance.Core;
const annotManager = documentViewer.getAnnotationManager();
const doc = documentViewer.getDocument();
const displayMode = documentViewer
.getDisplayModeManager()
.getDisplayMode();
const page = displayMode.getSelectedPages(point, point);
if (!!point.x && page.first == null) {
return; //don't add field to an invalid page location
}
const page_idx =
page.first !== null ? page.first : documentViewer.getCurrentPage();
const page_info = doc.getPageInfo(page_idx);
const page_point = displayMode.windowToPage(point, page_idx);
const zoom = documentViewer.getZoom();
const textAnnot = new Annotations.FreeTextAnnotation();
textAnnot.PageNumber = page_idx;
const rotation = documentViewer.getCompleteRotation(page_idx) * 90;
textAnnot.Rotation = rotation;
if (rotation === 270 || rotation === 90) {
textAnnot.Width = 50.0 / zoom;
textAnnot.Height = 250.0 / zoom;
} else {
textAnnot.Width = 250.0 / zoom;
textAnnot.Height = 50.0 / zoom;
}
textAnnot.X =
(page_point.x || page_info.width / 2) - textAnnot.Width / 2;
textAnnot.Y =
(page_point.y || page_info.height / 2) - textAnnot.Height / 2;
textAnnot.setCustomData('type', type);
textAnnot.setCustomData('name', 'Alejandro Parra');
// set the type of annot
textAnnot.setContents('Alejandro ParraT');
textAnnot.setPadding(new Math.Rect(0, 0, 0, 0));
textAnnot.disableRotationControl();
textAnnot.LockedContents = true;
textAnnot.FontSize = `${25.0 / zoom}px`;
textAnnot.TextColor = new Annotations.Color(0, 0, 0);
textAnnot.StrokeThickness = 0; // Remove border
textAnnot.Author = annotManager.getCurrentUser();
textAnnot.Font = 'Great Vibes';
annotManager.deselectAllAnnotations();
annotManager.addAnnotation(textAnnot, {
imported: true,
autoFocus: true,
});
annotManager.redrawAnnotation(textAnnot);
annotManager.selectAnnotation(textAnnot);
}
};
const drop = (
e: DragEvent<HTMLDivElement>,
instance: WebViewerInstance,
) => {
const { documentViewer } = instance.Core;
const scrollElement = documentViewer.getScrollViewElement();
const scrollLeft = scrollElement.scrollLeft || 0;
const scrollTop = scrollElement.scrollTop || 0;
setDropPoint({ x: e.pageX + scrollLeft, y: e.pageY + scrollTop });
e.preventDefault();
return false;
};
const dragStart = (e: DragEvent<HTMLDivElement>) => {
e.currentTarget.style.opacity = '0.5';
const copy = e.currentTarget.cloneNode(true) as HTMLDivElement;
copy.id = 'form-build-drag-image-copy';
copy.style.width = '250px';
document.body.appendChild(copy);
e.dataTransfer.setDragImage(copy, 125, 25);
e.dataTransfer.setData('text', '');
};
const dragEnd = (e: DragEvent<HTMLDivElement>, type: string) => {
addField(type, dropPoint as ICoodirnates);
e.currentTarget.style.opacity = '1';
document.body.removeChild(
document.getElementById('form-build-drag-image-copy') as Node,
);
e.preventDefault();
};
return (
<>
<div className="flex ml-7 mt-7 mb-4">
<h2>
Header
</h2>
</div>
<div className="flex max-h-screen ">
<div className="flex flex-col w-1/4 min-h-full max-h-175 overflow-y-auto bg-gray-light pt-4">
<h1 className="text-center text-primary mb-4">Title</h1>
<div
className="w-full justify-center border-b-2 border-primary p-4 cursor-move"
draggable
onDragStart={(e) => dragStart(e)}
onDragEnd={(e) => dragEnd(e, 'SIGNATURE')}>
<h3>Alejandro Parra</h3>
</div>
</div>
<div className="w-3/4 flex justify-center py-6 h-175 bg-gray-light">
<div className="w-full h-full" ref={viewerRef}></div>
</div>
</div>
<div className="flex justify-center">
<div className="flex justify-center w-9/12">
<div className="w-1/2 p-2">
<Button
label="Cancelar"
variant="secondary"
onClick={onCloseModal}
/>
</div>
<div className="w-1/2 p-2">
<Button
label="Agregar firmas"
variant="primary"
onClick={applyFields}
/>
</div>
</div>
</div>
</>
);
};
export default ContentModalLocaleSignature;