Message API/docs/components/measurement/calibration

Calibration

Calculate a document scale from a measured canvas reference and an entered real-world length.

Calibration Workflow

Calibration is a calculate-then-apply workflow. The user opens a file, starts calibration, picks the reference line in the Canvas, enters the known real-world length, calculates the scale candidate, and then explicitly adds/applies that candidate.

`calibrationSet` only calculates the scale. It does not add or apply anything until the host sends `calibrationAddScale`.

  • Blocked until file active: calibration does not start before the file is loaded.
  • Canvas pick required: after `calibrationStart`, the user must pick a reference line in the Canvas.
  • Calculation is gated: `calibrationSet` should be sent only after `calibrationFinished` has been received.
  • Apply is explicit: `calibrationAddScale` adds/applies the returned candidate and then the viewer emits `scalesSnapshot`.

Event Flow

Use the production calibration events for new UI. The legacy `startCalibration`, `completeCalibration`, and `cancelCalibration` events remain only for old clients.

Host Sends

1. Host sends calibrationStart

Start RXCore calibration mode for the active file.

javascript
const requestId = `cal-${Date.now()}`;

iframe.contentWindow?.postMessage({
  type: 'calibrationStart',
  payload: {
    requestId,
    fileIndex: 0
  }
}, '*');
Canvas Emits

2. Canvas returns calibrationFinished

The viewer emits this after the user picks the reference line.

javascript
{
  type: 'calibrationFinished',
  payload: {
    requestId: 'cal-123',
    fileIndex: 0,
    fileName: 'drawing.pdf',
    isFinished: true,
    measuredLength: '5.15625'
  }
}
Host Sends

3. Host sends calibrationSet

Send one real-world length payload to calculate the candidate scale. This represents the updated Rasterex Set Calibration action.

javascript
iframe.contentWindow?.postMessage({
  type: 'calibrationSet',
  payload: {
    requestId,
    fileIndex: 0,
    measurementSystem: 2,
    calibrateCorrectionFeetValue: 20,
    calibrateCorrectionInchValue: 7,
    dimPrecision: 2,
    pageRanges: [[1, 5]],
    totalPages: 5
  }
}, '*');
Canvas Emits

4. Canvas returns calibrationScaleCalculated

The calculated scale is a candidate. Show it to the user before applying it.

javascript
{
  type: 'calibrationScaleCalculated',
  payload: {
    requestId: 'cal-123',
    fileIndex: 0,
    fileName: 'drawing.pdf',
    scale: {
      value: '1:48',
      preciseValue: 48,
      label: '1/4" = 1\'',
      source: 'calibrate',
      metric: '1',
      metricUnit: 'Feet',
      dimPrecision: 2,
      isSelected: true,
      pageRanges: [[1, 5]],
      isGlobal: false,
      imperialNumerator: 1,
      imperialDenominator: 4
    }
  }
}
Host Sends

5. Host sends calibrationAddScale

Explicitly add/apply the calculated candidate scale.

javascript
iframe.contentWindow?.postMessage({
  type: 'calibrationAddScale',
  payload: {
    requestId,
    fileIndex: 0,
    scale: calculatedScale
  }
}, '*');
Canvas Emits

6. Canvas returns scalesSnapshot

The viewer emits the updated scale list after the calculated candidate is added/applied.

javascript
{
  type: 'scalesSnapshot',
  payload: {
    fileIndex: 0,
    fileName: 'drawing.pdf',
    scales: [
      {
        value: '1:48',
        preciseValue: 48,
        label: '1/4" = 1\'',
        source: 'calibrate',
        metric: '1',
        metricUnit: 'Feet',
        dimPrecision: 2,
        isSelected: true,
        pageRanges: [[1, 5]],
        isGlobal: false,
        imperialNumerator: 1,
        imperialDenominator: 4
      }
    ],
    selectedLabel: '1/4" = 1\''
  }
}

Supplying Real-World Values

Calibration needs two lengths. The viewer supplies the measured drawing/page length after the reference line is picked. Your application supplies the real-world length represented by that same reference line.

After `calibrationFinished`, prompt the operator for the known real-world length from the drawing, title block, dimension label, or project standard. Convert that input into the `calibrationSet` payload.

  • `measuredLength`: returned by the viewer in `calibrationFinished`; do not ask the operator to enter it manually.
  • `measurementSystem`: set by your integration based on the real-world units being entered; use `1` for Metric and `2` for Imperial.
  • `calibrateCorrectionMetricValue`: the known real-world metric length for the picked line, for example `100` when the line represents 100 millimeters.
  • `metricUnit`: the metric unit for `calibrateCorrectionMetricValue`, for example `Millimeter`, `Centimeter`, or `Meter`.
  • `calibrateCorrectionFeetValue`: the feet portion of an Imperial real-world length, for example `20` when the picked line represents 20 feet plus any inches.
  • `calibrateCorrectionInchValue`: the inches portion of an Imperial real-world length, for example `7` when the picked line represents 20 feet 7 inches.
  • `dimPrecision`: the decimal precision your application wants the viewer to use for displayed measurements.
  • `pageRanges` and `totalPages`: optional page scope from your document/page-selection logic.

Payload Reference

