Create custom PDF annotations with this PDF.js Express sample (no servers or other external dependencies required). Annotations can be customized in several different ways – you can change appearances and behaviors, selection box and control handles. Change one of our pre-built annotations or create your own custom annotations that integrate directly into your workflow. A common example of a custom annotation would be creating a 'complete' annotation stamp that triggers a back-end workflow to mark a task item as complete. View demo
WebViewer({
path: '/static/WebViewer/lib/',
pdftronServer: 'https://demo.pdftron.com/', // comment this out to do client-side only
initialDoc: 'https://pdftron.s3.amazonaws.com/downloads/pl/demo-annotated.pdf',
}, document.getElementById('viewer'))
.then((instance) => {
// ruler.js
const rulerTool = window.createRulerTool(instance);
// stamp.js
const customStampTool = window.createStampTool(instance);
const addRulerTool = () => {
// Register tool
instance.registerTool({
toolName: 'RulerTool',
toolObject: rulerTool,
buttonImage: '../../../samples/annotation/custom-annotations/ruler.svg',
buttonName: 'rulerToolButton',
tooltip: 'Ruler Tool',
});
// Add tool button in header
instance.setHeaderItems((header) => {
header.get('freeHandToolGroupButton').insertBefore({
type: 'toolButton',
toolName: 'RulerTool',
hidden: ['tablet', 'mobile'],
});
header.getHeader('tools').get('freeHandToolGroupButton').insertBefore({
type: 'toolButton',
toolName: 'RulerTool',
hidden: ['desktop'],
});
});
instance.setToolMode('RulerTool');
};
function removeRulerTool() {
// Unregister tool
instance.unregisterTool('RulerTool');
instance.setToolMode('AnnotationEdit');
}
function addCustomStampTool() {
// Register tool
instance.registerTool({
toolName: 'CustomStampTool',
toolObject: customStampTool,
buttonImage: '../../../samples/annotation/custom-annotations/stamp.png',
buttonName: 'customStampToolButton',
tooltip: 'Approved Stamp Tool',
});
// Add tool button in header
instance.setHeaderItems((header) => {
header.get('freeHandToolGroupButton').insertBefore({
type: 'toolButton',
toolName: 'CustomStampTool',
hidden: ['tablet', 'mobile'],
});
header.getHeader('tools').get('freeHandToolGroupButton').insertBefore({
type: 'toolButton',
toolName: 'CustomStampTool',
hidden: ['desktop'],
});
});
instance.setToolMode('CustomStampTool');
}
function removeCustomStampTool() {
instance.unregisterTool('CustomStampTool');
instance.setToolMode('AnnotationEdit');
}
document.getElementById('ruler').onchange = (e) => {
if (e.target.checked) {
addRulerTool();
} else {
removeRulerTool();
}
};
document.getElementById('custom-stamp').onchange = (e) => {
if (e.target.checked) {
addCustomStampTool();
} else {
removeCustomStampTool();
}
};
});
<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='width=device-width, initial-scale=1, user-scalable=no'>
<link rel='stylesheet' href='../../style.css'>
<script src="/static/WebViewer/lib/webviewer.min.js"></script>
<script src='../../old-browser-checker.js'></script>
</head>
<body>
<header>
<div className="title sample">Custom annotations sample</div>
</header>
<aside>
<h1>Controls</h1>
<h2>Custom annotation tools</h2>
<input type='checkbox' id='ruler' />
<label for='ruler'>Custom ruler tool</label>
<br />
<input type='checkbox' id='custom-stamp' />
<label for='custom-stamp'>Custom stamp tool</label>
<hr />
<h1>Instructions</h1>
<p>Toggle checkboxes to create/destroy custom annotation tools.</p>
</aside>
<div id='viewer'></div>
<script src="../../menu-button.js"></script>
<script src='ruler.js'></script>
<script src='stamp.js'></script>
<script src='custom-annotations.js'></script>
</body>
</html>