Instance
annotate() returns an Annotator. Every method that returns annotations returns copies: changing them has no effect. Use update() instead.
const penciled = annotate('#article');await penciled.ready;
const [first] = penciled.getAll();penciled.update(first.id, { color: 'green', note: 'Revisit this' });Properties
Section titled “Properties”documentId
Section titled “documentId”Type: string (read-only)
The id annotations are stored under. See the documentId option.
container
Section titled “container”Type: Element (read-only)
The element passed to annotate().
Type: Promise<void> (read-only)
Resolves once stored annotations have been loaded and anchored. It also resolves when loading fails: the error goes to onError, and the instance doesn’t save (see Errors and offline).
Reading
Section titled “Reading”getAll()
Section titled “getAll()”getAll(): Annotation[]Every annotation, in document order, including orphans.
get(id: string): Annotation | undefinedgetRange()
Section titled “getRange()”getRange(id: string): Range | nullA DOM Range over the annotation’s text where it is now, or null if it is orphaned or unknown. Useful to position your own UI, or to scroll to the text.
annotationAt()
Section titled “annotationAt()”annotationAt(x: number, y: number): Annotation | undefinedThe annotation painted at a point in the viewport, for example under the pointer. Where annotations overlap, the innermost one is returned.
document.addEventListener('contextmenu', (event) => { const annotation = penciled.annotationAt(event.clientX, event.clientY); if (annotation) console.log(annotation.note);});Changing
Section titled “Changing”create()
Section titled “create()”create(range: Range, init?: AnnotationInit): Annotation | undefinedAnnotates the text in range, clamped to the container, with leading and trailing whitespace trimmed. init can set color, note, editable and meta. If an annotation already covers exactly the same text, that annotation is returned unchanged. Returns undefined when the range holds no text.
const selection = getSelection();if (selection?.rangeCount) { penciled.create(selection.getRangeAt(0), { color: 'blue', meta: { source: 'shortcut' } });}Creating works even with readOnly: that option only restricts readers.
update()
Section titled “update()”update(id: string, patch: AnnotationPatch): Annotation | undefinedChanges an annotation’s color, note, editable or meta, and returns the result. A note of null or '' removes the note. meta is replaced, not merged. Returns undefined if there is no annotation with that id.
remove()
Section titled “remove()”remove(id: string): voidclear()
Section titled “clear()”clear(): voidRemoves every annotation in this document, emitting delete for each.
import()
Section titled “import()”import(data: ExportData | Annotation[], options?: { mode?: 'merge' | 'replace' }): voidAdds annotations, for example from export() or your own backend, and anchors them against the current content. Annotations that don’t fit the content become orphans.
merge(default) adds new annotations and replaces existing ones with the sameid.replacealso removes every annotation that isn’t indata.
Invalid entries are skipped. See Export, import and W3C.
export()
Section titled “export()”export(): ExportDataReturns { version: 1, documentId, annotations }, ready for JSON.stringify.
Navigating
Section titled “Navigating”focus()
Section titled “focus()”focus(id: string): voidScrolls the annotation into view, marks it as active and opens the toolbar on it (in the headless build, emits select). Does nothing for orphans.
blur()
Section titled “blur()”blur(): voidCloses whatever is open, the toolbar on a selection or on an annotation, and emits select with null.
Lifecycle
Section titled “Lifecycle”refresh()
Section titled “refresh()”refresh(): voidRe-anchors every annotation against the current content and repaints. penciled does this automatically when content changes, unless you set observe: false.
setTheme()
Section titled “setTheme()”setTheme(theme: 'light' | 'dark' | 'auto'): voidChanges the UI’s color scheme. Not available in penciled/headless, which has no UI.
on(event: keyof AnnotatorEvents, listener: Function): () => voidAdds an event listener and returns a function that removes it. See Events.
const off = penciled.on('create', (annotation) => track('highlight', annotation.color));off();destroy()
Section titled “destroy()”destroy(): voidSaves pending changes, then removes every highlight, UI element, event listener and observer. Stored annotations are kept. Calling it twice is safe. Destroy the instance before removing its container from the page, or when you want to call annotate() again on the same element.