# `Camera`

> Contract 2.0.0 · package sha256 `a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e` · generated from `configurator-runtime.d.ts` by `services/onsite-scripter/scripts/build-contract-docs.mjs`; edit the source, not this file.

Interface · `import type { Camera } from '@holostep-configurators/runtime-client/contract';` · stable · since 2.0.0 · section 10. Camera

Camera writes are look-only and never undo steps; of the commit options they take only `origin`,
`actor` and `expectRevision` ([`CameraCommitOptions`](CameraCommitOptions.md)). They are not in the write queue: outside a
transaction each starts at once. Autocommit: resolves when the move ends (at rest); a newer view
write takes over a move in progress, which then resolves 'committed', and so does a shopper's
pointer or touch gesture ('camera:control-start'; a wheel is not one). Through a `tx`: resolves
'deferred' at once and starts when the commit is shown; a `durationMs: 0` view write lands in
the frame that presents the commit, so the reveal shows the new view. At the commit point, before
queued writes start or the transaction's Promise resolves, its deferred commands take their place
in each target's command order, though none draws before that frame: a later command to the same
target, called before they start, takes them over as it takes over a running move, so a replaced
command never replays at presentation, and a deferred `durationMs: 0` write still gives a later
eased move its start ([`CameraMoveOptions`](CameraMoveOptions.md)). A command through a later `tx` takes them over only at
its own transaction's commit point, so one whose transaction rolls back (a timeout included), is
aborted or is superseded takes nothing over. An equal transaction's deferred commands, which start
at the next drawn frame, are ordered the same way. The view ([`set`](Camera.set.md), [`fit`](Camera.fit.md),
`views.go`), the
lens, the limits, the mode and the rotation are separate targets: an eased lens doesn't delay a
[`set`](Camera.set.md), so run them together rather than awaiting one before the other.

## Members

| Member | Kind | Summary |
| --- | --- | --- |
| <a id="state"></a>[`state`](Camera.state.md) | property | Observed: the camera as of the last drawn frame (this frame's in a 'late' hook), [`Frame.camera`](Frame.camera.md) views included. |
| <a id="set"></a>[`set`](Camera.set.md) | method | Moves the camera to a view (look-only, replacing; target: the view). |
| <a id="fit"></a>[`fit`](Camera.fit.md) | method | Frames the matches (a view write; as `set`) inside the part of the element the lens's `insets` leave, with the insets and field of view of the newest `lens` write at the fit's call (its target while an eased one runs,… |
| <a id="views"></a>[`views`](Camera.views.md) | property | The document's named views ([`camera.views`](Camera.views.md)); their names are `Object.keys(session.document.camera?.views ?? {})`. |
| <a id="limits"></a>[`limits`](Camera.limits.md) | method | Merges into your app limits (see [`CameraLimits`](CameraLimits.md)); null drops them all, restoring the document's. |
| <a id="lens"></a>[`lens`](Camera.lens.md) | method | Sets the lens; null restores the document's lens. |
| <a id="mode"></a>[`mode`](Camera.mode.md) | method | 'pan': trucks only. |
| <a id="autorotate"></a>[`autoRotate`](Camera.autoRotate.md) | method | null stops. |
| <a id="project"></a>[`project`](Camera.project.md) | method | Projects with the camera of [`camera.state`](Camera.state.md): exact when the camera is at rest; during a move or damping, as of the last drawn frame (this frame's inside a 'late' hook). |
| <a id="ray"></a>[`ray`](Camera.ray.md) | method | The world ray under a screen point, with the same camera as `project`. |

## Declaration

```ts
export interface Camera<C extends object = NoCommitOptions> {
  readonly state: CameraState;
  set(view: CameraView | LookAtView, options?: CameraCommitOptions<C> & CameraMoveOptions): Promise<Report>;
  fit(query?: Query, options?: CameraCommitOptions<C> & CameraMoveOptions & {
    paddingM?: number;
    view?: Pick<CameraView, 'azimuthDeg' | 'polarDeg'>;
  }): Promise<Report>;
  readonly views: {
    go(name: string, options?: CameraCommitOptions<C> & CameraMoveOptions): Promise<Report>;
  };
  limits(limits: CameraLimits | null, options?: CameraCommitOptions<C> & SignalOption): Promise<Report>;
  lens(lens: CameraLens | null, options?: CameraCommitOptions<C> & CameraMoveOptions): Promise<Report>;
  mode(mode: 'orbit' | 'pan' | 'fixed', options?: CameraCommitOptions<C> & SignalOption): Promise<Report>;
  autoRotate(degPerSecond: number | null, options?: CameraCommitOptions<C> & SignalOption): Promise<Report>;
  project(points: readonly Point3[]): Array<ProjectedPoint | null>;
  ray(at: ScreenPoint): Ray;
}
```

## Generic-API test (spec 3.1)

| Rule | Result |
| --- | --- |
| 1. Neutral name | pass: `Camera` names no product |
| 2. A precedent | not recorded: no ledger row (coverage.json) names this member or its owner |
| 3. Two apps, or labs | pass: 21 apps (fleet cross-check: app-04c2774145, app-0c773a4ee3, app-37356bf09f, app-378d190f1b, app-4762caacdc, app-4f16d2f6da, app-510d750508, app-59c5b5751e and 13 more) |
| 4. The cheaper fix first | not recorded per member (Appendix B decides it per need) |
