Now that I am able to annotate on both documents, I am seeing some issues. I am not sure if I am doing something wrong. The document on the left is working correctly. I can create, edit and delete annotations. The document on the right has some problems. I am using an annotation manager for each document. When working with the right document, adding, replying and deleting will use the annotation manager for the right document. Editing comments will use the annotation viewer for the left document. The right document also doesn’t include the xfdf content.
For my use case, I need the xfdf data to pass to our API.
Is there a different way that I should be doing this?
import { AfterViewInit, Component, ElementRef, EventEmitter, Output, ViewChild } from '@angular/core';
import WebViewer, { Core, WebViewerInstance } from "@pdftron/webviewer";
import { Subject } from "rxjs";
@Component({
selector: 'app-root',
styleUrls: ['app.component.css'],
templateUrl: 'app.component.html'
})
export class AppComponent implements AfterViewInit {
wvInstance?: WebViewerInstance;
@ViewChild('viewer') viewer!: ElementRef;
@Output() coreControlsEvent: EventEmitter<string> = new EventEmitter();
private documentLoaded$: Subject<void>;
constructor() {
this.documentLoaded$ = new Subject<void>();
}
ngAfterViewInit(): void {
WebViewer({
path: '../lib',
fullAPI: true
}, this.viewer.nativeElement).then(instance => {
this.wvInstance = instance;
const { documentViewer, Annotations, annotationManager } = instance.Core;
instance.UI.openElements(['notesPanel']);
documentViewer.addEventListener('annotationsLoaded', () => {
console.log('annotations loaded');
});
const { UI, Core } = instance;
const { Color } = Annotations;
UI.addEventListener(UI.Events.MULTI_VIEWER_READY, () => {
const [documentViewer1, documentViewer2] = Core.getDocumentViewers();
const startCompare = async () => {
const shouldCompare = documentViewer1.getDocument() && documentViewer2.getDocument();
if (shouldCompare) { // Check if both documents loaded before comparing
const beforeColor = new Color(21, 205, 131, 0.4);
const afterColor = new Color(255, 73, 73, 0.4);
const options = { beforeColor, afterColor };
await documentViewer1.startSemanticDiff(documentViewer2, options);
}
}
documentViewer1.addEventListener('documentLoaded', startCompare);
documentViewer2.addEventListener('documentLoaded', startCompare);
documentViewer1.loadDocument('http://localhost:4200/files/fluffy.pdf');
documentViewer2.loadDocument('http://localhost:4200/files/scooby.pdf');
let document1AnnotationManager = documentViewer1.getAnnotationManager();
document1AnnotationManager.addEventListener(
'annotationChanged',
(annotations: any, action: any, { imported }: any) => {
console.log('document1AnnotationManager.annotationChanged');
this.saveAnnotations(document1AnnotationManager, annotations, action);
}
);
let document2AnnotationManager = documentViewer2.getAnnotationManager();
document2AnnotationManager.addEventListener(
'annotationChanged',
(annotations: any, action: any, { imported }: any) => {
console.log('document2AnnotationManager.annotationChanged');
this.saveAnnotations(document1AnnotationManager, annotations, action);
}
);
});
UI.enableFeatures([UI.Feature.MultiViewerMode]);
})
}
private saveAnnotations(annotationManager: Core.AnnotationManager,
annotations: any,
action: string) {
annotations.forEach((annotation: Core.Annotations.Annotation) => {
annotationManager.exportAnnotationCommand().then((xfdfData: any) => {
console.log(`Saving... ${action}`);
console.log(`XFDF data = ${xfdfData}`);
});
});
}
}
This gif is a recording that shows what is happening using the above sample code.
