Rasterex API/docs/getting-started/quick-start

Canvas Quick Start

Embed the canvas, open a document, track loading, and send your first command.

What You Build

This starter page gives you the smallest useful host integration. It mounts the canvas iframe, opens a PDF, shows loading status, and sends basic navigation commands.

  • CANVAS_URL: https://beta.viewer.viewsoft.com.
  • FILE_URL: https://res.cloudinary.com/dvgeew3bj/image/upload/v1779169700/Main_version_1.pdf_1_ifrgjq.pdf.
  • viewerOrigin: the trusted origin used for postMessage.

How to Read the Example

The complete example is intentionally plain HTML, CSS, and JavaScript. Frameworks can wrap the same logic later, but the integration contract stays the same.

  • 1Create the iframe without src so JavaScript can attach the first load handler safely.
  • 2Assign iframe.src = CANVAS_URL after the handler is attached.
  • 3Send the first view message with FILE_URL after the canvas has had a moment to register its message listener.
  • 4Use progressStart and progressEnd to update host UI.

Complete HTML Example

This is the full flow in one file. The important part is the order: register listeners, set iframe src, wait briefly after load, then send the view message.

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Canvas Quick Start</title>
    <style>
      body {
        margin: 0;
        font-family: system-ui, sans-serif;
        color: #172033;
      }

      .toolbar {
        display: flex;
        align-items: center;
        gap: 8px;
        min-height: 56px;
        padding: 10px 12px;
        border-bottom: 1px solid #d9e0ea;
        background: #ffffff;
      }

      button {
        border: 1px solid #c8d2df;
        background: #f7f9fc;
        border-radius: 6px;
        padding: 8px 12px;
        cursor: pointer;
      }

      #status {
        margin-left: auto;
        color: #5c6b80;
        font-size: 14px;
      }

      .canvas-frame {
        display: block;
        width: 100%;
        height: calc(100vh - 57px);
        border: 0;
      }
    </style>
  </head>
  <body>
    <div class="toolbar">
      <button id="open-file" type="button">Open file</button>
      <button id="zoom-in" type="button">Zoom in</button>
      <button id="fit-width" type="button">Fit width</button>
      <span id="status">Ready</span>
    </div>

    <iframe
      id="viewsoft-canvas"
      class="canvas-frame"
      title="Canvas"
    ></iframe>

    <script>
      const CANVAS_URL = 'https://beta.viewer.viewsoft.com'
      const FILE_URL = 'https://res.cloudinary.com/dvgeew3bj/image/upload/v1779169700/Main_version_1.pdf_1_ifrgjq.pdf'
      const viewerOrigin = new URL(CANVAS_URL).origin

      const iframe = document.getElementById('viewsoft-canvas')
      const status = document.getElementById('status')
      let fileLoadStarted = false

      function sendToCanvas(message) {
        if (!iframe.contentWindow) return
        iframe.contentWindow.postMessage(message, viewerOrigin)
      }

      function openFile() {
        status.textContent = 'Opening file...'
        sendToCanvas({
          type: 'view',
          payload: {
            fileUrl: FILE_URL,
          },
        })
      }

      function openFileWhenCanvasIsReady() {
        window.setTimeout(openFile, 500)

        window.setTimeout(() => {
          if (!fileLoadStarted) {
            openFile()
          }
        }, 1500)
      }

      iframe.addEventListener('load', () => {
        status.textContent = 'Canvas loaded'
        openFileWhenCanvasIsReady()
      })

      iframe.src = CANVAS_URL

      document.getElementById('open-file').addEventListener('click', openFile)

      document.getElementById('zoom-in').addEventListener('click', () => {
        sendToCanvas({
          type: 'navigationToolControl',
          payload: {
            action: 'ZOOM_IN',
          },
        })
      })

      document.getElementById('fit-width').addEventListener('click', () => {
        sendToCanvas({
          type: 'navigationToolControl',
          payload: {
            action: 'FIT_TO_WIDTH',
          },
        })
      })

      window.addEventListener('message', (event) => {
        if (event.origin !== viewerOrigin) return

        if (event.data?.type === 'progressStart') {
          fileLoadStarted = true
          status.textContent = 'Loading file...'
        }

        if (event.data?.type === 'progressEnd') {
          status.textContent = 'File loaded'
        }
      })
    </script>
  </body>
</html>
Complete HTML Example

Why This Order Matters

The common first-run bug is sending the view message too early. Create the iframe without src, register the load and message handlers, then assign iframe.src = CANVAS_URL.

After the iframe load event, wait briefly before sending the first view message. If progressStart does not arrive, retry once. This protects the first load without creating an endless message loop.

javascript
const iframe = document.getElementById('viewsoft-canvas')

iframe.addEventListener('load', () => {
  window.setTimeout(openFile, 500)
})

// Set src after the load handler is attached.
iframe.src = CANVAS_URL
Why This Order Matters

Loading Events

Validate the event origin before reading canvas messages. Use these events to update host loading UI and to know whether the first view message was received.

javascript
window.addEventListener('message', (event) => {
  if (event.origin !== viewerOrigin) return

  if (event.data?.type === 'progressStart') {
    fileLoadStarted = true
    console.log('Canvas is loading the file')
  }

  if (event.data?.type === 'progressEnd') {
    console.log('Canvas finished loading')
  }
})
Loading Events

Common Messages

These are the first messages most integrations need. Keep the helper function small and reuse it for every command.

javascript
// Open a file
sendToCanvas({
  type: 'view',
  payload: {
    fileUrl: FILE_URL,
  },
})

// Zoom in
sendToCanvas({
  type: 'navigationToolControl',
  payload: {
    action: 'ZOOM_IN',
  },
})

// Export the current file
sendToCanvas({
  type: 'export',
})
Common Messages

Checklist

Before moving into the full API docs, verify these integration basics.

  • Do not put src in the iframe markup if your script depends on catching the first load event.
  • Do not use * as the target origin in production.
  • Make sure FILE_URL is reachable from the canvas environment.

Next Steps

After the file opens, move into the API areas that match your workflow.