The `calibrationSet` payload must describe exactly one measurement system. Metric and Imperial correction fields are mutually exclusive.

  • Always include: `requestId`, `fileIndex`, `measurementSystem`, and `dimPrecision`.
  • Metric only: when `measurementSystem: 1`, include `metricUnit` and `calibrateCorrectionMetricValue`.
  • Imperial only: when `measurementSystem: 2`, include `calibrateCorrectionFeetValue` and/or `calibrateCorrectionInchValue`.
  • Do not mix systems: do not send `calibrateCorrectionMetricValue` together with feet/inch correction fields.
  • Optional page scope: include `pageRanges` and `totalPages` when the calculated scale should be scoped to known pages.
  • Not sent by host: do not send `measuredLength` in `calibrationSet`; it is already known to the viewer from the picked reference line.

Valid Imperial calibrationSet

// The picked reference line is known to represent 20 ft 7 in.
{
  requestId,
  fileIndex: 0,
  measurementSystem: 2,
  calibrateCorrectionFeetValue: 20,
  calibrateCorrectionInchValue: 7,
  dimPrecision: 2
}

Valid Metric calibrationSet

// The picked reference line is known to represent 100 millimeters.
{
  requestId,
  fileIndex: 0,
  measurementSystem: 1,
  metricUnit: 'Millimeter',
  calibrateCorrectionMetricValue: 100,
  dimPrecision: 2
}

Invalid Mixed Payload

// Do not send Metric and Imperial correction fields together.
{
  requestId,
  fileIndex: 0,
  measurementSystem: 1,
  metricUnit: 'Millimeter',
  calibrateCorrectionMetricValue: 100,
  calibrateCorrectionFeetValue: 20,
  calibrateCorrectionInchValue: 7,
  dimPrecision: 2
}

Metric And Imperial Payloads

Use one of these `calibrationSet` payload shapes based on the selected real-world unit system.

  • Metric validation: `calibrateCorrectionMetricValue` must parse as a positive number.
  • Imperial validation: at least one of `calibrateCorrectionFeetValue` or `calibrateCorrectionInchValue` must be provided.
  • Page metadata: pass the page ranges the calculated scale should cover, or omit `pageRanges` for the viewer default.

Metric calibrationSet Payload

{
  requestId,
  fileIndex,
  measurementSystem: 1,
  metricUnit: 'Millimeter',
  calibrateCorrectionMetricValue: 100,
  dimPrecision: 2,
  pageRanges: [[1, 5]],
  totalPages: 5
}

Imperial calibrationSet Payload

{
  requestId,
  fileIndex,
  measurementSystem: 2,
  calibrateCorrectionFeetValue: 20,
  calibrateCorrectionInchValue: 7,
  dimPrecision: 2,
  pageRanges: [[1, 5]],
  totalPages: 5
}

Add Scale Payload

`calibrationAddScale` applies the candidate returned by `calibrationScaleCalculated`. You can send the returned scale explicitly, or omit `scale` to apply the viewer's last pending calculated scale for the request.

  • Recommended: send the explicit `scale` returned by `calibrationScaleCalculated` so the applied value is visible in your application state.
  • Fallback: omit `scale` only when your integration intentionally relies on the viewer's pending calculated scale.

Apply Explicit Candidate

{
  requestId,
  fileIndex: 0,
  scale: calculatedScale
}

Apply Pending Candidate

{
  requestId,
  fileIndex: 0
}

Integration UI Guidance

Your application can present calibration controls in any layout, but the Canvas must remain available while the operator picks the reference line.

A common pattern is to place the controls beside the viewer on larger screens and below the viewer on smaller screens. The important requirement is that the operator can see the drawing, pick the reference line, enter the known real-world length, review the candidate scale, and then apply it.

Disable the control that sends `calibrationSet` until `calibrationFinished` is received. Disable the control that sends `calibrationAddScale` until `calibrationScaleCalculated` returns a candidate scale.

  • Canvas access: keep the drawing visible and clickable between `calibrationStart` and `calibrationFinished`.
  • Unit selection: provide a way to choose Metric or Imperial before sending `calibrationSet`.
  • Metric input: collect a numeric real-world length and metric unit.
  • Imperial input: collect feet and/or inches for the real-world length.
  • Actions: provide controls that map to `calibrationStart`, `calibrationSet`, `calibrationAddScale`, and `calibrationCancel`.
  • Candidate review: display the `calibrationScaleCalculated.scale` result before applying it.

Responsive UI Considerations

If your calibration controls are responsive, keep the drawing and form usable at each breakpoint. Avoid layouts where labels, inputs, action buttons, or the calculated scale preview overlap.

  • Large screens: leave enough drawing area visible for accurate reference-line selection.
  • Medium screens: keep the controls scrollable if the viewport is short.
  • Small screens: stack inputs and actions so they remain readable and tappable.
  • Long scale labels: wrap calculated and saved scale labels instead of forcing horizontal overflow.

Cancel Calibration

Cancel calibration mode when the user abandons the flow. Canceling also clears the pending calculated scale for that request.

iframe.contentWindow?.postMessage({
  type: 'calibrationCancel',
  payload: {
    requestId,
    fileIndex: 0
  }
}, '*');
Cancel Calibration

Current Limitations

These notes reflect the behavior currently documented for calibration in the app.

  • File required: calibration depends on an active file.
  • Calculation depends on finish event: the host does not send `calibrationSet` before `calibrationFinished` is received.
  • Apply depends on calculated event: the host does not send `calibrationAddScale` before `calibrationScaleCalculated` returns a candidate.
  • Snapshot is the confirmation path: the later `scalesSnapshot` refresh confirms the calculated scale was applied.