PDF Generation Template Editor
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
ComPDF supports a wide variety of annotation types, including text notes, links, shapes, highlights, stamps, freehand drawings, and audio annotations, fully meeting diverse annotation requirements.
ComPDF React Native SDK provides two ways to create annotations:
CPDFReaderView component.With CPDFReaderView, users can enter annotation mode and create annotations via touch interaction. The annotation type can be set using the setAnnotationMode() method.
const pdfReaderRef = useRef<CPDFReaderView>(null);
<CPDFReaderView
ref={pdfReaderRef}
document={samplePDF}
configuration={ComPDFKit.getDefaultConfig({
})}/>
await pdfReaderRef.current?.setAnnotationMode(CPDFAnnotationType.HIGHLIGHT);Exiting Annotation Mode
To exit annotation mode after finishing the operation, call:
await pdfReaderRef.current?.setAnnotationMode(CPDFAnnotationType.UNKNOWN);Get Current Annotation Type
You can retrieve the current annotation type to check whether you are in annotation mode or determine the selected tool:
const annotationMode = await pdfReaderRef.current?.getAnnotationMode();The CPDFAnnotationType enum supports the following annotation types:
| Annotation Type | Enum Value |
|---|---|
| Text Note | note |
| Highlight | highlight |
| Underline | underline |
| Squiggly | squiggly |
| Strikeout | strikeout |
| Ink | ink |
| Circle | circle |
| Rectangle | square |
| Arrow | arrow |
| Line | line |
| Free Text | freetext |
| Signature | signature |
| Stamp | stamp |
| Link | link |
| Sound | sound |
| Exit Drawing Mode | unknown |
Set autoShowNoteEditDialog to false to replace the built-in Note editor. When onAnnotationCreationPrepared returns a Note, the annotation has already been added to the page. Confirm the dialog with updateAnnotation(), or remove the annotation when the user cancels.
The following example implements the complete create, confirm, and cancel flow:
const pdfReaderRef = useRef<CPDFReaderView | null>(null);
const [noteEditorVisible, setNoteEditorVisible] = useState(false);
const [noteContent, setNoteContent] = useState('');
const [noteAnnotation, setNoteAnnotation] =
useState<CPDFNoteAnnotation | null>(null);
const configuration = ComPDFKit.getDefaultConfig({
annotationsConfig: {
autoShowNoteEditDialog: false,
},
});
const closeNoteEditor = () => {
setNoteEditorVisible(false);
setNoteAnnotation(null);
setNoteContent('');
};
const handleAnnotationCreationPrepared = (
type: CPDFAnnotationType,
annotation: CPDFAnnotation | null,
) => {
if (
type !== CPDFAnnotationType.NOTE ||
!(annotation instanceof CPDFNoteAnnotation)
) {
return;
}
setNoteAnnotation(annotation);
setNoteContent(annotation.content ?? '');
setNoteEditorVisible(true);
};
const handleNoteConfirm = async () => {
const reader = pdfReaderRef.current;
if (!reader || !noteAnnotation) {
return;
}
noteAnnotation.update({ content: noteContent });
await reader._pdfDocument.updateAnnotation(noteAnnotation);
closeNoteEditor();
};
const handleNoteCancel = async () => {
const reader = pdfReaderRef.current;
if (!reader || !noteAnnotation) {
return;
}
const removed = await reader._pdfDocument.removeAnnotation(noteAnnotation);
if (!removed) {
console.warn('The SDK could not remove the created Note annotation');
return;
}
closeNoteEditor();
};
return (
<>
<CPDFReaderView
ref={pdfReaderRef}
document={samplePDF}
configuration={configuration}
onAnnotationCreationPrepared={handleAnnotationCreationPrepared}
/>
<Modal
visible={noteEditorVisible}
transparent
animationType="fade"
onRequestClose={() => {
void handleNoteCancel();
}}
>
<View>
<TextInput
value={noteContent}
onChangeText={setNoteContent}
multiline
/>
<Button
title="Cancel"
onPress={() => {
void handleNoteCancel();
}}
/>
<Button
title="Save"
onPress={() => {
void handleNoteConfirm();
}}
/>
</View>
</Modal>
</>
);ComPDF also supports creating annotations programmatically through APIs. The following examples demonstrate how to create different types of annotations on a specified page.
Note: The rect parameter defines the position and size of the annotation on the page. The coordinate system origin is located at the bottom-left corner of the page.
const annotations = [
new CPDFNoteAnnotation({
page: 0,
createDate: new Date(),
title: "ComPDF",
content: "This is Note Annotation",
rect: { left: 260, top: 740, right: 300, bottom: 700 },
})
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);Markup annotations include Highlight, Underline, Squiggly, and Strikeout types.
const annotations = [
new CPDFMarkupAnnotation({
type: CPDFAnnotationType.HIGHLIGHT,
page: 1,
createDate: new Date(),
title: "ComPDF",
content: "This is Highlight Annotation",
rect: { left: 55, top: 800, right: 180, bottom: 770 },
markedText: "Annotations",
color: "#00aa00",
alpha: 200,
})
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);const annotations = [
new CPDFInkAnnotation({
page: 0,
createDate: new Date(),
type: CPDFAnnotationType.INK,
color: "#ff7043",
borderWidth: 10,
inkPath: [
[
[176.43, 72.22],
[206.94, 78.95],
[217.57, 82.21],
[227.0, 85.49],
[232.42, 87.92],
[243.73, 91.83]
],
],
})
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);The shape annotations include Square, Circle, Line, and Arrow types.
const annotations = [
new CPDFSquareAnnotation({
page: 0,
title: "Title",
content: "This is a square annotation with long content.",
createDate: new Date(),
rect: { left: 20, top: 200, right: 200, bottom: 100 },
borderWidth: 5,
borderColor: "#ff5722",
fillColor: "#8bc34a",
bordEffectType: CPDFBorderEffectType.SOLID,
borderAlpha: 200,
dashGap: 0,
fillAlpha: 100,
}),
new CPDFCircleAnnotation({
page: 0,
title: "Title",
content: "This is a circle annotation.",
createDate: new Date(),
rect: { left: 220, top: 200, right: 360, bottom: 100 },
borderWidth: 5,
borderColor: "#448aff",
fillColor: "#ffeb3b",
bordEffectType: CPDFBorderEffectType.SOLID,
borderAlpha: 255,
fillAlpha: 120,
dashGap: 0,
}),
new CPDFLineAnnotation({ // Line annotation example. Line type annotations don't need the rect parameter; position is determined by points
title: "Title",
page: 1,
content: "This is a line annotation.",
createDate: new Date(),
borderWidth: 6,
borderColor: "#55FF26",
borderAlpha: 255,
fillColor: "#000000",
fillAlpha: 255,
points: [
[504, 219], // Line start point coordinates
[320, 88], // Line end point coordinates
],
}),
new CPDFLineAnnotation({
title: "Title",
page: 1,
content: "This is an arrow annotation.",
createDate: new Date(),
points: [
[288, 342],
[159, 209],
],
borderWidth: 6,
borderColor: "#009688",
borderAlpha: 255,
fillColor: "#009688",
fillAlpha: 255,
lineHeadType: CPDFLineType.SQUARE,
lineTailType: CPDFLineType.OPEN_ARROW,
dashGap: 0,
})
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);const annotations = [
new CPDFFreeTextAnnotation({
title: "Freetext",
page: 0,
content: "Hello, ComPDF!",
createDate: new Date(),
rect: { left: 30, top: 750, right: 230, bottom: 700 },
textAttribute: {
color: "#000000",
familyName: "Times",
styleName: "Bold",
fontSize: 20,
},
alpha: 255,
alignment: CPDFAlignment.LEFT,
})
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);The familyName and styleName parameters are optional. If not specified, the system default font will be used. You can use the
ComPDFKit.getFonts()method to retrieve the list of supported fonts.
const annotations = [
new CPDFStampAnnotation({ // Standard stamp annotation
page: 0,
title: "Stamp",
content: "Approved",
createDate: new Date(),
rect: { left: 20, top: 300, right: 200, bottom: 260 },
stampType: CPDFStampType.STANDARD,
standardStamp: CPDFStandardStamp.COMPLETED,
}),
new CPDFStampAnnotation({ // Custom text stamp annotation
page: 0,
title: "Stamp",
content: "Custom Text Stamp",
createDate: new Date(),
rect: { left: 220, top: 300, right: 350, bottom: 260 },
stampType: CPDFStampType.TEXT,
textStamp: new CPDFTextStamp({
content: "Test Text",
date: textStampDate,
shape: CPDFTextStampShape.rightTriangle,
color: CPDFTextStampColor.red,
}),
})
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);const annotations = [
new CPDFImageAnnotation({
page: 0,
title: "Stamp-Image",
content: "Custom Image Stamp",
createDate: new Date(),
rect: { left: 380, top: 420, right: 550, bottom: 260 },
image: "iVBORw0KGgoAAAANSUhEUgAAAgIAAABz...",
}),
]
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);const annotations = [
new CPDFSignatureAnnotation({
page: 1,
title: "Stamp-Image",
content: "Signature",
createDate,
rect: { left: 380, top: 420, right: 550, bottom: 260 },
image: "iVBORw0KGgoAAAANSUhEUgAAAgIAAABz...",
}),
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);const annotations = [
new CPDFLinkAnnotation({
title: "ComPDF",
page: 0,
createDate,
content: "Link Annotation",
rect: { left: 248, top: 799, right: 407, bottom: 732 },
action: CPDFUriAction.createWeb("https://www.compdf.com"),
}),
new CPDFLinkAnnotation({
title: "ComPDF",
page: 0,
createDate,
content: "Link Annotation",
rect: { left: 374, top: 304, right: 530, bottom: 236 },
action: CPDFGoToAction.toPage(2),
}),
new CPDFLinkAnnotation({
title: "ComPDF",
page: 0,
content: "Link Annotation",
createDate,
rect: { left: 374, top: 199, right: 529, bottom: 121 },
action: CPDFUriAction.createEmail("[email protected]"),
}),
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);const annotations = [
new CPDFSoundAnnotation({
title: "ComPDF",
page: 0,
content: "Sound Annotation",
createDate,
rect: { left: 75, top: 607, right: 119, bottom: 563 },
soundPath,
})
];
const document = pdfReaderRef?.current?._pdfDocument;
await document.addAnnotations(annotations);