Rasterex API/docs/components/measurement/scale

Scale Settings

Set document scale to ensure accurate measurements on the canvas.

The Mental Model

To ensure scaling and measurements work reliably, always follow this integration flow:

  • 1. Load Canvas: Initialize the canvas iframe.
  • 2. Load File: Send the view message to load a document.
  • 3. Apply Scale: Use addScale only AFTER the file is loaded.
  • 4. Activate Tools: Finally, enable measurement tools.

Lifecycle & Order

Scale logic is context-aware. You cannot apply a scale unless a document is active in the canvas. If you call addScale before view, the settings will be ignored.

Overview

Scale defines the relationship between canvas pixels and real-world dimensions. Without it, measurements like length and area cannot be calculated accurately.

  • Two-way communication: Request current scales or push new scales.
  • Metric and Imperial: Native support for both unit systems.
  • Flexible scoping: Apply scales globally, per-page, or by page range.

Quick Start

Send a scale to the canvas and listen for the confirmation.

javascript
// 1. Send a scale to the canvas
iframe.contentWindow.postMessage({
  type: 'addScale',
  payload: {
    fileIndex: 0,
    scale: {
      label: "1 m : 10 m",
      value: "1:10",
      metric: "0",           // "0" = Metric, "1" = Imperial
      metricUnit: "Meter",
      dimPrecision: 2,
      isSelected: true
    }
  }
}, '*');

// 2. Listen for the snapshot confirmation
window.addEventListener('message', (event) => {
  if (event.data.type === 'scalesSnapshot') {
    console.log('Active scale:', event.data.payload.selectedLabel);
  }
});
Quick Start

Scale Properties

Most integration issues stem from understanding the difference between ratio values and multipliers.

  • label: Display name shown to users (e.g., "1 m : 10 m")
  • value: The mathematical ratio as a string (e.g., "1:10").
  • metric: Unit system - "0" for Metric, "1" for Imperial
  • metricUnit: The exact unit name (e.g., "Meter", "Feet"). Strict naming required.
  • dimPrecision: Decimal places for rounding (0-4)
  • isSelected: Set to true to activate this scale immediately

Supported Units

IMPORTANT: You must use these exact unit names. Using shortcodes like "m" or "ft" will result in a silent failure.

  • Metric: Millimeter, Centimeter, Decimeter, Meter, Kilometer
  • Imperial: Inch, Feet, Yard, Mile, Nautical Miles

Communication Flow

The scale system uses a request-response pattern:

Host Sends

1. Request Current Scales

Ask the canvas for the current scale state.

javascript
iframe.contentWindow.postMessage({
  type: 'getScales',
  payload: { fileIndex: 0 }
}, '*');
Canvas Emits

2. Receive Snapshot

The canvas sends back the complete scale state.

javascript
// event.data.payload
{
  "fileIndex": 1,
  "fileName": "sample.pdf",
  "selectedLabel": "1 mm : 12 mm",
  "scales": [
    {
      "value": "1:12",
      "label": "1 mm : 12 mm",
      "metric": "0",
      "metricUnit": "Millimeter",
      "dimPrecision": 2,
      "isSelected": true,
      "source": "calibrate"
    }
  ]
}
Host Sends

3. Update Scale

Apply the scale only AFTER receiving a file load event.

javascript
iframe.contentWindow.postMessage({
  type: 'addScale',
  payload: {
    fileIndex: 0,
    scale: {
      label: "1 m : 10 m",
      value: "1:10",
      metric: "0",
      metricUnit: "Meter",
      dimPrecision: 2,
      isSelected: true
    }
  }
}, '*');

Advanced Scaling

For complex layouts, you can apply scales to specific page ranges or handle architectural fractions.

javascript
// Page-Specific Scale (applies only to pages 1-5 and page 9)
iframe.contentWindow.postMessage({
  type: 'addScale',
  payload: {
    scale: {
      label: "Detail Scale",
      value: "1:5",
      metric: "0",
      metricUnit: "Meter",
      dimPrecision: 2,
      isSelected: true,
      pageRanges: [[1, 5], [9, 9]]  // Pages 1-5 and 9
    }
  }
}, '*');

// Imperial Architectural Scale (1/8" = 1')
iframe.contentWindow.postMessage({
  type: 'addScale',
  payload: {
    scale: {
      label: "1/8\" = 1'",
      value: "1:96",
      metric: "1",                  // Imperial
      metricUnit: "Feet",
      dimPrecision: 2,
      isSelected: true,
      imperialNumerator: 1,        // 1/8 inch
      imperialDenominator: 8
    }
  }
}, '*');
Advanced Scaling

Calibration

Calibration is documented separately because it is an interactive calculate-then-apply workflow rather than a direct addScale update.

Complete Example

A production-ready implementation with initialization and event handling.

const iframe = document.querySelector('[data-viewer-iframe]');

// 1. Request scales when iframe loads
iframe.addEventListener('load', () => {
  iframe.contentWindow.postMessage({ 
    type: 'getScales', 
    payload: { fileIndex: 0 } 
  }, '*');
});

// 2. Listen for scale updates
window.addEventListener('message', (event) => {
  if (event.data.type === 'scalesSnapshot') {
    const { scales, selectedLabel } = event.data.payload;
    console.log('Document calibrated with:', selectedLabel);
    updateScaleUI(scales, selectedLabel);
  }
});

// 3. Set a new scale
// 1. Load a file first
function loadFile() {
  iframe.contentWindow.postMessage({
    type: 'view',
    payload: { fileUrl: 'https://example.com/document.pdf' }
  }, '*');
}

// 2. Set scale AFTER the file is active (usually in a 'fileInfo' listener)
function setScale() {
  iframe.contentWindow.postMessage({
    type: 'addScale',
    payload: {
      fileIndex: 0,
      scale: {
        label: "1 m : 10 m",
        value: "1:10",
        metric: "0",
        metricUnit: "Meter",
        dimPrecision: 2,
        isSelected: true
      }
    }
  }, '*');
}

// 3. Listen for confirmations
window.addEventListener('message', (event) => {
  if (event.data.type === 'fileInfo') {
    console.log('File ready, applying scale...');
    setScale();
  }
  if (event.data.type === 'scalesSnapshot') {
    console.log('Scale active:', event.data.payload.selectedLabel);
  }
});
Complete Example

Full Type Definition

The complete ViewerScale interface with all available properties.

typescript
interface ViewerScale {
  label: string;             // Display name (e.g., "1 m : 10 m")
  value: string;             // Ratio string (e.g., "1:10")
  metric: "0" | "1";         // "0" = Metric, "1" = Imperial
  metricUnit: string;        // Unit name (e.g., "Meter", "Feet")
  dimPrecision: number;      // Decimal places (0-4)
  isSelected: boolean;       // Active state
  
  // Optional properties
  isGlobal?: boolean;        // Apply to all pages
  pageRanges?: number[][];   // Page ranges [[start, end], ...]
  source?: string;           // "manual", "auto", or "calibrate"
  imperialNumerator?: number;    // For fractional imperial scales
  imperialDenominator?: number;  // For fractional imperial scales
}
Full Type Definition