Annotations
KViewer provides annotation tools accessible from the default toolbar. Users select a tool and draw directly on the page.
Annotation Tools Overview
Toolbar Tools
These tools are available in the default toolbar:
| Tool | Icon | Description |
|---|---|---|
| Select | Click to select, move, and resize annotations | |
| Freehand | Draw freeform lines (pen) | |
| Free Highlight | Freehand highlighting | |
| Free Text | Place a text box on the page | |
| Stamp | Place a predefined image stamp | |
| Signature | Place a saved signature | |
| Rectangle | Draw a rectangle shape |
Engine-Only Tools
These annotation types are supported by the annotation engine and can be used programmatically via selectTool(), but are not shown in the default toolbar:
| Tool | Icon | Description |
|---|---|---|
| Highlight | Highlight selected text in color | |
| Strikeout | Strike through selected text | |
| Underline | Underline selected text | |
| Circle | Draw a circle/ellipse shape | |
| Arrow | Draw an arrow line | |
| Note | Place a sticky note |
text-layer to be enabled. These tools detect selected text ranges on the rendered page.Use Text Markup Tools
Enable the text layer and select text to apply markup:
<template>
<div class="h-screen">
<KViewer
:source="pdfUrl"
text-layer
user-name="Reviewer"
/>
</div>
</template>
<script setup lang="ts">
const pdfUrl = '/documents/contract.pdf'
</script>
With the text layer enabled, you can activate these tools programmatically and then select text on the page to apply the markup.
Use Shape Tools
Rectangle (and programmatically Circle, Arrow) tools work by click-and-drag on the page. After placing a shape, it can be:
- Resized by dragging corner handles
- Moved by dragging the shape body
- Styled by changing color and stroke width in the floating toolbar
Use Drawing Tools
Freehand and Free Highlight tools allow continuous pen strokes. The drawing follows the cursor or stylus. On iPad, both a finger and the Apple Pencil draw unless stylus mode is on — see Touch input.
Touch input
On touch devices the viewer has to decide whether a finger is navigating the document or editing it. Two things control that: the active tool, and stylus mode.
| Hand tool (default) | Select tool | Drawing / eraser tools | |
|---|---|---|---|
| Stylus mode off | Finger pans and pinch-zooms; a tap selects an annotation. Moving and resizing needs the select tool (or a pen / mouse). | Finger selects, moves, resizes and erases. No pan gesture — scroll with two fingers is off too, switch back to the hand tool to navigate. | Finger draws / erases. No pan gesture. |
| Stylus mode on | Finger pans and pinch-zooms only. | Finger pans and pinch-zooms only. | Finger pans and pinch-zooms only. |
Pen (Apple Pencil) and mouse input is never restricted: it annotates in every tool and in both modes.
Stylus mode is the "only draw with Apple Pencil" setting: the finger becomes navigation-only so the pen can annotate without the palm or a stray finger leaving marks. It is off by default and is never switched on by device detection. Users toggle it in the page-settings menu; while it is on, a pen indicator sits next to the hand tool, and the first finger tap that is ignored shows a hint with a "turn off" action. Hosts control it via the stylusMode prop / v-model:stylus-mode, setStylusMode(), or the embed bridge. When the prop is omitted the toggle is remembered per browser.
Placed form fields (e.g. signature fields) live in the DOM layer, not on the canvas. Outside form-edit mode their body stays usable for signing or typing; the grip above the field moves it and the corner handles resize it. Both are enlarged on touch devices. Stylus mode applies to them too.
Add Text Annotations
The Free Text tool opens a modal dialog for entering text. After confirming, the text box is placed on the page and can be repositioned and resized.
Work with Annotations Programmatically
Get All Annotations
const viewer = ref()
const annotations = viewer.value?.getAnnotations()
// Returns IAnnotationStore[] with all annotations on the document
Save and Restore Annotations
// Save
const draft = viewer.value?.getAnnotations() ?? []
await saveToServer(JSON.stringify(draft))
// Restore
const saved = await loadFromServer()
const annotations = JSON.parse(saved)
await viewer.value?.importAnnotations(annotations, { mode: 'replace' })
Delete an Annotation
Select an annotation and click the delete button in the floating toolbar, or use the eraser tool to click individual annotations to remove them.
Undo and Redo
KViewer tracks annotation history automatically. Use the undo/redo buttons in the toolbar or keyboard shortcuts:
- Undo:
Ctrl+Z/Cmd+Z - Redo:
Ctrl+Shift+Z/Cmd+Shift+Z
Native PDF Annotations
When a PDF already contains annotations (highlights, text boxes, ink, shapes, etc.), KViewer auto-imports them into editable Konva annotations. Supported native annotation types:
- Text (sticky notes)
- FreeText (text boxes)
- Highlight, Underline, StrikeOut
- Square, Circle
- Ink (freehand)
- Line, PolyLine
- Stamp (with appearance extraction)