0
# Annotation API
1
2
Interactive PDF annotations including links, form fields, and multimedia content. Supports both rendering existing annotations and creating new ones.
3
4
## Capabilities
5
6
### Annotation Layer Rendering
7
8
Renders interactive PDF annotations including links, form fields, stamps, and multimedia content over the PDF page.
9
10
```javascript { .api }
11
class AnnotationLayer {
12
/**
13
* Render annotations on a page
14
* @param parameters - Annotation layer parameters
15
*/
16
static render(parameters: AnnotationLayerParameters): void;
17
18
/**
19
* Update existing annotation layer
20
* @param parameters - Annotation layer parameters
21
*/
22
static update(parameters: AnnotationLayerParameters): void;
23
}
24
```
25
26
### Annotation Layer Parameters
27
28
Configuration for rendering annotation layers.
29
30
```javascript { .api }
31
interface AnnotationLayerParameters {
32
/** Page viewport for positioning */
33
viewport: PageViewport;
34
/** Container element for annotations */
35
div: HTMLElement;
36
/** Array of annotation objects */
37
annotations: any[];
38
/** Page proxy for annotation interactions */
39
page: PDFPageProxy;
40
/** Path to image resources */
41
imageResourcesPath?: string;
42
/** Whether to render form elements */
43
renderForms?: boolean;
44
/** Link service for navigation */
45
linkService: IPDFLinkService;
46
/** Download manager for file attachments */
47
downloadManager?: IDownloadManager;
48
/** Enable JavaScript in annotations */
49
enableScripting?: boolean;
50
/** Promise for JavaScript actions check */
51
hasJSActionsPromise?: Promise<boolean>;
52
/** Promise for form field objects */
53
fieldObjectsPromise?: Promise<{ [id: string]: any }>;
54
/** Map of annotation canvases */
55
annotationCanvasMap?: Map<string, HTMLCanvasElement>;
56
/** Accessibility manager */
57
accessibilityManager?: any;
58
/** Annotation storage for form data */
59
annotationStorage?: AnnotationStorage;
60
/** Additional HTML attributes */
61
additionalAttributes?: Map<string, Map<string, any>>;
62
}
63
```
64
65
**Usage Examples:**
66
67
```javascript
68
import { AnnotationLayer } from "pdfjs-dist";
69
70
// Get annotations from page
71
const annotations = await page.getAnnotations();
72
73
// Create annotation layer container
74
const annotationDiv = document.createElement("div");
75
annotationDiv.className = "annotationLayer";
76
document.body.appendChild(annotationDiv);
77
78
// Render annotations
79
AnnotationLayer.render({
80
viewport: viewport,
81
div: annotationDiv,
82
annotations: annotations,
83
page: page,
84
linkService: linkService,
85
renderForms: true,
86
enableScripting: false
87
});
88
```
89
90
### Link Service Interface
91
92
Service for handling PDF navigation and external links.
93
94
```javascript { .api }
95
interface IPDFLinkService {
96
/** Current page number */
97
page: number;
98
/** Current rotation */
99
rotation: number;
100
/** Current scale */
101
scale: number;
102
103
/**
104
* Navigate to page
105
* @param pageNumber - Target page number
106
*/
107
goToPage(pageNumber: number): void;
108
109
/**
110
* Navigate to destination
111
* @param dest - PDF destination
112
*/
113
goToDestination(dest: any): void;
114
115
/**
116
* Get destination hash fragment
117
* @param dest - PDF destination
118
* @returns Hash string
119
*/
120
getDestinationHash(dest: any): string;
121
122
/**
123
* Get anchor URL
124
* @param anchor - Anchor string
125
* @returns Full URL
126
*/
127
getAnchorUrl(anchor: string): string;
128
129
/**
130
* Set document reference
131
* @param pdfDocument - PDF document proxy
132
*/
133
setDocument(pdfDocument: PDFDocumentProxy): void;
134
135
/**
136
* Set viewer reference
137
* @param pdfViewer - PDF viewer instance
138
*/
139
setViewer(pdfViewer: any): void;
140
141
/**
142
* Execute named action
143
* @param action - Action name
144
*/
145
executeNamedAction(action: string): void;
146
147
/**
148
* Execute set OCG state action
149
* @param action - OCG action
150
*/
151
executeSetOCGState(action: any): void;
152
}
153
```
154
155
### Download Manager Interface
156
157
Service for handling file downloads from PDF attachments.
158
159
```javascript { .api }
160
interface IDownloadManager {
161
/**
162
* Download file from URL
163
* @param url - File URL
164
* @param filename - Suggested filename
165
* @param options - Download options
166
*/
167
downloadUrl(url: string, filename: string, options?: any): void;
168
169
/**
170
* Download binary data
171
* @param data - File data
172
* @param filename - Filename
173
* @param contentType - MIME type
174
*/
175
downloadData(data: Uint8Array, filename: string, contentType: string): void;
176
177
/**
178
* Open file in new window
179
* @param data - File data
180
* @param filename - Filename
181
* @param dest - Optional destination
182
* @param options - Open options
183
* @returns Whether file was opened
184
*/
185
openOrDownloadData(data: Uint8Array, filename: string, dest?: any, options?: any): boolean;
186
187
/**
188
* Download PDF document
189
* @param data - PDF data
190
* @param filename - Filename
191
*/
192
download(data: Uint8Array, filename: string): void;
193
}
194
```
195
196
### Annotation Types
197
198
Constants and interfaces for different annotation types.
199
200
```javascript { .api }
201
enum AnnotationType {
202
TEXT = 1,
203
LINK = 2,
204
FREETEXT = 3,
205
LINE = 4,
206
SQUARE = 5,
207
CIRCLE = 6,
208
POLYGON = 7,
209
POLYLINE = 8,
210
HIGHLIGHT = 9,
211
UNDERLINE = 10,
212
SQUIGGLY = 11,
213
STRIKEOUT = 12,
214
STAMP = 13,
215
CARET = 14,
216
INK = 15,
217
POPUP = 16,
218
FILEATTACHMENT = 17,
219
SOUND = 18,
220
MOVIE = 19,
221
WIDGET = 20,
222
SCREEN = 21,
223
PRINTERMARK = 22,
224
TRAPNET = 23,
225
WATERMARK = 24,
226
THREED = 25,
227
REDACT = 26
228
}
229
230
enum AnnotationFlag {
231
INVISIBLE = 0x01,
232
HIDDEN = 0x02,
233
PRINT = 0x04,
234
NOZOOM = 0x08,
235
NOROTATE = 0x10,
236
NOVIEW = 0x20,
237
READONLY = 0x40,
238
LOCKED = 0x80,
239
TOGGLENOVIEW = 0x100,
240
LOCKEDCONTENTS = 0x200
241
}
242
```
243
244
### Annotation Storage
245
246
Storage system for annotation data and form field values.
247
248
```javascript { .api }
249
class AnnotationStorage {
250
constructor();
251
252
/**
253
* Get stored value for annotation
254
* @param key - Annotation key
255
* @returns Stored value
256
*/
257
getValue(key: string): any;
258
259
/**
260
* Get raw stored value
261
* @param key - Annotation key
262
* @returns Raw value
263
*/
264
getRawValue(key: string): any;
265
266
/**
267
* Remove stored value
268
* @param key - Annotation key
269
*/
270
remove(key: string): void;
271
272
/**
273
* Store annotation value
274
* @param key - Annotation key
275
* @param value - Value to store
276
*/
277
setValue(key: string, value: any): void;
278
279
/**
280
* Check if annotation has stored data
281
* @param key - Annotation key
282
* @returns Whether data exists
283
*/
284
has(key: string): boolean;
285
286
/**
287
* Get all stored values
288
* @returns Map of all values
289
*/
290
getAll(): Map<string, any>;
291
292
/**
293
* Get size of stored data
294
* @returns Number of stored items
295
*/
296
get size(): number;
297
298
/**
299
* Reset all stored data
300
* @param keepTransformMatrix - Keep transform matrices
301
*/
302
resetModified(keepTransformMatrix?: boolean): void;
303
304
/**
305
* Get serializable representation
306
* @returns Serializable object
307
*/
308
serializable: any;
309
}
310
```
311
312
**Usage Examples:**
313
314
```javascript
315
// Create annotation storage for forms
316
const annotationStorage = new AnnotationStorage();
317
318
// Store form field value
319
annotationStorage.setValue("field1", "John Doe");
320
annotationStorage.setValue("checkbox1", true);
321
322
// Retrieve values
323
const name = annotationStorage.getValue("field1");
324
const isChecked = annotationStorage.getValue("checkbox1");
325
326
// Check for modifications
327
if (annotationStorage.size > 0) {
328
console.log("Form has been modified");
329
}
330
```
331
332
### Form Field Interactions
333
334
Handling form field events and validation.
335
336
```javascript { .api }
337
interface FormFieldEvent {
338
/** Field name */
339
name: string;
340
/** Field value */
341
value: any;
342
/** Event type */
343
type: "focus" | "blur" | "change" | "validate" | "calculate";
344
/** Source element */
345
source: HTMLElement;
346
}
347
348
interface FormValidationResult {
349
/** Whether field is valid */
350
isValid: boolean;
351
/** Validation message */
352
message?: string;
353
/** Suggested value */
354
value?: any;
355
}
356
```
357
358
### Accessibility Support
359
360
Annotation accessibility features and interfaces.
361
362
```javascript { .api }
363
interface AccessibilityManager {
364
/**
365
* Enable accessibility for annotation
366
* @param annotation - Annotation element
367
* @param data - Annotation data
368
*/
369
enable(annotation: HTMLElement, data: any): void;
370
371
/**
372
* Disable accessibility
373
* @param annotation - Annotation element
374
*/
375
disable(annotation: HTMLElement): void;
376
377
/**
378
* Move focus to annotation
379
* @param annotation - Target annotation
380
*/
381
focusAnnotation(annotation: HTMLElement): void;
382
}
383
```
384
385
**Usage Examples:**
386
387
```javascript
388
// Complete annotation layer setup with form handling
389
class InteractiveAnnotationLayer {
390
constructor(page, container, viewport) {
391
this.page = page;
392
this.container = container;
393
this.viewport = viewport;
394
this.annotationStorage = new AnnotationStorage();
395
this.linkService = new SimpleLinkService();
396
}
397
398
async render() {
399
const annotations = await this.page.getAnnotations({
400
intent: "display"
401
});
402
403
AnnotationLayer.render({
404
viewport: this.viewport,
405
div: this.container,
406
annotations: annotations,
407
page: this.page,
408
linkService: this.linkService,
409
annotationStorage: this.annotationStorage,
410
renderForms: true,
411
enableScripting: false
412
});
413
414
// Handle form field changes
415
this.container.addEventListener('change', (event) => {
416
if (event.target.dataset.annotationId) {
417
const key = event.target.dataset.annotationId;
418
const value = this.getFieldValue(event.target);
419
this.annotationStorage.setValue(key, value);
420
}
421
});
422
}
423
424
getFieldValue(element) {
425
switch (element.type) {
426
case 'checkbox':
427
case 'radio':
428
return element.checked;
429
case 'select-one':
430
return element.selectedIndex;
431
case 'select-multiple':
432
return Array.from(element.selectedOptions).map(opt => opt.value);
433
default:
434
return element.value;
435
}
436
}
437
438
getFormData() {
439
const formData = {};
440
for (const [key, value] of this.annotationStorage.getAll()) {
441
formData[key] = value;
442
}
443
return formData;
444
}
445
}
446
447
// Simple link service implementation
448
class SimpleLinkService {
449
constructor() {
450
this.page = 1;
451
this.rotation = 0;
452
this.scale = 1.0;
453
}
454
455
goToPage(pageNumber) {
456
this.page = pageNumber;
457
// Implement page navigation
458
}
459
460
goToDestination(dest) {
461
// Handle PDF destinations
462
console.log("Navigate to destination:", dest);
463
}
464
465
getDestinationHash(dest) {
466
return `#page=${dest[0]?.num || 1}`;
467
}
468
469
getAnchorUrl(anchor) {
470
return `#${anchor}`;
471
}
472
473
executeNamedAction(action) {
474
switch (action) {
475
case "NextPage":
476
this.goToPage(this.page + 1);
477
break;
478
case "PrevPage":
479
this.goToPage(this.page - 1);
480
break;
481
case "FirstPage":
482
this.goToPage(1);
483
break;
484
case "LastPage":
485
// Navigate to last page
486
break;
487
}
488
}
489
}
490
```
491
492
### CSS Styling
493
494
Required CSS for proper annotation display:
495
496
```css
497
.annotationLayer {
498
position: absolute;
499
left: 0;
500
top: 0;
501
right: 0;
502
bottom: 0;
503
overflow: hidden;
504
}
505
506
.annotationLayer section {
507
position: absolute;
508
text-align: initial;
509
}
510
511
.annotationLayer .buttonWidgetAnnotation.checkBox input,
512
.annotationLayer .buttonWidgetAnnotation.radioButton input {
513
width: 100%;
514
height: 100%;
515
}
516
517
.annotationLayer .textWidgetAnnotation input,
518
.annotationLayer .textWidgetAnnotation textarea,
519
.annotationLayer .choiceWidgetAnnotation select {
520
width: 100%;
521
height: 100%;
522
border: none;
523
outline: none;
524
background: transparent;
525
font: inherit;
526
}
527
528
.annotationLayer .linkAnnotation a {
529
position: absolute;
530
font-size: 1em;
531
top: 0;
532
left: 0;
533
width: 100%;
534
height: 100%;
535
}
536
537
.annotationLayer .linkAnnotation a:hover {
538
opacity: 0.2;
539
background: rgba(255, 211, 0, 1);
540
box-shadow: 0 2px 10px rgba(255, 211, 0, 1);
541
}
542
```