PDF.js Express Plusplay_arrow

Professional PDF.js Viewing & Annotations - Try for free

side menu

Get Started

play_arrow

Learn more

play_arrow

Common use cases

play_arrow

Open a document

play_arrow

Save a document

play_arrow

Viewer

play_arrow

UI Customization

play_arrow

Annotations

play_arrow

Collaboration

play_arrow

Forms

play_arrow

Signature

play_arrow

Searching

play_arrow

Measurement

play_arrow

Compare

play_arrow

Advanced Capabilities

play_arrow

PDF.js Express REST API

play_arrow

Migration Guides

play_arrow

Create custom annotation in PDF.js Express

The following features are available in:

check

PDF.js Express Viewer

help_outline

PDF.js Express Viewer is a free viewer with limited capabilities compared to PDF.js Express Plus

check

PDF.js Express Plus

help_outline

PDF.js Express Plus is a commercial PDF SDK for viewing, annotating, signing, form filling and more

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>